	GLOBAL	RDCHR
	GLOBAL	WRCHR
	GLOBAL	PTXT
	GLOBAL	SPACE
	GLOBAL	CRLF
	GLOBAL	JTASK
	GLOBAL	JIOCS
	PSECT	ABS
;***********************************************************************
;
;			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 consent of the authors.
;
;***********************************************************************
; 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
START	ORG	0
	JP	DRIVER
TBASE	EQU	0
;***********************************************************************
; TABLES SECTION
;***********************************************************************
;***********************************************************************
;DIRECT -- Direction Table.  Used to determine the direction
;	   of movement of each piece.
;***********************************************************************
DIRECT	EQU	$
	DEFB	+09,+11,-11,-09
	DEFB	+10,-10,+01,-01
	DEFB	-21,-12,+08,+19
	DEFB	+21,+12,-08,-19
	DEFB	+10,+10,+11,+09
	DEFB	-10,-10,-11,-09
;***********************************************************************
; DPOINT -- Direction Table Pointer.  Used to determine
;	   where to begin in the direction table for any
;	   given piece.
;***********************************************************************
DPOINT	EQU	$
	DEFB	20,16,8,0,4,0,0
;***********************************************************************
; DCOUNT -- Direction Table Counter.  Used to determine
;	   the number directions of movement for any
;	   given piece.
;***********************************************************************
DCOUNT	EQU	$
	DEFB	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	$-1
	DEFB	1,3,3,5,9,10
;***********************************************************************
; 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	$-1
PLISTD	EQU	PLIST+10
PLISTA: DEFW	0,0,0,0,0,0,0,0,0,0
;***********************************************************************
;***********************************************************************
; PIECES -- The initial arrangement of te first rank of
;	    pieces on the board.  Use to set up the board
;	    for the start of the game.
;***********************************************************************
PIECES	EQU	$
	DEFB	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
;		FF0000000000000000FF
;		FF0000000000000000FF
;		FF8181818181818181FF
;		FF8482838586838284FF
;		FFFFFFFFFFFFFFFFFFFF
;		FFFFFFFFFFFFFFFFFFFF
;		The valuesof FF form the border of the
;		board, and are used to indicate when a piece
;		moves off the board.  The individual bits of
;		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	$
BOARDA: DEFS	120
FILEND	DEFB	04H	; EOT
;***********************************************************************
; ATKLIST -- Attack List. A two part array, the first
;	     half for the 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 eigth byte of
;	     the array and does the same for black.
;***********************************************************************
ATKLST: DEFW	0,0,0,0,0,0,0
WACT	EQU	ATKLST
BACT	EQU	ATKLST+7
;***********************************************************************
; POSK	  -- Position of Kings.  A two byte area, the first
;	     byte of which holds the position of the white
;	     king and the second holds the position of
;	     the black king.
;
; POSQ	  -- Position of Queens.  Like POSK, but for queens.
;***********************************************************************
POSK:	DEFB	25,95
POSQ:	DEFB	24,94
	DEFB	-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:	DEFW	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:	DEFW	0,0,0,0,0,0,0,0,0,0
	DEFW	0,0,0,0,0,0,0,0,0,0
;***********************************************************************
; 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 which 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.
;
;***********************************************************************
M1:	DEFW	TBASE
M2:	DEFW	TBASE
M3:	DEFW	TBASE
M4:	DEFW	TBASE
T1:	DEFW	TBASE
T2:	DEFW	TBASE
T3:	DEFW	TBASE
INDX1:	DEFW	TBASE
INDX2:	DEFW	TBASE
NPINS:	DEFW	TBASE
MLPTRI: DEFW	PLYIX
MLPTRJ: DEFW	0
SCRIX:	DEFW	0
BESTM:	DEFW	0
MLLST:	DEFW	0
;***********************************************************************
; 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 to which white can move minus the
;		number to which black can move.
;
; 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
;		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 on-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:	DEFB	0
COLOR:	DEFB	0
P1:	DEFB	0
P2:	DEFB	0
P3:	DEFB	0
PMATE:	DEFB	0
MOVENO: DEFB	2
PLYMAX: DEFB	2
NPLY:	DEFB	0
CKFLG:	DEFB	0
MATEF:	DEFB	0
VALM:	DEFB	0
BRDC:	DEFB	0
PTSL:	DEFB	0
PTSW1:	DEFB	0
PTSW2:	DEFB	0
MTRL:	DEFB	0
BC0:	DEFB	0
MV0:	DEFB	0
PTSCK:	DEFB	0
BMOVES: DEFB	35,55,10H
	DEFB	34,54,10H
	DEFB	85,65,10H
	DEFB	84,64,10H
;***********************************************************************
; STACK  -- Contains the stack for the program.
;***********************************************************************
	ORG	START+2FFH
STACK:
;***********************************************************************
; 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.
;
; MLNXT    --	Pointer to the next available space in the move
;		list.
;
; 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 when a piece is
;			   captured, and the 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
MLIST:	DEFS	2048
MLNXT:	DEFW	MLIST
MLEND	EQU	MLIST+2040
MLPTR	EQU	0
MLFRP	EQU	2
MLTOP	EQU	3
MLFLG	EQU	4
MLVAL	EQU	5
BMOVE1	DEFS	120
BMOVE2	DEFS	120
;***********************************************************************
; STANDARD MESSAGES
;***********************************************************************
GRTTNG: DEFM	'WELCOME TO CHESS!  CARE FOR A GAME? '
ANAMSG: DEFM	'WOULD YOU LIKE TO ANALYZE A POSITION? '
CLRMSG: DEFM	'DO YOU WANT TO PLAY WHITE(W) OR BLACK(B)? '
TITLE1: DEFM	'SARGON'
TITLE2: DEFM	'PLAYER'
MVENUM: DEFM	'02 '
TITLE3: DEFM	'  '
	DEFB	42,42,42,42,42,42
	DEFM	' '
	DEFB	42,42,42,42,42,42
MVEMSG: DEFM	'a1-a1'
OO:	DEFM	'O-O  '
OOO:	DEFM	'O-O-O'
CKMSG:	DEFM	'CHECK'
MTMSG:	DEFM	'MATE IN '
MTPL:	DEFM	'2'
PCS:	DEFM	'KQRBNP'	; Valid piece characters
UWIN:	DEFM	'YOU WIN'
IWIN:	DEFM	'I WIN'
AGAIN:	DEFM	'CARE FOR ANOTHER GAME? '
CRTNES: DEFM	'IS THIS RIGHT? '
PLYDEP: DEFM	'SELECT LOOK AHEAD (1-6) '
TITLE4: DEFM	'                '
WSMOVE: DEFM	'WHOSE MOVE IS IT? '
PPEP:	DEFM	'PxPep'
INVAL1: DEFM	'INVALID MOVE -- TRY AGAIN'
;***********************************************************************
; VARIABLES
;***********************************************************************
BRDPOS: DEFB	0	; Index into the board array
ANBDPS: DEFB	0	; Additional indes required for ANALYS
LINECT: DEFB	0	; Current line number
YSET:	DEFS	1	; The MOSTEK video terminal Y pointer
XSET:	DEFS	1	; The MOSTEK video terminal X pointer
VIDBIT: DEFS	1	; Normal or inverse video register
VIDBI:	DEFS	1	; Normal or inverse video regoster
COLBIT: DEFS	1	; Color of piece for INSPCE
PCODE:	DEFM	'PNBRQK'
	DEFB	32
STUCK:	DEFS	1	; Piece register for INSPCE
RIP:	DEFM	'RIP'
XSETS:	DEFS	1
YSETS:	DEFS	1
TEB1:	DEFB	23,32,32,32,32,32	 ; First grid output
	DEFB	25,32,32,32,32,32	 ; TEB1 and TEB2 contain the text
	DEFB	23,32,32,32,32,32	 ; which is used by DSPBRD to
	DEFB	25,32,32,32,32,32	 ; form the chess board
	DEFB	23,32,32,32,32,32
	DEFB	25,32,32,32,32,32
	DEFB	23,32,32,32,32,32
	DEFB	25,32,32,32,32,32,124
	DEFB	03H		; ETX
TEB2:	DEFB	25,32,32,32,32,32	 ; Complement of first grid output
	DEFB	23,32,32,32,32,32
	DEFB	25,32,32,32,32,32
	DEFB	23,32,32,32,32,32
	DEFB	25,32,32,32,32,32
	DEFB	23,32,32,32,32,32
	DEFB	25,32,32,32,32,32
	DEFB	23,32,32,32,32,32,25,124
	DEFB	03H		; ETX
TEB3:	DEFB	42,42,32,97,32,42
	DEFB	42,32,98,32,42
	DEFB	42,32,99,32,42
	DEFB	42,32,100,32,42
	DEFB	42,32,101,32,42
	DEFB	42,32,102,32,42
	DEFB	42,32,103,32,42
	DEFB	42,32,104,32,42,42
	DEFB	03H		; ETX
TEXT5:	DEFM	'FILE NAME? '
	DEFB	03H		; ETX
TEXT6:	DEFM	'DO YOU HAVE A BOARD POSITION STORED'
	DEFM	' IN A FILE? '
	DEFB	03H		; ETX
TEXT7:	DEFM	'WHAT IS THE NAME OF YOUR BOARD POSITION'
	DEFM	' DATA FILE? '
	DEFB	03H		; ETX
RANK:	DEFS	1
FILE:	DEFS	1
YPOINT: DEFS	1
XPOINT: DEFS	1
SQHOLD: DEFB	32,32,32,32,32
	DEFB	32,32,32,32,32
HOLDER: DEFW	0
VEHOLD: DEFS	16
;***********************************************************************
; MOSTEK TERMINAL ORIENTED CONTROL FUNCTIONS
;***********************************************************************
; CLSCR  will home the cursor and clear the screen of a MOSTEK video
;	 terminal
; ESCAPE sets the ESCAPE function for a MOSTEK video terminal
; LINSET gives a line feed when the board is being displayed
; CURSOR determines the position of the cursor for a MOSTEK video
;	 terminal
; LINOUT outputs a message to the terminal using the WRCHR subroutine
; RANFIL determines if a given square is black or white
; TITLES writes the move list headings to the terminal
; RESET1 sets the IOCS vector to 0
;***********************************************************************
CLRSCR: DEFB	30,29
LINSET: CALL	PGIFND
LIN1:	LD	A,149
	LD	HL,LINECT
	SUB	(HL)
	LD	(YSET),A
CURSOR: LD	E,1
	LD	D,27
	CALL	WRCHR		; Output an ESCAPE
	LD	D,61
	CALL	WRCHR		; Output an = sign
	LD	HL,YSET
	LD	D,(HL)
	CALL	WRCHR		; Output Y coordinate
	LD	HL,XSET
	LD	D,(HL)
	CALL	WRCHR		; Output X coordinate
	LD	HL,0FF12H	; Reset carriage return counter
	SET	1,(HL)		; Set BIT 1 of (0FF12H)
	RET
LINOUT: LD	D,(HL)
	CALL	WRCHR
	INC	HL
	DJNZ	LINOUT-$
	RET
RANFIL: LD	A,(RANK)	; Y - position
	LD	HL,FILE 	; X - position
	ADD	A,(HL)		; Add RANK and FILE
BL50:	DEC	A		; If (RANK) + (FILE) / 2 leaves no
	DEC	A		; remainder, then te square is white.
	CP	2		; Otherwise the square is black.
	JR	Z,BL52-$	; Repeat the loop until a decision
	JR	NC,BL50-$	; can be made.
BL54:	LD	HL,VIDBIT	; Set normal video
	LD	(HL),25
	LD	HL,VIDBI
	LD	(HL),23
	JR	BL56-$
BL52:	LD	HL,VIDBIT	; Set inverse video.
	LD	(HL),23
	LD	HL,VIDBI
	LD	(HL),25
BL56:	RET
TITLES: LD	D,30
	CALL	WRCHR
	LD	B,15
	LD	HL,TITLE4
	CALL	LINOUT		; Put up player headings
	LD	A,-1
	LD	(LINECT),A
	CALL	LIN1
	LD	B,15
	LD	HL,TITLE3
	CALL	LINOUT
	CALL	LINSET		; Set cursor
	RET
RESET1: LD	A,10		; Get the IOCS vector start address
	CALL	JTASK
	LD	(HOLDER),IY	; Store IY address in IYHOLD
	LD	HL,(HOLDER)
	XOR	A
	LD	B,48
BS30:	LD	(HL),A		; Set the IOS vector = 0
	INC	HL
	DJNZ	BS30-$
	CALL	LINSET		; Carriage Return
	RET
;***********************************************************************
; MAIN PROGRAM DRIVER
;***********************************************************************
; FUNCTION:	To coordinate the game moves
;
; CALLED BY:	None
;
; CALLS:	INTERR	INITBD	DSPBRD	LINSET
;		CPTRMV	PLYRMV	TBCPCL	LINOUT
;		PGIFND	ANALYS	CHARTR	SPACE
;
; ARGUMENTS:	None
;***********************************************************************
DRIVER: LD	BC,2047
	LD	HL,MLIST
	XOR	A
	LD	(HL),A
	LD	DE,MLIST+1
	LDIR
	LD	SP,STACK	; Set stack pointer
	CALL	INITBD		; Initialize the board array
	LD	BC,120		; Initialize the BMOVE1 array
	LD	HL,BOARDA
	LD	DE,BMOVE1
	LDIR
	LD	BC,120		; Initialize the BMOVE2 array
	LD	HL,BOARDA
	LD	DE,BMOVE2
	LDIR
	LD	E,1
	LD	A,-1
	LD	(LINECT),A	; Line number is -1 at start
	LD	B,2
	LD	HL,CLRSCR	; Blank the video screen
	CALL	LINOUT
	LD	HL,GRTTNG	; Output greeting
	LD	B,36
	CALL	LINOUT
	LD	A,128
	LD	(XSET),A
DRIV01: CALL	CHARTR		; Accept the answer
	PUSH	AF
	CALL	LINSET		; Carriage return
	POP	AF
	CP	59H		; Is it a 'Y'?
	JP	NZ,ANALYS	; Yes - Jump
	SUB	A		; Code of White is zero
	LD	(COLOR),A	; White always moves first
	CALL	INTERR		; Player's color/search depth
	LD	A,1		; Move number is 1 at start
	LD	(MOVENO),A	; Save
	LD	HL,MVENUM	; Address of ASCII move number
	LD	(HL),30H	; Init to '01'
	INC	HL
	LD	(HL),31H
	INC	HL
	LD	(HL),20H
	CALL	DSPBRD
	CALL	TITLES		; Put up player headings
DRIV04: LD	B,3
	LD	HL,MVENUM	; Display move number
	CALL	LINOUT
	LD	A,(KOLOR)	; Bring in computer's color
	AND	A		; Is it white?
	JR	NZ,DR08-$	; No - Jump
	CALL	PGIFND		; New page if needed
	CP	0		; Was page turned?
	CALL	Z,TBCPCL	; Yes - Tab to computer's column
	CALL	CPTRMV		; Make and write computer's move
	CALL	SPACE		; Output a space
	CALL	SPACE		; Output a space
	CALL	PLYRMV		; Accept and make player's move
	LD	A,128
	LD	(XSET),A
	CALL	LIN1
	JR	DR0C-$		; Jump
DR08:	CALL	PLYRMV		; Accept and make player's move
	CALL	SPACE		; Output a space
	CALL	SPACE		; Output a space
	CALL	PGIFND		; New page if needed
	CP	0		; Was page turned?
	CALL	Z,TBCPCL	; Yes - Tab to computer's column
	CALL	CPTRMV		; Make and write computer's move
	LD	A,128
	LD	(XSET),A
	CALL	LIN1
DR0C:	LD	HL,MVENUM+2	; Addr of 3rd char of move
	LD	A,20H		; ASCII space
	CP	(HL)		; Is char a space?
	LD	A,3AH		; Set up test value
	JR	Z,DR10-$	; Yes - Jump
	INC	(HL)		; Increment value
	CP	(HL)		; Over ASCII 9?
	JR	NZ,DR14-$	; No - Jump
	LD	(HL),30H	; Set char to zero
DR10:	DEC	HL		; 2nd char of ASCII move no.
	INC	(HL)		; Increment value
	CP	(HL)		; Over ASCII 9?
	JR	NZ,DR14-$	; No - Jump
	LD	(HL),30H	; Set char to zero
	DEC	HL		; 1st char of ASCII move number
	INC	(HL)		; Increment value
	CP	(HL)		; Over ASCII 9?
	JR	NZ,DR14-$	; No - Jump
	LD	(HL),31H	; Make 1st char a one
	LD	A,30H		; Make 3rd char a zero
	LD	(MVENUM+2),A
DR14:	LD	HL,MOVENO	; Hexadecimal move number
	INC	(HL)		; Increment
	JP	DRIV04		; Jump
;***********************************************************************
; INTERROGATION FOR PLY AND COLOR
;***********************************************************************
; FUNCTION:  To query the player for his choice of ply
;	     depth and color.
;
; CALLED BY: DRIVER
;
; CALLS:     CHARTR  LINSET LINOUT
;
; ARGUEMENTS:	     None
;***********************************************************************
INTERR: LD	B,42
	LD	HL,CLRMSG
IN22:	CALL	LINOUT		; Request color choice
	CALL	CHARTR		; Accept response
	PUSH	AF
	CALL	LINSET		; Carriage return
	POP	AF
	CP	57H		; Did player request white?
	JR	Z,IN04-$	; Yes - Branch
	SUB	A		; Set computer's color to white
	LD	(KOLOR),A
	LD	DE,TITLE4+2
	LD	HL,TITLE1	; Prepare move list titles
	LD	BC,6
	LDIR
	LD	DE,TITLE4+9
	LD	HL,TITLE2
	LD	BC,6
	LDIR
	JR	IN08-$		; Jump
IN04:	LD	A,80H		; Set computer's color to black
	LD	(KOLOR),A
	LD	DE,TITLE4+2
	LD	HL,TITLE2	; Prepare move list titles
	LD	BC,6
	LDIR
	LD	HL,TITLE1
	LD	DE,TITLE4+9
	LD	BC,6
	LDIR
IN08:	LD	B,24
	LD	A,128
	LD	(XSET),A
	CALL	LINSET
	LD	HL,PLYDEP	; Request depth of search
IN24:	CALL	LINOUT
	CALL	CHARTR		; Accept response
	PUSH	AF
	CALL	LINSET
	POP	AF
	LD	HL,PLYMAX	; Address of ply depth variable
	LD	(HL),2		; Default depth of search
	CP	31H		; Under minimum of 1?
	RET	M		; Yes - Return
	CP	37H		; Over maximum of 6?
	RET	P		; Yes - Return
	SUB	30H		; Subtract ASCII constant
	LD	(HL),A		; Set desired depth
	RET
;***********************************************************************
; NEW PAGE IF NEEDED
;***********************************************************************
; FUNCTION:	To clear move list output when the column
;		has been filled
;
; CALLED BY:	DRIVER	PLYRMV CPTRMV
;
; CALLS:	DSPBRD
;
; ARGUMENTS:	Returns a 1 on the A register if
;		a new page was turned.
;***********************************************************************
PGIFND: LD	HL,LINECT	; Addr of page position countr
	INC	(HL)		; Increment
	LD	A,16H		; Page bottom?
	CP	(HL)
	RET	NC		; No - Return
	CALL	DSPBRD		; Put up new page
	LD	E,1
	LD	A,151
	LD	(YSET),A
	LD	A,128
	LD	(XSET),A
	LD	D,25
	CALL	WRCHR
	CALL	CURSOR
	LD	B,15
	LD	HL,TITLE4	; Re-print titles
PG20:	LD	D,(HL)
	CALL	WRCHR
	INC	HL
	DJNZ	PG20-$
	LD	A,-1
	LD	(LINECT),A
	CALL	LIN1
	LD	B,15
	LD	HL,TITLE3
PG30:	LD	D,(HL)
	CALL	WRCHR
	INC	HL
	DJNZ	PG30-$
	LD	A,128
	LD	(XSET),A
	LD	A,0		; Set line count to 0
	LD	(LINECT),A
	CALL	LIN1
	LD	A,1
	LD	(LINECT),A	; Set line count to 1
	XOR	A
	RET			; Return
;***********************************************************************
; ACCEPT INPUT CHARACTER
;***********************************************************************
; FUNCTION:	Accepts a single character input from the
;		console keyboard and places it in the A
;		register.  The character is also echoed on
;		the video screen, unless it is a carriage
;		return, line feed, or backspace.  Lower
;		case alphabetic characters are folded to
;		upper case.
;
; CALLED BY:	DRIVER	INTERR	PLYRMV	ANALYS
;
; CALLS:	None
;
; ARGUMENTS:	Character input is output in register A.
;***********************************************************************
CHARTR: LD	E,0		; Input single character
	CALL	RDCHR
	CP	0DH		; Carriage return?
	RET	Z		; Yes - Return
	CP	0AH		; Line feed?
	RET	Z		; Yes - Return
	CP	08H		; Backspace?
	RET	Z		; Yes - Return
CHART1: CALL	WRCHR		; Output single character
	LD	A,D
	AND	7FH		; Mask off parity bit
	CP	7BH		; Upper range check (z+1)
	RET	P		; No need to fold -- Return
	CP	61H		; Lower range check (a)
	RET	M		; No need to fold -- Return
	SUB	20H		; Change to one of A-Z
	RET			; Return
;***********************************************************************
; SET UP EMPTY BOARD
;***********************************************************************
; FUNCTION:	Display graphics board and pieces
;
; CALLED BY:	DRIVER	ANALYS	PGIFND
;
; CALLS:	CONVRT	INSPCE	CURSOR	WHCHR
;		LINSET
;
; ARGUMENTS:	None
;***********************************************************************
DSPBRD: PUSH	BC
	PUSH	DE
	PUSH	HL
	PUSH	AF
	LD	E,1
	LD	B,2
	LD	HL,CLRSCR	; Clear the screen
DB20:	LD	D,(HL)
	CALL	WRCHR
	INC	HL
	DJNZ	DB20-$
	LD	A,149
	LD	(YSET),A
	LD	A,165
	LD	(XSET),A
	CALL	CURSOR
	LD	B,42
	LD	D,42		; Output a top line of *'s
DB22:	CALL	WRCHR
	DJNZ	DB22-$
	LD	A,132
	LD	(YSET),A
	LD	A,165
	LD	(XSET),A
	CALL	CURSOR
	LD	HL,TEB3
DB24:	CALL	PTXT		; Output  bottom border of the board
	LD	HL,XSET
	LD	(HL),165
	LD	HL,YSET
	LD	(HL),148
	LD	B,4		; Repeat 4 times
	LD	A,56
	PUSH	AF
DB26:	CALL	CURSOR		; Output a line of grid
	POP	AF
	LD	D,A
	DEC	A
	PUSH	AF
	CALL	WRCHR
	LD	HL,TEB1
	CALL	PTXT
	LD	HL,YSET
	DEC	(HL)
	CALL	CURSOR
	LD	D,124
	CALL	WRCHR
	LD	HL,TEB1 	; Repeat first line
	CALL	PTXT		; This completes one rank
	LD	HL,YSET
	DEC	(HL)
	CALL	CURSOR
	POP	AF
	LD	D,A
	DEC	A
	PUSH	AF
	CALL	WRCHR
	LD	HL,TEB2 	; Output complement grid line
	CALL	PTXT
	LD	HL,YSET
	DEC	(HL)
	CALL	CURSOR
	LD	D,124
	CALL	WRCHR
	LD	HL,TEB2 	; Repeat output of complement
	CALL	PTXT		; grid line
	LD	HL,YSET
	DEC	(HL)		; The next rank is completed
	DJNZ	DB26-$
	POP	AF
BSETUP: LD	A,21		; First board index
BSET04: LD	(BRDPOS),A	; Ready parameter
	CALL	CONVRT		; Determine norm address
	CALL	INSPCE		; Insert that piece onto board
	INC	A		; Next square
	CP	99		; Done?
	JR	C,BSET04-$	; No - Jump
DB50:	LD	A,128		; Set X-pointer to 128
	LD	(XSET),A
	POP	AF
	POP	HL
	POP	DE
	POP	BC
	RET
;***********************************************************************
; BOARD SETUP ROUTINE
;***********************************************************************
; FUNCTION:	To initialize the board array, setting the
;		pieces in their initial positions for the start
;		start of the game.
;
; CALLED BY:	DRIVER
;
; CALLS:	None
;
; ARGUMENTS:	None
;
;***********************************************************************
INITBD: LD	B,120		; Pre-fill board with -1's
	LD	HL,BOARDA
IB10:	LD	(HL),-1
	INC	HL
	DJNZ	IB10-$
	LD	B,8
	LD	IX,BOARDA
IB2:	LD	A,(IX-8)	; Fill non-border squares
	LD	(IX+21),A	; White pieces
	SET	7,A		; Change to black
	LD	(IX+91),A	; Black pieces
	LD	(IX+31),PAWN	; White Pawns
	LD	(IX+81),BPAWN	; Black Pawns
	LD	(IX+41),0	; Empty squares
	LD	(IX+51),0
	LD	(IX+61),0
	LD	(IX+71),0
	INC	IX
	DJNZ	IB2-$
	LD	IX,POSK 	; Init King/Queen position list
	LD	(IX+0),25
	LD	(IX+1),95
	LD	(IX+2),24
	LD	(IX+3),94
	RET
;***********************************************************************
; INSERT PIECE SUBROUTINE
;***********************************************************************
; FUNCTION:	This subroutine places a piece onto a
;		given square on the video board.  The piece
;		inserted is that stored in the board array
;		for that square.
;
; CALLED BY:	DSPRD	MATED
;
; CALLS:	MLTPLY
;
; ARGUMENTS:	None
;***********************************************************************
INSPCE: PUSH	HL		; Save registers
	PUSH	BC
	PUSH	DE
	PUSH	IX
	PUSH	AF
	LD	A,(BRDPOS)	; Get board index
	LD	(M1),A		; Save
	LD	IX,(M1) 	; Index into board array
	LD	A,(IX+BOARD)	; Contents of board array
	AND	A		; Is square empty?
	JR	NZ,IP22-$	; No - Jump
	LD	A,32
	LD	(COLBIT),A
	LD	E,6
	JR	IP25-$
IP22:	CP	0FFH		; Is it a border square?
	JR	Z,IP2C-$	; Yes - Jump
	BIT	7,A		; Is piece white?
	LD	HL,COLBIT	; Load color bit address
	JR	Z,IP30-$	; Yes - Jump
	LD	(HL),42H	; Color is black(B)
	JR	IP04-$		; Jump
IP30:	LD	(HL),57H	; Color is white(W)
IP04:	AND	7		; Delete flags, leave piece
	DEC	A		; Piece on a 0-5 basis
	LD	E,A		; Save
IP25:	CALL	RANFIL
IP56:	LD	HL,PCODE	; Determine piece to insert
	LD	D,0
	ADD	HL,DE
	LD	A,(HL)
	LD	(STUCK),A	; Load piece select to (STUCK)
	LD	A,(YPOINT)	; Convert norm address to pointer
	LD	(YSET),A	; address
	LD	A,(XPOINT)
	ADD	A,2
	LD	(XSET),A
	CALL	CURSOR		; Set the cursor
	LD	E,1
	LD	HL,VIDBIT
	LD	D,(HL)
	CALL	WRCHR		; Output video signal (inverse or
	LD	HL,COLBIT	; normal)
	LD	D,(HL)
	CALL	WRCHR		; Output piece color
	LD	HL,STUCK
	LD	D,(HL)
	CALL	WRCHR		; Output piece name
	LD	D,25
	CALL	WRCHR		; Set normal video
IP2C:	POP	AF		; Restore registers
	POP	IX
	POP	DE
	POP	BC
	POP	HL
	RET			; Return
;***********************************************************************
; BOARD INDEX TO NORM ADDRESS SUBROUTINE
;***********************************************************************
; FUNCTION:	Converts a hexadecimal board index into
;		a Norm address for the square.
;
; CALLED BY:	DSPBRD	INSPCE	ANALYS	MATED
;
; CALLS:	DIVIDE	MLTPLY
;
; ARGUMENTS:	Returns the Norm address in register pair
;		HL.
;***********************************************************************
CONVRT: PUSH	BC		; Save registers
	PUSH	DE
	PUSH	AF
	LD	A,(BRDPOS)	; Get board index
	LD	D,A		; Set up dividend
	SUB	A
	LD	E,10		; Divisor
	CALL	DIVIDE		; Index into rank and file
				; File (1-8) & Rank (2-9)
	PUSH	AF
	LD	(FILE),A	; Store file pointer
	LD	A,D
	LD	(RANK),A	; Store rank pointer
	POP	AF		; Restore A register
	LD	HL,XPOINT	; For file (1-8)
	LD	(HL),161
	LD	B,A
CNVRT1: INC	(HL)		; File Norm address
	INC	(HL)
	INC	(HL)
	INC	(HL)
	INC	(HL)
	DJNZ	CNVRT1-$
	LD	HL,YPOINT
	LD	(HL),130
	LD	B,D
CNVRT2: INC	(HL)		; Rank Norm address
	INC	(HL)
	DJNZ	CNVRT2-$
	POP	AF		; Restore registers
	POP	DE
	POP	BC
	RET			; Return
;***********************************************************************
; POSITIVE INTEGER MULTIPLICATION
;***********************************************************************
MLTPLY: PUSH	BC
	SUB	A
	LD	B,8
ML04:	BIT	0,D
	JR	Z,ML10-$
	ADD	A,E
ML10:	SRA	A
	RR	D
	DJNZ	ML04-$
	POP	BC
	RET
;***********************************************************************
; POSITIVE INTEGER DIVISION
;***********************************************************************
DIVIDE: PUSH	BC
	LD	B,8
DD04:	SLA	D
	RLA
	SUB	E
	JP	M,DD9
	INC	D
	JR	DD10-$
DD9:	ADD	A,E
DD10:	DJNZ	DD04-$
	POP	BC
	RET
;***********************************************************************
; PATH ROUTINE
;***********************************************************************
; FUNCTION:	To generate a single position 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:	LD	HL,M2		; Get previous position
	LD	A,(HL)
	ADD	A,C		; Add direction constant
	LD	(HL),A		; Save new position
	LD	IX,(M2) 	; Load board index
	LD	A,(IX+BOARD)	; Get contents of board
	CP	-1		; In border area?
	JR	Z,PA2-$ 	; Yes - Jump
	LD	(P2),A		; Save piece
	AND	7		; Clear flags
	LD	(T2),A		; Save piece type
	RET	Z		; Return if empty
	LD	A,(P2)		; Get piece if encountered
	LD	HL,P1		; Get moving piece address
	XOR	(HL)		; Compare
	BIT	7,A		; Do colors match?
	JR	Z,PA1-$ 	; Yes - Jump
	LD	A,1		; Set different color flag
	RET			; Return
PA1:	LD	A,2		; Set same color flag
	RET			; Return
PA2:	LD	A,3		; Set off board flag
	RET			; Return
;***********************************************************************
; PIECE MOVER ROUTINE
;***********************************************************************
; FUNCTION:	To generate all the legal possible moves for a
;		given piece.
;
; CALLED BY:	GENMOV
;
; CALLS:	PATH	ADMOVE	CASTLE	ENPSNT
;
; ARGUMENTS:	The piece to be moved.
;***********************************************************************
MPIECE: XOR	(HL)		; Piece to move
	AND	87H		; Clear flag bit
	CP	BPAWN		; Is it a black Pawn?
	JR	NZ,MP50-$	; No - Skip
	DEC	A		; Decrement for black Pawns
MP50:	AND	7		; Get piece type
	LD	(T1),A		; Save piece type
	LD	IY,(T1) 	; Load index to DCOUNT/DPOINT
	LD	B,(IY+DCOUNT)	; Get direction count
	LD	A,(IY+DPOINT)	; Get direction pointer
	LD	(INDX2),A	; Save as index to direct
	LD	IY,(INDX2)	; Load index
MP5:	LD	C,(IY+DIRECT)	; Get move direction
	LD	A,(M1)		; From position
	LD	(M2),A		; Initialize to position
MP10:	CALL	PATH		; Calcuate next position
	CP	2		; Ready for new direction?
	JR	NC,MP15-$	; Yes - Jump
	AND	A		; Test for empty square
	EX	AF,AF'          ; Save result
	LD	A,(T1)		; Get piece moved
	CP	PAWN+1		; Is it a Pawn?
	JR	C,MP20-$	; Yes - Jump
	CALL	ADMOVE		; Add move to list
	EX	AF,AF'          ; Empty square?
	JR	NZ,MP15-$	; No - Jump
	LD	A,(T1)		; Piece type
	CP	KING		; King?
	JR	Z,MP15-$	; Yes - Jump
	CP	BISHOP		; Bishop, Rook, or Queen?
	JR	NC,MP10-$	; Yes - Jump
MP15:	INC	IY		; Increment direction index
	DJNZ	MP5-$		; Decrement count - Jump if non-zero
	LD	A,(T1)		; Piece type
	CP	KING		; King?
	CALL	Z,CASTLE	; Yes - Try Castling
	RET
; ****	PAWN LOGIC *****
MP20:	LD	A,B		; Counter for direction
	CP	3		; On diagonal moves?
	JR	C,MP35-$	; Yes - Jump
	JR	Z,MP30-$	; -or- Jump if on 2 square move
	EX	AF,AF'          ; Is forward square empty?
	JR	NZ,MP15-$	; No - Jump
	LD	A,(M2)		; Get "to" position
	CP	91		; Promote white Pawn?
	JR	NC,MP25-$	; Yes - Jump
	CP	29		; Promote black Pawn?
	JR	NC,MP26-$	; No - Jump
MP25:	LD	HL,P2		; Flag address
	SET	5,(HL)		; Set promote flag
MP26:	CALL	ADMOVE		; Add to move list
	INC	IY		; Adjust to two square move
	DEC	B
	LD	HL,P1		; Check Pawn moved flag
	BIT	3,(HL)		; Has it been moved before?
	JR	Z,MP10-$	; No - Jump
	JR	MP15-$		; Jump
MP30:	EX	AF,AF'          ; Is the forward square empty?
	JR	NZ,MP15-$	; No - Jump
MP31:	CALL	ADMOVE		; Add to move list
	JR	MP15-$		; Jump
MP35:	EX	AF,AF'          ; Is the diagonal square empty?
	JR	Z,MP36-$	; Yes - Jump
	LD	A,(M2)		; Get "to" position
	CP	91		; Promote white Pawn?
	JR	NC,MP37-$	; Yes - Jump
	CP	29		; Black Pawn promotion?
	JR	NC,MP31-$	; No - Jump
MP37:	LD	HL,P2		; Get flag address
	SET	5,(HL)		; Set promote flag
	JR	MP31-$		; Jump
MP36:	CALL	ENPSNT		; Try en passant capture
	JP	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: LD	A,(M1)		; Set position of Pawn
	LD	HL,P1		; Check color
	BIT	7,(HL)		; Is it white?
	JR	Z,EP20-$	; Yes - skip
	ADD	A,10		; Add 10 for black
EP20:	CP	61		; On en passant capture rank?
	RET	C		; No - Return
	CP	69		; On en passant capture rank?
	RET	NC		; No - Return
	LD	IX,(MLPTRJ)	; Get pointer to previous move
	BIT	4,(IX+MLFLG)	; First move for that piece?
	RET	Z		; No - Return
	LD	A,(IX+MLTOP)	; Get "to" position
	LD	(M4),A		; Store as index to board
	LD	IX,(M4) 	; Load board index
	LD	A,(IX+BOARD)	; Get piece moved
	LD	(P3),A		; Save it
	AND	7		; Get piece type
	CP	PAWN		; Is it a Pawn?
	RET	NZ		; No - Return
	LD	A,(M4)		; Get "to" position
	LD	HL,M2		; Get present "to" position
	SUB	(HL)		; Find difference
	JP	P,EP30		; Positive?  Yes - Jump
	NEG			; Else take absolute value
EP30:	CP	10		; Is difference 10?
	RET	NZ		; No - return
	LD	HL,P2		; Address of flags
	SET	6,(HL)		; Set double move flag
	CALL	ADMOVE		; Add Pawn move to move list
	LD	A,(M1)		; Save initial Pawn position
	LD	(M3),A
	LD	A,(M4)		; Set "from" and "to" positions
				; for dummy move
	LD	(M1),A
	LD	(M2),A
	LD	A,(P3)		; Save captured Pawn
	LD	(P2),A
	CALL	ADMOVE		; Add Pawn capture to move list
	LD	A,(M3)		; Restore "from" position
	LD	(M1),A
;***********************************************************************
; 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: LD	HL,(MLLST)	; Get list pointer
	LD	DE,-6		; Size of a move entry
	ADD	HL,DE		; Back up list pointer
	LD	(MLLST),HL	; Save list pointer
	LD	(HL),0		; Zero out link, first byte
	INC	HL		; Next byte
	LD	(HL),0		; Zero out link, second byte
	RET
;***********************************************************************
; 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: LD	A,(P1)		; Get King
	BIT	3,A		; Has it moved?
	RET	NZ		; Yes - return?
	LD	A,(CKFLG)	; Fetch Check Flag
	AND	A		; Is the King in check?
	RET	NZ		; Yes - Return
	LD	BC,0FF03H	; Initialize King-side values
CA5:	LD	A,(M1)		; King position
	ADD	A,C		; Rook position
	LD	C,A		; Save
	LD	(M3),A		; Store as board index
	LD	IX,(M3) 	; Load board index
	LD	A,(IX+BOARD)	; Get contents of board
	AND	7FH		; Clear color bit
	CP	ROOK		; Has Rook ever moved?
	JR	NZ,CA20-$	; Yes - Jump
	LD	A,C		; Restore Rook position
	JR	CA15-$		; Jump
CA10:	LD	IX,(M3) 	; Load board index
	LD	A,(IX+BOARD)	; Get contents of board
	AND	A		; Empty?
	JR	NZ,CA20-$	; No - Jump
	LD	A,(M3)		; Current position
	CP	22		; White Queen Knight square?
	JR	Z,CA15-$	; Yes - Jump
	CP	92		; Black Queen Knight square?
	JR	Z,CA15-$	; Yes - Jump
	CALL	ATTACK		; Look for an attack on square
	AND	A		; Any attackers?
	JR	NZ,CA20-$	; Yes - Jump
	LD	A,(M3)		; Current position
CA15:	ADD	A,B		; Next position
	LD	(M3),A		; Save as board index
	LD	HL,M1		; King position
	CP	(HL)		; Reached King?
	JR	NZ,CA10-$	; No - Jump
	SUB	B		; Determine King's position
	SUB	B
	LD	(M2),A		; Save it
	LD	HL,P2		; Address of flags
	LD	(HL),40H	; Set double move flag
	CALL	ADMOVE		; Put King move in list
	LD	HL,M1		; Addr of King "from" position
	LD	A,(HL)		; Get King's "from" position
	LD	(HL),C		; Store Rook "from" positon
	SUB	B		; Get Rook "to" position
	LD	(M2),A		; Store Rook "to" position
	XOR	A		; Zero
	LD	(P2),A		; Zero move flags
	CALL	ADMOVE		; Put Rook move in list
	CALL	ADJPTR		; Re-adjust move list pointer
	LD	A,(M3)		; Restore King position
	LD	(M1),A		; Store
CA20:	LD	A,B		; Scan index
	CP	1		; Done?
	RET	Z		; Yes - Return
	LD	BC,01FCH	; Set Queen-side initial values
	JP	CA5		; Jump
;***********************************************************************
; ADMOVE ROUTINE
;***********************************************************************
; FUNCTION:	To add a move to the move list
;
; CALLED BY:	MPIECE	ENPSNT	CASTLE
;
; CALLS:	None
;
; ARGUMENTS:	None
;***********************************************************************
ADMOVE: LD	DE,(MLNXT)	; Addr of next loc in move list
	LD	HL,MLEND	; Address of list end
	AND	A		; Clear carry flag
	SBC	HL,DE		; Calcuate difference
	JR	C,AM10-$	; Jump if out of space
	LD	HL,(MLLST)	; Addr of prev. list area
	LD	(MLLST),DE	; Save next as previous
	LD	(HL),E		; Store link address
	INC	HL
	LD	(HL),D
	LD	HL,P1		; Address of moved piece
	BIT	3,(HL)		; Has it moved before?
	JR	NZ,AD20-$	; Yes - Jump
	LD	HL,P2		; Address of move flags
	SET	4,(HL)		; Set first move flag
AD20:	EX	DE,HL		; Address of move area
	LD	(HL),0		; Store zero in link address
	INC	HL
	LD	(HL),0
	INC	HL
	LD	A,(M1)		; Store "from" move position
	LD	(HL),A
	INC	HL
	LD	A,(M2)		; Store "to" move position
	LD	(HL),A
	INC	HL
	LD	A,(P2)		; Store move flags/capt. piece
	LD	(HL),A
	INC	HL
	LD	(HL),0		; Store initial move value
	INC	HL
	LD	(MLNXT),HL	; Save address for next move
	RET			; Return
AM10:	LD	(HL),0		; Abort entry on table overflow
	INC	HL
	LD	(HL),0
	DEC	HL
	RET
;***********************************************************************
; GENERATE MOVE ROUTINE
;***********************************************************************
; FUNCTION:	To generate the move set for all of
;		pieces of a given color.
;
; CALLED BY:	FNDMOV
;
; CALLS:	MPIECE	INCHK
;
; ARGUMENTS:	None
;***********************************************************************
GENMOV: CALL	INCHK		; Test for King in check
	LD	(CKFLG),A	; Save attack count as flag
	LD	DE,(MLNXT)	; Addr of next available list space
	LD	HL,(MLPTRI)	; Ply list pointer index
	INC	HL		; Increment to next ply
	INC	HL
	LD	(HL),E		; Save move list pointer
	INC	HL
	LD	(HL),D
	INC	HL
	LD	(MLPTRI),HL	; Save new index
	LD	(MLLST),HL	; Last pointer for chain initialization
	LD	A,21		; First position on board
GM5:	LD	(M1),A		; Save as index
	LD	IX,(M1) 	; Load board index
	LD	A,(IX+BOARD)	; Fetch board contents
	AND	A		; Is it empty?
	JR	Z,GM10-$	; Yes - Jump
	CP	-1		; Is it a border square?
	JR	Z,GM10-$	; Yes - Jump
	LD	(P1),A		; Save piece
	LD	HL,COLOR	; Address of color of piece
	XOR	(HL)		; Test color of piece
	BIT	7,A		; Match?
	CALL	Z,MPIECE	; Yes - Call Move Piece
GM10:	LD	A,(M1)		; Fetch current position
	INC	A		; Increment to next board position
	CP	99		; End of board array?
	JR	NZ,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
;
; ARGUEMENTS:	Color of King
;***********************************************************************
INCHK:	LD	A,(COLOR)	; Get color
INCHK1: LD	HL,POSK 	; Addr of white King position
	AND	A		; White?
	JR	Z,INCK5-$	; Yes - Skip
	INC	HL		; Addr of black King position
INCK5:	LD	A,(HL)		; Fetch King position
	LD	(M3),A		; Save
	LD	IX,(M3) 	; Load board index
	LD	A,(IX+BOARD)	; Fetch board contents
	LD	(P1),A
	AND	7		; Save
	LD	(T1),A		; Get piece type
	CALL	ATTACK		; Save
	RET			; Return
;***********************************************************************
; ATTACK ROUTINE
;***********************************************************************
; FUNCTION:	To determine all attackers on a given square
;		by scanning outward from the square
;		until a piece is found that attacks
;		that square or a piece is found that
;		does not attack that square, or the edge
;		of the board is reached.
;
;		     In determining which pieces attack
;		square, this routine also takes into
;		account the ability of certain pieces to
;		attack through another attacking piece.  (For
;		example a Queen lined up behind a Bishop
;		of her sane color along a diagonal.)  The
;		Bishop is then said to be transparent to the
;		Queen, since both participate in the attack.
;
;		     In the case where this routine is called
;		by CASTLE or INCHK, the routine is
;		terminated as soon as an attacker of the
;		opposite color is encountered.
;
; CALLED BY:	POINTS	PINFND	CASTLE	INCHK
;
; CALLS:	PATH	ATKSAV
;
; ARGUMENTS:	None
;***********************************************************************
ATTACK: PUSH	BC		; Save Register B
	XOR	A		; Clear
	LD	B,16		; Initial direction count
	LD	(INDX2),A	; Initial direction index
	LD	IY,(INDX2)	; Load index
AT5:	LD	C,(IY+DIRECT)	; Get direction
	LD	D,0		; Init. scan count/flags
	LD	A,(M3)		; Init. board start position
	LD	(M2),A		; Save
AT10:	INC	D		; Increment scan count
	CALL	PATH		; Next position
	CP	1		; Piece of an opposite color?
	JR	Z,AT14A-$	; Yes - Jump
	CP	2		; Piece of the same color?
	JR	Z,AT14B-$	; Yes - Jump
	AND	A		; Empty position?
	JR	NZ,AT12-$	; No - Jump
	LD	A,B		; Fetch direction count
	CP	9		; On Knight scan?
	JR	NC,AT10-$	; No - Jump
AT12:	INC	IY		; Increment direction index
	DJNZ	AT5-$		; Done?  No - Jump
	XOR	A		; There are no attackers
AT13:	POP	BC		; Restore register B
	RET			; Return
AT14A:	BIT	6,D		; Same color found already?
	JR	NZ,AT12-$	; Yes - Jump
	SET	5,D		; Set opposite color found flag
	JR	AT14-$		; Jump
AT14B:	BIT	5,D		; Same color found already?
	JR	NZ,AT12-$	; Yes - Jump
	SET	6,D		; Set same color found flag
; ***** DETERMINE IF PIECE ENCOUNTERED ATTACKS SQUARE *****
AT14:	LD	A,(T2)		; Fetch piece type encountered
	LD	E,A		; Save
	LD	A,B		; Get direction counter
	CP	9		; Look for Knights?
	JR	C,AT25-$	; Yes - Jump
	LD	A,E		; Get piece type
	CP	QUEEN		; Is it a Queen?
	JR	NZ,AT15-$	; No - Jump
	SET	7,D		; Set Queen found flag
	JR	AT30-$		; Jump
AT15:	LD	A,D		; Get flag/scan count
	AND	0FH		; Isolate count
	CP	1		; On first position?
	JR	NZ,AT16-$	; No - Jump
	LD	A,E		; Get encountered piece type
	CP	KING		; Is it a King?
	JR	Z,AT30-$	; Yes - Jump
AT16:	LD	A,B		; Get direction counter
	CP	13		; Scanning files or ranks
	JR	C,AT21-$	; Yes - Jump
	LD	A,E		; Get piece type
	CP	BISHOP		; Is it a Bishop?
	JR	Z,AT30-$	; Yes - Jump
	LD	A,D		; Get flags/scan count
	AND	0FH		; Isolate count
	CP	1		; On first position?
	JR	NZ,AT12-$	; No - Jump
	CP	E		; Is it a Pawn?
	JR	NZ,AT12-$	; No - Jump
	LD	A,(P2)		; Fetch piece including color
	BIT	7,A		; Is it white?
	JR	Z,AT20-$	; Yes - Jump
	LD	A,B		; Get direction counter
	CP	15		; On a non-attacking diagonal?
	JR	C,AT12-$	; Yes - Jump
	JR	AT30-$		; Jump
AT20:	LD	A,B		; Get direction counter
	CP	15		; On a non-attacking diagonal?
	JR	NC,AT12-$	; Yes - Jump
	JR	AT30-$		; Jump
AT21:	LD	A,E		; Get piece type
	CP	ROOK		; Is it a Rook?
	JR	NZ,AT12-$	; No - Jump
	JR	AT30-$		; Jump
AT25:	LD	A,E		; Get piece type
	CP	KNIGHT		; Is it a Knight?
	JR	NZ,AT12-$	; No - Jump
AT30:	LD	A,(T1)		; Attacked piece type/flag
	CP	7		; Call from POINTS?
	JR	Z,AT31-$	; Yes - Jump
	BIT	5,D		; Is attacker opposite color
	JR	Z,AT32-$	; No - Jump
	LD	A,1		; Set attacker found flag
	JP	AT13		; Jump
AT31:	CALL	ATKSAV		; Save attacker in attack list
AT32:	LD	A,(T2)		; Attacking piece type
	CP	KING		; Is it a King?
	JP	Z,AT12		; Yes - Jump
	CP	KNIGHT		; Is it a Knight?
	JP	Z,AT12		; Yes - Jump
	JP	AT10		; Jump
;***********************************************************************
; ATTACK SAVE ROUTINE
;***********************************************************************
; FUNCTION:	To save an attacking piece value in the
;		attack list, and to increment the attack
;		count for that color piece.
;
;		The pin piece list is checked for the
;		attacking piece, and if found there, the
;		piece is not included in the attack list.
;
; CALLED BY:	ATTACK
;
; CALLS:	PNCK
;
; ARGUMENTS:	None
;**************************************************************************
ATKSAV: PUSH	BC		; Save Regs BC
	PUSH	DE		; Save Regs DE
	LD	A,(NPINS)	; Number of pinned pieces
	AND	A		; Any?
	CALL	NZ,PNCK 	; Yes - check pin list
	LD	IX,(T2) 	; Initialize index to value table
	LD	HL,ATKLST	; Initialize address of attack list
	LD	BC,0		; Initialize increment for white
	LD	A,(P2)		; Attacking piece
	BIT	7,A		; Is it white?
	JR	Z,AS30-$	; Yes - Jump
	LD	C,7		; Initialize increment for black
AS30:	AND	7		; Attacking piece type
	LD	E,A		; Initialize increment tor type
	BIT	7,D		; Queen found this scan
	JR	Z,AS40-$	; No - Jump
	LD	E,QUEEN 	; Use Queen slot in attack list
AS40:	ADD	HL,BC		; Attack list adddress
	INC	(HL)		; Increment list count
	LD	D,0
	ADD	HL,DE		; Attack list slot address
	LD	A,(HL)		; Get data already there
	AND	0FH		; Is first slot empty
	JR	Z,AS20-$	; Yes - Jump
	LD	A,(HL)		; Get data again
	AND	0F0H		; Is second slot empty?
	JR	Z,AS19-$	; Yes - Jump
	INC	HL		; Increment to King slot
	JR	AS20-$		; Jump
AS19:	RLD			; Temp save lower in upper
	LD	A,(IX+PVALUE)	; Get new value for attack list
	RRD			; Put in 2nd attack list slot
	JR	AS25-$		; Jump
AS20:	LD	A,(IX+PVALUE)	; Get new value for attack list
	RLD			; Put in 1st attack list slot
AS25:	POP	DE		; Restore DE registers
	POP	BC		; Restore BC registers
	RET			; Return
;***************************************************************************
; PIN CHECK ROUTINE
;**************************************************************************
; FUNCTION:	Checks to see if the attacker is in the
;		pinned piece list. If so he is not a valid
;		attacker unless the direction in which he
;		attacks is the same as the direction along
;		which he is pinned.  If the piece is
;		found to be invalid as an attacker, the
;		return to the calling routinne is aborted
;		and this routine returns directly to ATTACK.
;
; CALLED BY:	ATKSAV
;
; CALLS:	None
;
; ARGUMENTS:	The direction of the attack.
;		The pinned piece count.
;***************************************************************************
PNCK:	LD	D,C		; Save attack direction
	LD	E,0		; Clear flag
	LD	C,A		; Load pin count for search
	LD	B,0
	LD	A,(M2)		; Position of piece
	LD	HL,PLISTA	; Pin list adress
PC1:	CPIR			; Search list for position
	RET	NZ		; Return if not found
	EX	AF,AF'          ; Save search parameters
	BIT	0,E		; Is this the first find?
	JR	NZ,PC5-$	; No - Jump
	SET	0,E		; Set first find flag
	PUSH	HL		; Get corresponding index to dir list
	POP	IX
	LD	A,(IX+9)	; Get direction
	CP	D		; Same as attacking direction
	JR	Z,PC3-$ 	; Yes - Jump
	NEG			; Opposite direction?
	CP	D		; Same as attacking direction?
	JR	NZ,PC5-$	; No - Jump
PC3:	EX	AF,AF'          ; Restore search parameters
	JP	PE,PC1		; Jump if search not complete
	RET			; Return
PC5:	POP	AF		; Abnormal exit
	POP	DE		; Restore registers
	POP	BC
	RET			; Return to attack
;***************************************************************************
; PIN FIND ROUTINE
;***************************************************************************
; FUNCTION:	To produce a list of all pieces pinned
;		against a King or Queen, for both white and black.
;
; CALLED BY:	FNDMOV	EVAL
;
; CALLS:	PATH	ATTACK
;
; ARGUEMENTS:	None
;****************************************************************************
PINFND: XOR	A		; Zero pin count
	LD	(NPINS),A
	LD	DE,POSK 	; Address of King/Queen position list
PF1:	LD	A,(DE)		; Get position of royal piece
	AND	A		; Is it on the board
	JP	Z,PF26		; No - Jump
	CP	-1		; At end of list
	RET	Z		; Yes - Return
	LD	(M3),A		; Save position as board index
	LD	IX,(M3) 	; Load index to board
	LD	A,(IX+BOARD)	; Get contents of board
	LD	(P1),A		; Save
	LD	B,8		; Init scan direction count
	XOR	A
	LD	(INDX2),A	; Init direction index
	LD	IY,(INDX2)
PF2:	LD	A,(M3)		; Get King/Queen position
	LD	(M2),A		; Save
	XOR	A
	LD	(M4),A		; Clear pinned piece saved position
	LD	C,(IY+DIRECT)	; Get direction of scan
PF5:	CALL	PATH		; Compute nextt position
	AND	A		; Is it empty
	JR	Z,PF5-$ 	; Yes - Jump
	CP	3		; Off the board?
	JP	Z,PF25		; Yes - Jump
	CP	2		; Piece of the same color found?
	LD	A,(M4)		; Load pinned piece position
	JR	Z,PF15-$	; Yes - jump
	AND	A		; Possible pin?
	JP	Z,PF25		; No - Jump
	LD	A,(T2)		; Piece type encountered
	CP	QUEEN		; Queen?
	JR	Z,PF19-$	; Yes - Jump
	LD	L,A		; Save piece type
	LD	A,B		; Direction counter
	CP	5		; Non-diagonal direction
	JR	C,PF10-$	; Yes - Jump
	LD	A,L		; Piece type
	CP	BISHOP		; Bishop?
	JR	NZ,PF25-$	; No - Jump
	JR	PF20-$		; Jump
PF10:	LD	A,L		; Piece type
	CP	ROOK		; Rook?
	JR	NZ,PF25-$	; No - Jump
	JR	PF20-$		; Jump
PF15:	AND	A		; Possible pin?
	JR	NZ,PF25-$	; No - Jump
	LD	A,(M2)		; Save possible pin position
	LD	(M4),A
	JR	PF5-$		; Jump
PF19:	LD	A,(P1)		; Load King or Queen
	AND	7		; Clear flags
	CP	QUEEN		; Queen?
	JR	NZ,PF20-$	; No - Jump
	PUSH	BC		; Save regs.
	PUSH	DE
	PUSH	IY
	XOR	A		; Zero out attack list
	LD	B,14
	LD	HL,ATKLST
PF50:	LD	(HL),A
	INC	HL
	DJNZ	PF50-$
	LD	A,7		; Set attack flag
	LD	(T1),A
	CALL	ATTACK		; Find attackers/defenders
	LD	HL,WACT 	; White Queen attackers
	LD	DE,BACT 	; Black Queen attackers
	LD	A,(P1)		; Get Queen
	BIT	7,A		; Is she white?
	JR	Z,PF30-$	; Yes - Jump
	EX	DE,HL		; Reverse for black
PF30:	LD	A,(HL)		; Number of defenders
	EX	DE,HL		; Reverse for attackers
	SUB	(HL)		; Defenders minus attackers
	DEC	A		; Less 1
	POP	IY		; Restore registers
	POP	DE
	POP	BC
	JP	P,PF25		; Jump if pin not valid
PF20:	LD	HL,NPINS	; Address of pinned piece count
	INC	(HL)		; Increment
	LD	IX,(NPINS)	; Load pin list index
	LD	(IX+PLISTD),C	; Save direction of pin
	LD	A,(M4)		; Position of pinned piece
	LD	(IX+PLIST),A	; Save in list
PF25:	INC	IY		; Increment direction index
	DJNZ	PF27-$		; Done?  No - Jump
PF26:	INC	DE		; Incr king/queen pos index
	JP	PF1		; Jump
PF27:	JP	PF2		; Jump
;**************************************************************************
; EXCHANGE ROUTINE
;**************************************************************************
; FUNCTION:	To determine the exchange value of a
;		on a given square by examining all
;		attackers and defenders of that piece.
;
; CALLED BY:	POINTS
;
; CALLS:	NEXTAD
;
; ARGUMENTS:	None
;**************************************************************************
XCHNG:	EXX			; Swap registers
	LD	A,(P1)		; Piece attacked
	LD	HL,WACT 	; Addr of white attkrs/defenders
	LD	DE,BACT 	; Addr of black attkrs/defenders
	BIT	7,A		; Is piece white?
	JR	Z,XC20-$	; Yes - Jump
	EX	DE,HL		; Swap list pointers
XC20:	LD	B,(HL)		; Initialize list counts
	EX	DE,HL
	LD	C,(HL)
	EX	DE,HL
	EXX			; Restore registers
	LD	C,0		; Init attacker/defender flag
	LD	E,0		; Init points lost count
	LD	IX,(T3) 	; Load piece value index
	LD	D,(IX+PVALUE)	; Get attacked piece value
	SLA	D		; Double it
	LD	B,D		; Save
	CALL	NEXTAD		; Retrieve first attacker
	RET	Z		; Return if none
XC10:	LD	L,A		; Save attacker value
	CALL	NEXTAD		; Get next defender
	JR	Z,XC18-$	; Jump if none
	EX	AF,AF'          ; Save defender value
	LD	A,B		; Get attacked value
	CP	L		; Attacked less than attacker?
	JR	NC,XC19-$	; No - Jump
	EX	AF,AF'          ; Restore defender
XC15:	CP	L		; Defender less than attacker?
	RET	C		; Yes - Return
	CALL	NEXTAD		; Retrieve next attacker value
	RET	Z		; Return if none
	LD	L,A		; Save attacker value
	CALL	NEXTAD		; Retrieve next defender value
	JR	NZ,XC15-$	; Jump if none
XC18:	EX	AF,AF'          ; Save defender
	LD	A,B		; Get value of attacked piece
XC19:	BIT	0,C		; Attacker or defender?
	JR	Z,XC30-$	; Jump if defender
	NEG			; Negate value for attacker
XC30:	ADD	A,E		; Total points lost
	LD	E,A		; Save total
	EX	AF,AF'          ; Restore previous defender
	RET	Z		; Return if none
	LD	B,L		; Prev attacker becomes defender
	JR	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	C		; Increment side flag
	EXX			; Swap registers
	LD	A,B		; Swap list counts
	LD	B,C
	LD	C,A
	EX	DE,HL		; Swap list pointers
	XOR	A
	CP	B		; At end of list?
	JR	Z,NX6-$ 	; Yes - Jump
	DEC	B		; Decrement list count
NX10:	INC	HL		; Increment list pointer
	CP	(HL)		; Check next item in list
	JR	Z,NX10-$	; Jump if empty
	RRD			; Get value from list
	ADD	A,A		; Double it
	DEC	HL		; Decrement list pointer
NX6:	EXX			; Restore registers
	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
;
; ARGUMNENTS:	None
;***************************************************************************
POINTS: XOR	A		; Zero out variables
	LD	(MTRL),A
	LD	(BRDC),A
	LD	(PTSL),A
	LD	(PTSW1),A
	LD	(PTSW2),A
	LD	(PTSCK),A
	LD	HL,T1		; Set attacker flag
	LD	(HL),7		;
	LD	A,21		; Init to first square on the board
PT5:	LD	(M3),A		; Save as board index
	LD	IX,(M3) 	; Load board index
	LD	A,(IX+BOARD)	; Get piece from board
	CP	-1		; Off board edge?
	JP	Z,PT25		; Yes - Jump
	LD	HL,P1		; Save piece, if any
	LD	(HL),A
	AND	7		; Save piece type, if any
	LD	(T3),A
	CP	KNIGHT		; Less than a Knight (Pawn)?
	JR	C,PT6X-$	; Yes - Jump
	CP	ROOK		; Rook, Queen or King
	JR	C,PT6B-$	; No - Jump
	CP	KING		; Is it a King?
	JR	Z,PT6AA-$	; Yes - Jump
	LD	A,(MOVENO)	; Get move number
	CP	7		; Less than 7?
	JR	C,PT6A-$	; Yes - Jump
	JR	PT6X-$		; Jump
PT6AA:	BIT	4,(HL)		; Castled yet?
	JR	Z,PT6A-$	; No - Jump
	LD	A,6		; Bonus for white castling
	BIT	7,(HL)		; Check piece color
	JR	Z,PT6D-$	; Jump if white
	LD	A,-6		; Bonus for black castling
	JR	PT6D-$		; Jump
PT6A:	BIT	3,(HL)		; Has piece moved yet?
	JR	Z,PT6X-$	; No - Jump
	JR	PT6C-$		; Jump
PT6B:	BIT	3,(HL)		; Has piece moved yet?
	JR	NZ,PT6X-$	; Jump
PT6C:	LD	A,-2		; Two points penalty for white
	BIT	7,(HL)		; Check piece color
	JR	Z,PT6D-$	; Jump if white
	LD	A,2		; Two points penalty for black
PT6D:	LD	HL,BRDC 	; Get address of board control
	ADD	A,(HL)		; Add on penalty/bonus points
	LD	(HL),A		; Save
PT6X:	XOR	A		; Zero out attack list
	LD	B,14
	LD	HL,ATKLST
PT85:	LD	(HL),A
	INC	HL
	DJNZ	PT85-$
	CALL	ATTACK		; Build attack list for square
	LD	HL,BACT 	; Get black attacker count addr
	LD	A,(WACT)	; Get white attacker count
	SUB	(HL)		; Accumulate board control score
	LD	HL,BRDC 	; Address of board control
	ADD	A,(HL)		; Accumulate board control score
	LD	(HL),A		; Save
	LD	A,(P1)		; Get piece on current square
	AND	A		; Is it empty?
	JR	Z,PT25-$	; Yes - Jump
	CALL	XCHNG		; Evaluate exchange, if any
	XOR	A		; Check for a loss
	CP	E		; Points lost?
	JR	Z,PT23-$	; No - Jump
	DEC	D		; Deduct half a pawn value
	LD	A,(P1)		; Get piece under attack
	LD	HL,COLOR	; Color of side just moved
	XOR	(HL)		; Compare with piece
	BIT	7,A		; Do colors match?
	LD	A,E		; Points lost
	JR	NZ,PT20-$	; Jump if no match
	LD	HL,PTSL 	; Previous max points lost
	CP	(HL)		; Compare to current value
	JR	C,PT23-$	; Jump if greater than
	LD	(HL),E		; Store new value as max lost
	LD	IX,(MLPTRJ)	; Load pointer to this move
	LD	A,(M3)		; Get position of lost piece
	CP	(IX+MLTOP)	; Is it the one moving?
	JR	NZ,PT23-$	; No - Jump
	LD	(PTSCK),A	; Save position as a flag
	JR	PT23-$		; Jump
PT20:	LD	HL,PTSW1	; Previous maximum points won
	CP	(HL)		; Compare to current value
	JR	C,PT50-$	; Jump if greater than
	LD	A,(HL)		; Load previous maximum value
	LD	(HL),E		; Store new value as maximum won
PT50:	LD	HL,PTSW2	; Previous 2nd max points won
	CP	(HL)		; Compare to current value
	JR	C,PT23-$	; Jump if greater than
	LD	(HL),A		; Store as new 2nd max lost
PT23:	LD	HL,P1		; Get piece
	BIT	7,(HL)		; Test color
	LD	A,D		; Value of piece
	JR	Z,PT55-$	; Jump if white
	NEG			; Negate if black
PT55:	LD	HL,MTRL 	; Get addrs of material total
	ADD	A,(HL)		; Add new value
	LD	(HL),A		; Store
PT25:	LD	A,(M3)		; Get current board position
	INC	A		; Increment
	CP	99		; At end of the board?
	JP	NZ,PT5		; No - Jump
	LD	A,(PTSCK)	; Moving piece lost flag
	AND	A		; Was it lost?
	JR	Z,PT25A-$	; No - Jump
	LD	A,(PTSW2)	; 2nd max points won
	LD	(PTSW1),A	; Store as max points won
	XOR	A		; Zero out 2nd max points won
	LD	(PTSW2),A
PT25A:	LD	A,(PTSL)	; Get max points lost
	AND	A		; Is it zero?
	JR	Z,PT60-$	; Yes - Jump
	DEC	A		; Decrement it
PT60:	LD	B,A		; Save it
	LD	A,(PTSW1)	; Max points won
	AND	A		; Is it zero?
	JR	Z,PT65-$	; Yes - Jump
	LD	A,(PTSW2)	; 2nd max points won
	AND	A		; Is it zero?
	JR	Z,PT65-$	; Yes - Jump
	DEC	A		; Decrement it
	SRL	A		; Divide it by 2
PT65:	SUB	B		; Subtract points lost
	LD	HL,COLOR	; Color of side just moved
	BIT	7,(HL)		; Is it white?
	JR	Z,PT70-$	; Yes - Jump
	NEG			; Negate for black
PT70:	LD	HL,MTRL 	; Net material on board
	ADD	A,(HL)		; Add exchange adjustments
	LD	HL,MV0		; Material at ply 0
	SUB	(HL)		; Subtract from current
	LD	B,A		; Save
	LD	A,30		; Load material limit
	CALL	LIMIT		; Limit to plus or minus value
	LD	E,A		; Save limited value
	LD	A,(BRDC)	; Get board control poinnts
	LD	HL,BC0		; Board control at ply 0
	SUB	(HL)		; Get difference
	LD	B,A		; Save
	LD	A,(PTSCK)	; Moving piece lost flag
	AND	A		; Is it zero?
	JR	Z,PT75-$	; Yes - Jump
	LD	B,0		; Zero board control points
PT75:	LD	A,6		; Load board control limit
	CALL	LIMIT		; Limit to plus or minus value
	LD	D,A		; Save limited value
	LD	A,E		; Get material points
	ADD	A,A		; Multiply by 4
	ADD	A,A
	ADD	A,D		; Add board control
	LD	HL,COLOR	; Color of side just moved
	BIT	7,(HL)		; Is it white?
	JR	NZ,PT80-$	; No - Jump
	NEG			; Negate for white
PT80:	ADD	A,80H		; Rescale score (neutral = 80H)
	LD	(VALM),A	; Save score
	LD	IX,(MLPTRJ)	; Load move list pointer
	LD	(IX+MLVAL),A	; 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 B
;			 register.
;		       - Value to limit in the A register.
;		Output - Limited value in the A register.
;***************************************************************************
LIMIT:	BIT	7,B		; Is the value negative?
	JR	Z,LIM10-$	; No - Jump
	NEG			; Make positive
	CP	B		; Compare to limit
	RET	NC		; Return if outside limit
	LD	A,B		; Output value as it is
	RET			; Return
LIM10:	CP	B		; Compare to limit
	RET	C		; Return if outside limit
	LD	A,B		; 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:	LD	HL,(MLPTRJ)	; Load move list pointer
	INC	HL		; Increment past link bytes
	INC	HL
MV1:	LD	A,(HL)		; "From" position
	LD	(M1),A		; Save
	INC	HL		; Increment pointer
	LD	A,(HL)		; "To" position
	LD	(M2),A		; Save
	INC	HL		; Increment pointer
	LD	D,(HL)		; Get captured piece/flags
	LD	IX,(M1) 	; Load "from" position board index
	LD	E,(IX+BOARD)	; Get piece moved
	BIT	5,D		; Test Pawn promotion flag
	JR	NZ,MV15-$	; Jump if set
	LD	A,E		; Piece moved
	AND	7		; Clear flag bits
	CP	QUEEN		; Is it a Queen?
	JR	Z,MV20-$	; Yes - Jump
	CP	KING		; Is it a King?
	JR	Z,MV30-$	; Yes - Jump
MV5:	LD	IY,(M2) 	; Load "to" position board index
	SET	3,E		; Set piece moved flag
	LD	(IY+BOARD),E	; Insert piece at new position
	LD	(IX+BOARD),0	; Empty previous position
	BIT	6,D		; Double move?
	JR	NZ,MV40-$	; Yes - Jump
	LD	A,D		; Get captured piece, if any
	AND	7
	CP	QUEEN		; Was it a Queen?
	RET	NZ		; No - Return
	LD	HL,POSQ 	; Addr of saved Queen position
	BIT	7,D		; Is Queen white?
	JR	Z,MV10-$	; Yes - Jump
	INC	HL		; Increment to black Queen position
MV10:	XOR	A		; Set saved position to zero
	LD	(HL),A
	RET			; Return
MV15:	SET	2,E		; Change Pawn to a Queen
	JR	MV5-$		; Jump
MV20:	LD	HL,POSQ 	; Addr of saved Queen position
MV21:	BIT	7,E		; Is Queen white?
	JR	Z,MV22-$	; Yes - Jump
	INC	HL		; Increment to black Queen position
MV22:	LD	A,(M2)		; Get new Queen position
	LD	(HL),A		; Save
	JR	MV5-$		; Jump
MV30:	LD	HL,POSK 	; Get saved King position
	BIT	6,D		; Castling?
	JR	Z,MV21-$	; No - Jump
	SET	4,E		; Set King castled flag
	JR	MV21-$		; Jump
MV40:	LD	HL,(MLPTRJ)	; Get move list pointer
	LD	DE,8		; Increment to next move
	ADD	HL,DE
	JP	MV1		; Jump (2nd part of double 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: LD	HL,(MLPTRJ)	; Load move list pointer
	INC	HL		; Increment past the link bytes
	INC	HL
UM1:	LD	A,(HL)		; Get "from" position
	LD	(M1),A		; Save
	INC	HL		; Increment pointer
	LD	A,(HL)		; Get "to" position
	LD	(M2),A		; Save
	INC	HL		; Increment pointer
	LD	D,(HL)		; Get captured piece/flags
	LD	IX,(M2) 	; Load "to" position board index
	LD	E,(IX+BOARD)	; Get piece moved
	BIT	5,D		; Was it a Pawn promotion?
	JR	NZ,UM15-$	; Yes - Jump
	LD	A,E		; Get piece moved
	AND	7		; Clear flag bits
	CP	QUEEN		; Was it a Queen?
	JR	Z,UM20-$	; Yes - Jump
	CP	KING		; Was it a King?
	JR	Z,UM30-$	; Yes - Jump
UM5:	BIT	4,D		; Is this the 1st move for this piece?
	JR	NZ,UM16-$	; Yes - Jump
UM6:	LD	IY,(M1) 	; Load "from" position board index
	LD	(IY+BOARD),E	; Return to previous board position
	LD	A,D		; Get captured piece, if any
	AND	8FH		; Clear flags
	LD	(IX+BOARD),A	; Return to board
	BIT	6,D		; Was it a double move?
	JR	NZ,UM40-$	; Yes - Jump
	LD	A,D		; Get captured piece, if any
	AND	7		; Clear flag bits
	CP	QUEEN		; Was it a Queen?
	RET	NZ		; No - Return
	LD	HL,POSQ 	; Address of saved Queen position
	BIT	7,D		; Is Queen white?
	JR	Z,UM10-$	; Yes - Jump
	INC	HL		; Increment to black Queen position
UM10:	LD	A,(M2)		; Queen's previous position
	LD	(HL),A		; Save
	RET			; Return
UM15:	RES	2,E		; Restore Queen to Pawn
	JR	UM5-$		; Jump
UM16:	RES	3,E		; Clear piece move flag
	JR	UM6-$		; Jump
UM20:	LD	HL,POSQ 	; Addr of saved Queen position
UM21:	BIT	7,E		; Is Queen white?
	JR	Z,UM22-$	; Yes - Jump
	INC	HL		; Increment to black Queen position
UM22:	LD	A,(M1)		; Get previous position
	LD	(HL),A		; Save
	JP	UM5		; Jump
UM30:	LD	HL,POSK 	; Address of saved King position
	BIT	6,D		; Was it a castle?
	JR	Z,UM21-$	; No - Jump
	RES	4,E		; Clear castled flag
	JR	UM21-$		; Jump
UM40:	LD	HL,(MLPTRJ)	; Load move list pointer
	LD	DE,8		; Increment to next move
	ADD	HL,DE
	JP	UM1		; Jump (2nd part of double move)
;***************************************************************************
; SORT ROUTINE
;***************************************************************************
; FUNCTION:	To sort the move list in order of
;		increasing move value scores.
;
; CALLED BY:	FNDMOV
;
; CALLS:	EVAL
;
; ARGUMENTS:	None
;***************************************************************************
SORTM:	LD	BC,(MLPTRI)	; Move list begin pointer
	LD	DE,0		; Initialize working pointers
SR5:	LD	H,B
	LD	L,C
	LD	C,(HL)		; Link to next move
	INC	HL
	LD	B,(HL)
	LD	(HL),D		; Store to link in list
	DEC	HL
	LD	(HL),E
	XOR	A		; End of list?
	CP	B
	RET	Z		; Yes - Return
SR10:	LD	(MLPTRJ),BC	; Save list pointer
	CALL	EVAL		; Evaluate move
	LD	HL,(MLPTRI)	; Beginning of move list
	LD	BC,(MLPTRJ)	; Restore list pointer
SR15:	LD	E,(HL)		; Next move for compare
	INC	HL
	LD	D,(HL)
	XOR	A		; At end of list?
	CP	D
	JR	Z,SR25-$	; Yes - Jump
	PUSH	DE		; Transfer move pointer
	POP	IX
	LD	A,(VALM)	; Get new move value
	CP	(IX+MLVAL)	; Less than list value?
	JR	NC,SR30-$	; No - Jump
SR25:	LD	(HL),B		; Link new move into list
	DEC	HL
	LD	(HL),C
	JR	SR5-$		; Jump
SR30	EX	DE,HL		; Swap pointers
	JR	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	A		; Legal move?
	JR	Z,EV5-$ 	; Yes - Jump
	XOR	A		; Score of zero
	LD	(VALM),A	; For illegal move
	JR	EV10-$		; Jump
EV5:	CALL	PINFND		; Compile pinned list
	CALL	POINTS		; Assign points to move
EV10:	CALL	UNMOVE		; Restore board array
	RET			; Return
;**************************************************************************
; 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	MOVE
;
; ARGUMENTS:	None
;**************************************************************************
FNDMOV: LD	A,(MOVENO)	; Current move number
	CP	1		; First move?
	CALL	Z,BOOK		; Yes - execute book opening
	XOR	A		; Initialize ply number to zero
	LD	(NPLY),A
	LD	HL,0		; Initialize best move to zero
	LD	(BESTM),HL
	LD	HL,MLIST	; Initialize ply list pointers
	LD	(MLNXT),HL
	LD	(MLPTRJ),HL
	LD	HL,PLYIX-2
	LD	(MLPTRI),HL
	LD	A,(KOLOR)	; Initialize color
	LD	(COLOR),A
	LD	HL,SCORE	; Initialize score index
	LD	(SCRIX),HL
	LD	A,(PLYMAX)	; Get max ply number
	ADD	A,2		; Add 2
	LD	B,A		; Save as counter
	XOR	A		; Zero out score table
FM41:	LD	(HL),A
	INC	HL
	DJNZ	FM41-$
	LD	(BC0),A 	; Zero ply 0 board control
	LD	(MV0),A 	; Zero ply 0 material
	CALL	PINFND		; Compile pin list
	CALL	POINTS		; Evaluate board at ply 0
	LD	A,(BRDC)	; Get board control points
	LD	(BC0),A 	; Save
	LD	A,(MTRL)	; Get material count
	LD	(MV0),A 	; Save
FM5:	LD	HL,NPLY 	; Address of ply counter
	INC	(HL)		; Increment ply count
	XOR	A		; Initialize mate flag
	LD	(MATEF),A
	CALL	GENMOV		; Generate list of moves
	LD	A,(NPLY)	; Current ply counter
	LD	HL,PLYMAX	; Address of maximum ply number
	CP	(HL)		; At max ply?
	CALL	C,SORTM 	; No - Call SORTM
	LD	HL,(MLPTRI)	; Load ply index pointer
	LD	(MLPTRJ),HL	; Save as last move pointer
FM15:	LD	HL,(MLPTRJ)	; Load last move pointer
	LD	E,(HL)		; Get next move pointer
	INC	HL
	LD	D,(HL)
	LD	A,D
	AND	A		; End of move list?
	JR	Z,FM25-$	; Yes - Jump
	LD	(MLPTRJ),DE	; Save current move pointer
	LD	HL,(MLPTRI)	; Save in ply pointer list
	LD	(HL),E
	INC	HL
	LD	(HL),D
	LD	A,(NPLY)	; Current ply counter
	LD	HL,PLYMAX	; Maximum ply counter?
	CP	(HL)		; Compare
	JR	C,FM18-$	; Jump if not max
	CALL	MOVE		; Execute move on board array
	CALL	INCHK		; Check for legal move
	AND	A		; Is move legal?
	JR	Z,FM50-$	; Yes - Jump
	CALL	UNMOVE		; Restore board position
	JR	FM15-$		; Jump
FM50:	LD	A,(NPLY)	; Get ply number
	LD	HL,PLYMAX	; Max ply number
	CP	(HL)		; Beyond max ply
	JR	NZ,FM35-$	; Yes - Jump
	LD	A,(COLOR)	; Get current color
	XOR	80H		; Get opposite color
	CALL	INCHK1		; Determine if King is in check
	AND	A		; In check?
	JR	Z,FM35-$	; No - Jump
	JR	FM19-$		; Jump (One more ply for check)
FM18:	LD	IX,(MLPTRJ)	; Load move pointer
	LD	A,(IX+MLVAL)	; Get move score
	AND	A		; Is it zero (illegal move)?
	JR	Z,FM15-$	; Yes - Jump
	CALL	MOVE		; Execute move on board array
FM19:	LD	HL,COLOR	; Toggle color
	LD	A,80H
	XOR	(HL)
	LD	(HL),A		; Save new color
	BIT	7,A		; Is it white?
	JR	NZ,FM55-$	; No - Jump
	LD	HL,MOVENO	; Increment move counter
	INC	(HL)
FM55:	LD	HL,(SCRIX)	; Load score table pointer
	LD	A,(HL)		; Get score two plys above
	INC	HL		; Increment ply
	INC	HL
	LD	(HL),A		; Save score as initial value
	DEC	HL		; Decrement pointer
	LD	(SCRIX),HL	; Save it
	JP	FM5		; Jump
FM25:	LD	A,(MATEF)	; Get mate flag
	AND	A		; Checkmate or stalemate?
	JR	NZ,FM30-$	; No - Jump
	LD	A,(CKFLG)	; Get check flag
	AND	A		; Was King in check?
	LD	A,80H		; Pre-set stalemate score
	JR	Z,FM36-$	; No - Jump (stalemate)
	LD	A,(MOVENO)	; Get move number
	LD	(PMATE),A	; Save
	LD	A,0FFH		; Pre-set checkmate score
	JR	FM36-$		; Jump
FM30:	LD	A,(NPLY)	; Get ply counter
	CP	1		; At top of tree?
	RET	Z		; Yes - return
	CALL	ASCEND		; Ascend one ply in tree
	LD	HL,(SCRIX)	; Load score table pointer
	INC	HL		; Increment to current ply
	INC	HL
	LD	A,(HL)		; Get score
	DEC	HL		; Restore pointer
	DEC	HL
	JR	FM37-$		; Jump
FM35:	CALL	PINFND		; Compile pin list
	CALL	POINTS		; Evaluate move
	CALL	UNMOVE		; Restore board position
	LD	A,(VALM)	; Get value of move
FM36:	LD	HL,MATEF	; Set mate flag
	SET	0,(HL)
	LD	HL,(SCRIX)	; Load score table pointer
FM37:	CP	(HL)		; Compare to score 2 ply above
	JR	C,FM40-$	; Jump if less
	JR	Z,FM40-$	; Jump if equal
	NEG			; Negate score
	INC	HL		; Increment score table pointer
	CP	(HL)		; Compare to score 1 ply above
	JP	C,FM15		; Jump if less than
	JP	Z,FM15		; Jump if equal
	LD	(HL),A		; Save as new score 1 ply above
	LD	A,(NPLY)	; Get current ply counter
	CP	1		; At top of tree?
	JP	NZ,FM15 	; No - Jump
	LD	HL,(MLPTRJ)	; Load current move pointer
	LD	(BESTM),HL	; Save as best move pointer
	LD	A,(SCORE+1)	; Get best move score
	CP	0FFH		; Was it a checkmate?
	JP	NZ,FM15 	; No - Jump
	LD	HL,PLYMAX	; Get maximum ply number
	DEC	(HL)		; Subtract 2
	DEC	(HL)
	LD	A,(KOLOR)	; Get computer's color
	BIT	7,A		; Is it white?
	RET	Z		; Yes - Return
	LD	HL,PMATE	; Checkmate move number
	DEC	(HL)		; Decrement
	RET			; Return
FM40:	CALL	ASCEND		; Ascend one ply in tree
	JP	FM15		; Jump
;**************************************************************************
; ASCEND TREE ROUTINE
;**************************************************************************
; FUNCTION:  To adjust all necessary parameters to
;	     ascend one ply in the tree.
;
; CALLED BY: FNDMOV
;
; CALLS:     UNMOV
;
; ARGUMENTS: None
;**************************************************************************
ASCEND: LD	HL,COLOR	; Toggle color
	LD	A,80H
	XOR	(HL)
	LD	(HL),A		; Save new color
	BIT	7,A		; Is it white?
	JR	Z,ASC20-$	; Yes - Jump
	LD	HL,MOVENO	; Decrement move numbr
	DEC	(HL)
ASC20:	LD	HL,(SCRIX)	; Load score table index
	DEC	HL		; Decrement
	LD	(SCRIX),HL	; Save
	LD	HL,NPLY 	; Decrement ply counter
	DEC	(HL)
	LD	HL,(MLPTRI)	; Load ply list pointer
	DEC	HL		; Load pointer to move list top
	LD	D,(HL)
	DEC	HL
	LD	E,(HL)
	LD	(MLNXT),DE	; Update move avail pointer
	DEC	HL		; Get pointer to next move to undo
	LD	D,(HL)
	DEC	HL
	LD	E,(HL)
	LD	(MLPTRI),HL	; Save new ply counter
	LD	(MLPTRJ),DE	; Save next move pointer
	CALL	UNMOVE		; Restore board to previous ply
	RET
;**************************************************************************
; ONE MOVE BOOK OPENING
;**************************************************************************
;
; FUNCTION:  To provide a book opening of a single move
;
; CALLED BY: FNDMOV
;
; CALLS:     None
;
; ARGUMENTS: None
;***************************************************************************
BOOK:	POP	AF		; Abort return to FNDMOV
	LD	HL,SCORE+1	; Zero out score
	LD	(HL),0		; Zero out score table
	LD	HL,BMOVES-2	; Init best move ptr to book
	LD	(BESTM),HL
	LD	HL,BESTM	; Initialize address of pointer
	LD	A,(KOLOR)	; Get computer's color
	AND	A		; Is it white?
	JR	NZ,BM5-$	; No - Jump
	LD	A,R		; Load refresh reg (random no)
	BIT	0,A		; Test random bit
	RET	Z		; Return if zero (P-K4)
	INC	(HL)		; P-Q4
	INC	(HL)
	INC	(HL)
	RET
 BM5:	INC	(HL)		; Increment to black moves
	INC	(HL)
	INC	(HL)
	INC	(HL)
	INC	(HL)
	INC	(HL)
	LD	IX,(MLPTRJ)	; Pointer to opponent's 1st move
	LD	A,(IX+MLFRP)	; Get "from" position
	CP	22		; Is it a Queen Knight move?
	JR	Z,BM9-$ 	; Yes - Jump
	CP	27		; Is it a King Knight move?
	JR	Z,BM9-$ 	; Yes - Jump
	CP	34		; Is it a Queen Pawn?
	JR	Z,BM9-$ 	; Yes - Jump
	RET	C		; If Queen side Pawn opening -
				; return (P-K4)
	CP	35		; Is it a King Pawn?
	RET	Z		; Yes - Return (P-K4)
 BM9:	INC	(HL)		; (P-Q4)
	INC	(HL)
	INC	(HL)
	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	EXECMV
;		BITASN	INCHK	LINOUT	LINSET
;
; ARGUMENTS:	None
;***********************************************************************
CPTRMV: LD	BC,2047
	LD	HL,MLIST
	XOR	A
	LD	(HL),A
	LD	DE,MLIST+1
	LDIR
	CALL	FNDMOV			; Select best move
	LD	HL,(BESTM)		; Move list pointer variable
	LD	(MLPTRJ),HL		; Pointer to move data
	LD	A,(SCORE+1)		; To check for mates
	CP	1			; Mate against computer
	JR	NZ,CP0C-$		; No - Jump
	LD	C,1			; Computer mate flag
	CALL	FCDMAT			; Full checkmate?
CP0C:	CALL	MOVE			; Produce move on board array
	LD	E,1
	LD	D,7			; Ring the bell
	CALL	WRCHR
	LD	BC,120			; Store the board condition
	LD	HL,BOARDA		; as a result ofthis move
	LD	DE,BMOVE1		; in array BMOVE1
	LDIR
	CALL	EXECMV			; Make move on graphics board
					; and return info about it
	LD	A,B			; Special move flags
	AND	A			; Special?
	JR	NZ,CP10-$		; Yes - Jump
	LD	D,E			; "To" position of the move
	CALL	BITASN			; Convert to ASCII
	LD	(MVEMSG+3),HL		; Put in move message
	LD	D,C			; "From" position of the move
	CALL	BITASN			; Convert to ASCII
	LD	(MVEMSG),HL		; Put in move message
	LD	HL,MVEMSG
	LD	E,1
	LD	B,5
	CALL	LINOUT			; Output text of the move
	JR	CP1C-$
CP10:	BIT	1,B			; King side castle?
	JR	Z,CP34-$		; No - Jump
	LD	E,1
	LD	B,5
	LD	HL,OO
	CALL	LINOUT			; Output "O-O"
	JR	CP1C-$
CP34:	BIT	2,B			; Queen side castle?
	JR	Z,CP28-$		; No - Jump
	LD	B,5
	LD	HL,OOO
	CALL	LINOUT			; Output "O-O-O"
	JR	CP1C-$
CP28:	LD	B,5
	LD	HL,PPEP
	CALL	LINOUT			; Output "PxPep" - En passant
CP1C:	LD	A,128
	LD	(XSET),A
	LD	A,(COLOR)		; Should computer call check?
	LD	B,A
	XOR	80H			; Toggle color
	LD	(COLOR),A
	CALL	INCHK			; Check for check
	AND	A			; Is enemy in check?
	LD	A,B			; Restore color
	LD	(COLOR),A
	JR	Z,CP24-$		; No - Return
	LD	A,(KOLOR)		; Bring in the computer's color
	AND	A			; Is it white?
	JR	NZ,CP50-$		; No - Jump
	LD	A,(MOVENO)
	CP	4			; Is the move number < 4?
	JR	C,CP50-$		; Yes - Jump
	LD	HL,LINECT
	DEC	(HL)			; Decrement the line counter
CP50:	CALL	LINSET			; Set the cursor
	LD	A,(SCORE+1)		; Check for player mated
	CP	0FFH			; Forced mate?
	CALL	NZ,TBCPMV		; No - Tab to computer column
	LD	E,1
	LD	B,5
	LD	HL,CKMSG
	CALL	LINOUT			; Output "CHECK"
	LD	HL,LINECT
	INC	(HL)
CP24:	LD	A,(SCORE+1)		; Check again for mates
	CP	0FFH			; Player mated?
	RET	NZ			; No - Return
	LD	C,0			; Set player mate flag
	CALL	FCDMAT			; Full checkmate?
	RET
;***********************************************************************
; FORCED MATE HANDLING
;***********************************************************************
; FUNCTION:	To examine situations where there exists
;		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 resignation signal.
;
; CALLED BY:	CPTRMV
;
; CALLS:	MATED	CHARTR	TBPLMV
;
; ARGUMENTS:	The only value passed in a register is the
;		flag which tells FCDMAT whether the computer
;		or the player is mated.
;***********************************************************************
FCDMAT: LD	A,(MOVENO)	; Current move number
	LD	B,A		; Save
	LD	A,(PMATE)	; Move number where mate occurs
	SUB	B		; Number of moves till mate
	AND	A		; Checkmate?
	JR	NZ,FM0C-$	; No - Jump
	BIT	0,C		; Check flag for who is mated
	JR	Z,FM04-$	; Jump if player
	CALL	LINSET		; New line
	LD	B,9
	LD	HL,CKMSG
FM20:	CALL	LINOUT		; Print "CHECKMATE"
	CALL	MATED		; RIP King
	LD	A,128
	LD	(XSET),A
	CALL	LINSET
	LD	B,7
	LD	HL,UWIN
FM22:	CALL	LINOUT		; Output "YOU WIN"
	JR	FM08-$		; Jump
FM04:	LD	A,128
	LD	(XSET),A
	CALL	LINSET
	LD	B,4
	LD	HL,MTMSG
	CALL	LINOUT		; Output "MATE"
	CALL	LINSET
	LD	B,5
	LD	HL,IWIN
	CALL	LINOUT		; Output "I WIN"
FM08:	POP	HL		; Remove return addresses
	POP	HL
	CALL	LINSET
	CALL	CHARTR		; Input any character to play again
FM09:	LD	B,2
	LD	HL,CLRSCR
FM28:	CALL	LINOUT		; Blank screen
	LD	B,23
	LD	HL,AGAIN
	CALL	LINOUT		; Output "CARE FOR ANOTHER GAME?"
	JP	DRIV01		; Jump (Rest of game initialization)
FM0C:	BIT	0,C		; Who has forced mate?
	RET	NZ		; Return if player
	PUSH	AF		; Save the A register
	LD	A,128
	LD	(XSET),A
	CALL	LINSET		; New line
	POP	AF		; Return the A register
	ADD	A,30H		; Number of moves in ASCII
	LD	(MTPL),A	; Place value in message
	LD	B,9
	LD	HL,MTMSG
	CALL	LINOUT		; Output "MATE IN x MOVES"
	CALL	LINSET		; New line
	CALL	TBPLMV		; Tab to player's column
	RET			; Return
;***********************************************************************
; TAB TO PLAYER'S COLUMN
;***********************************************************************
; FUNCTION:	To space over in the move listing to the
;		column in which the player's moves are being
;		recorded.  This routine also reprints the
;		move number.
;
; CALLED BY:	PLYRMV
;
; CALLS:	None
;
; ARGUMENTS:	None
;***********************************************************************
TBPLCL: LD	B,3
	LD	HL,MVENUM
	CALL	LINOUT		; Reproduce move number
	LD	A,(KOLOR)	; Computer's color
	AND	A		; Is computer white?
	RET	NZ		; No - Return
	LD	B,7
TBPL2:	CALL	SPACE		; Tab to next column
	DJNZ	TBPL2-$
	RET			; Return
;***********************************************************************
; TAB TO COMPUTER'S COLUMN
;***********************************************************************
; FUNCTION:	To space over in the move listing to the
;		column in which the computer's moves are being
;		recorded.  This routine also reprints the
;		move number.
;
; CALLED BY:	PLYRMV
;
; CALLS:	None
;
; ARGUMENTS:	None
;***********************************************************************
TBCPCL: LD	B,3
	LD	HL,MVENUM
	CALL	LINOUT		; Reproduce move number
	LD	A,(KOLOR)	; Computer's color
	AND	A		; Is computer white?
	RET	Z		; No - Return
	LD	B,7
TBCP2:	CALL	SPACE		; Tab to next column
	DJNZ	TBCP2-$
	RET			; Return
;***********************************************************************
; TAB TO PLAYER'S W/O MOVE NO.
;***********************************************************************
; FUNCTION:	Like TBPLCL, except that the move number
;		is not reprinted.
;
; CALLED BY:	FCDMAT
;***********************************************************************
TBPLMV: LD	B,3
TBPL3:	CALL	SPACE
	DJNZ	TBPL3-$
	LD	A,(KOLOR)
	AND	A
	RET	NZ
	LD	B,7
TBPL4:	CALL	SPACE
	DJNZ	TBPL4-$
	RET
;***********************************************************************
; TAB TO COMPUTER'S W/O MOVE NO.
;***********************************************************************
; FUNCTION:	Like TBCPCL, except that the move number
;		is not reprinted.
;
; CALLED BY:	FCDMAT
;***********************************************************************
TBCPMV: LD	B,3
TBCP3:	CALL	SPACE
	DJNZ	TBCP3-$
	LD	A,(KOLOR)
	AND	A
	RET	Z
	LD	B,7
TBCP4:	CALL	SPACE
	DJNZ	TBCP4-$
	RET
;***********************************************************************
; 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 inpur in register D and the
;		ASCII square name is output in register
;		pair HL.
;***********************************************************************
BITASN: SUB	A		; Get ready for division
	LD	E,10
	CALL	DIVIDE		; Divide
	DEC	D		; Get rank on 1-8 basis
	ADD	A,60H		; Convert file to ASCII (a-h)
	LD	L,A		; Save
	LD	A,D		; Rank
	ADD	A,30H		; Convert rank to ASCII (1-8)
	LD	H,A		; Save
	RET			; Return
;***********************************************************************
; PLAYER'S MOVE ANALYSIS
;***********************************************************************
; FUNCTION:	To accept and validate the player's move
;		and produce it on the graphics board.  It
;		allows player to resign the game by
;		entering a Control-R.  It allows the player
;		to replay his last move by entering a Control-S.
;		It allows the player to save the current board
;		position in a floppy disc file by entering a
;		Control-V.
;
; CALLED BY:	DRIVER
;
; CALLS:	CHARTR	ASNTBI	VALMOV	EXECMV
;		PGIFND	TBPLCL
;
; ARGUMENTS:	None
;***********************************************************************
PLYRMV: CALL	CHARTR		; Accept "from" file letter
	CP	12H		; Is it instead a Control-R?
	JP	Z,FM09		; Yes - Jump
	CP	13H		; Is it instead a Control-S?
	JP	Z,PL30		; Yes - Jump
	CP	16H		; Is it instead a Control-V?
	JP	NZ,PL70 	; No - Jump
;*********************************************
;  OUTPUT THE BOARD POSITION TO THE DISKETTE
;*********************************************
	LD	D,5
	CALL	RESET1		; Call GETVEC
	LD	HL,TEXT5	; Request the name of the data file
	CALL	PTXT
	CALL	LINSET		; Carriage Return
	LD	B,16
	LD	HL,VEHOLD
BS35:	CALL	RDCHR		; Input the data set specification
	CALL	CHART1
	LD	(HL),A
	INC	HL
	CP	0DH		; Is the input a Carriage Return?
	JR	Z,BS40-$	; Yes - Jump
	DJNZ	BS35-$
	JP	BS75		; Jump to the error address
BS40:	LD	HL,VEHOLD
	LD	A,7		; CALL CSISYN
	CALL	JTASK
	CP	2		; Error bit set?
	JP	Z,BS75		; Yes - Jump to the error address
	LD	HL,VEHOLD
	LD	A,6
	CALL	JTASK		; CALL CSISYN
	CP	0		; Dataset found and parsed?
	JP	NZ,BS75 	; No - Jump to error address
;*********************************************
; STUFF THE OUTPUT VECTOR AND PREPARE TO OPEN
; THE OUTPUT FILE FOR A WRITE
;*********************************************
	LD	(IY+0),5	; Set LUN = 5
	LD	(IY+1),'D'	; Set device to DK:
	LD	(IY+2),'K'
	LD	(IY+15),1	; Request to open the file for a WRITE
	LD	(IY+16),21H	; Format = Logical Buffer; 1 Rec buff
	LD	(IY+19),0	; Clear Error Return Address
	LD	(IY+20),0
	LD	(IY+22),0	; Clear status flags
	LD	(IY+27),121	; Set USIZE to 121
	LD	(IY+28),0
	CALL	JIOCS
	LD	(IY+15),7	; Erase the file
	CALL	JIOCS
	LD	(IY+15),1	; Request to open the file for a WRITE
	CALL	JIOCS
	LD	A,(IY+23)	; Errors?
	AND	A
	JR	NZ,BS75-$	; Yes - Jump to error address
;*********************************************************
; THIS SECTION OUTPUTS THE CONTENTS OF THE BOARD POSITION
; ARRAY TO THE DISKETTE
;*********************************************************
BS99:	LD	HL,BOARDA
	LD	(IY+25),L	; Store address of the buffer
	LD	(IY+26),H	; BOARDA in UBFFR for writing
	LD	(IY+15),4
	CALL	JIOCS		; Write data to the unit
	LD	(IY+15),2
	CALL	JIOCS		; Close the output file
BS75:	LD	A,128
	LD	(XSET),A
	CALL	LINSET		; Carriage Return
	CALL	TBPLCL		; Tab to player's column
	LD	HL,LINECT
	INC	(HL)
	JP	PLYRMV		; Jump to PLYRMV
;*********************************************
; RESTORE THE PLAYER'S MOVE
;*********************************************
PL30:	LD	BC,120		; Restore board to the condition
	LD	DE,BOARDA	; it was in three moves ago
	LD	HL,BMOVE2
	LDIR
	CALL	DSPBRD		; Display board
	CALL	TITLES		; Display titles
	LD	A,(MOVENO)	; What is the present hexadecimal
	CP	1		; move number?	Is it 1?
	JP	Z,BA25		; Yes - Jump
	LD	HL,MVENUM+2	; Address of the 3rd move character
	LD	A,20H
	CP	(HL)		; Is the character a space?
	LD	A,47		; Set up test value
	JR	Z,BA10-$
	DEC	HL		; Decrement value
	CP	(HL)		; Under ASCII 0?
	JR	NZ,BA14-$
	LD	(HL),32 	; Set 3rd character to a blank
	DEC	HL
	LD	(HL),57 	; Set 2nd character to 9
	DEC	HL
	LD	(HL),57 	; Set 1st character to 9
	JR	BA14-$
BA10:	DEC	HL		; 2nd character of ASCII move
	DEC	(HL)		; Decrement value
	CP	(HL)		; Under ASCII 9?
	JR	NZ,BA14-$
	LD	(HL),57 	; Set character to 9
	DEC	HL		; 1st character of ASCII move
	DEC	(HL)		; Decrement value
BA14:	LD	HL,MOVENO	; Decrement the hexadecimal move
	DEC	HL		; number
BA25:	CALL	TBPLCL
	LD	HL,LINECT	; Increment the line counter
	INC	(HL)
	CALL	CHARTR		; Accept "from" file letter
	CP	12H		; Is it a Control-R?
	JP	Z,FM09
	JR	PL35-$
PL70:	PUSH	AF		; Save the A register
	LD	BC,120		; Transfer the contents of the
	LD	HL,BMOVE1	; board array from the past move
	LD	DE,BMOVE2	; to the board array of the
	LDIR			; 2nd previous move
	POP	AF		; Restore the A register
PL35:	LD	H,A		; Save
	CALL	CHARTR		; Accept "from" rank number
	LD	L,A		; Save
	CALL	ASNTBI		; Convert to a board index
	SUB	B		; Gives board index, if valid
	JR	Z,PL08-$	; Jump if invalid
	LD	(MVEMSG),A	; Move list "from" position
	CALL	CHARTR		; Accept separator & ignore it
	CALL	CHARTR		; Repeat for "to" position
	LD	H,A
	CALL	CHARTR
	LD	L,A
	CALL	ASNTBI
	SUB	B
	JR	Z,PL08-$
	LD	(MVEMSG+1),A	; Move list "to" position
	CALL	VALMOV		; Determines if a legal move
	AND	A		; Legal?
	JR	NZ,PL08-$	; No - Jump
	CALL	EXECMV		; Make move on graphics board
	RET
PL08:	LD	E,1		; Adress to LUN #1
	LD	A,128
	LD	(XSET),A
	LD	A,(KOLOR)	; Get the computer's color
	AND	A		; Is it white?
	JR	Z,PL25-$	; Yes - Jump
	CALL	LINSET		; New line
	JR	PL20-$
PL25:	CALL	LIN1
PL20:	LD	HL,INVAL1	; Output "INVALID MOVE -- TRY AGAIN"
	LD	B,25
	CALL	LINOUT
	CALL	LINSET
	CALL	TBPLCL		; Tab to player's column
	LD	A,(KOLOR)	; Get the computer's color
	AND	A		; Is it white?
	JR	NZ,PL10-$	; No - Jump
	LD	HL,LINECT
	INC	(HL)
PL10:	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 for input validity/
;
; CALLED BY:	PLYRMV
;
; CALLS:	MLTPLY
;
; ARGUMENTS:	Accepts the square name in register pair HL
;		and outputs the board indes in register A.
;		Register B = 0 if ok.  Register B = Register
;		A if invalid.
;***********************************************************************
ASNTBI: LD	A,L		; ASCII rank
	SUB	30H		; Rank 1 - 8
	CP	1		; Check lower bound
	JP	M,AT04		; Jump if invalid
	CP	9
	JR	NC,AT04-$	; Jump if invalid
	INC	A		; Rank 2 - 9
	LD	D,A		; Ready for multiplication
	LD	E,10
	CALL	MLTPLY		; Multiply
	LD	A,H		; ASCII file letter (a - h)
	SUB	40H		; File 1 - 8
	CP	1		; Check lower bound
	JP	M,AT04		; Jump if invalid
	CP	9		; Check upper bound
	JR	NC,AT04-$	; Jump if invalid
	ADD	A,D		; File+Rank (20-90) = Board Index
	LD	B,0		; Ok flag
	RET			; Return
AT04:	LD	B,A		; Invalid flag
	RET
;***********************************************************************
; VALIDATE MOVE SUBROUTINE
;***********************************************************************
; FUNCTION:	To check a player's move for validity.
;
; CALLED BY:	PLYRMV
;
; CALLS:	GENMOV	MOVE	INCHK	UNMOVE
;
; ARGUMENTS:	Returns flag in register A, 0 for valid
;		and 1 for invalid move.
;***********************************************************************
VALMOV: LD	BC,1023
	LD	HL,MLIST+1024
	XOR	A
	LD	(HL),A
	LD	DE,MLIST+1025
	LDIR
	LD	HL,(MLPTRJ)	; Save last move pointer
	PUSH	HL		; Save register
	LD	A,(KOLOR)	; Computer's color
	XOR	80H		; Toggle color
	LD	(COLOR),A	; Store
	LD	HL,PLYIX-2	; Load move list index
	LD	(MLPTRI),HL
	LD	HL,MLIST+1024	; Next available list pointer
	LD	(MLNXT),HL
	CALL	GENMOV		; Generate opponent's moves
	LD	IX,MLIST+1024	; Index to start of moves
VA5:	LD	A,(MVEMSG)	; "From" position
	CP	(IX+MLFRP)	; Is it in list?
	JR	NZ,VA6-$	; No - Jump
	LD	A,(MVEMSG+1)	; "To" position
	CP	(IX+MLTOP)	; Is it the list?
	JR	Z,VA7-$ 	; Yes - Jump
VA6:	LD	E,(IX+MLPTR)	; Pointer to next move in the list
	LD	D,(IX+MLPTR+1)
	XOR	A		; At end of list?
	CP	D
	JR	Z,VA10-$	; Yes - Jump
	PUSH	DE
	POP	IX
	JR	VA5-$		; Jump
VA7:	LD	(MLPTRJ),IX	; Save opponent's move pointer
	CALL	MOVE		; Make move on board array
	CALL	INCHK		; Was it a legal move?
	AND	A
	JR	NZ,VA9-$	; No - Jump
VA8:	POP	HL		; Restore saved register
	RET			; Return
VA9:	CALL	UNMOVE		; Un-do move on board array
VA10:	LD	A,1		; Set flag for invalid move
	POP	HL		; Restore saved register
	LD	(MLPTRJ),HL	; Save move pointer
	RET			; Return
;***********************************************************************
; DISPLAY MATED KING
;***********************************************************************
; FUNCTION:	To let the computer's King RIP when
;		mated.
;
; CALLED BY:	FCDMAT
;
; CALLS:	CONVRT
;		BLNKER
;		INSPCE	 (Abnormal Call to IP04)
;
; ARGUMENTS:	None
;***********************************************************************
MATED:	LD	A,(KOLOR)	; Computer's color
	AND	A		; Is computer white?
	LD	HL,COLBIT	;
	JR	Z,MA20-$
	LD	(HL),42H	; Color is black (B)
	LD	A,(POSK+1)	; Position of black King
	JR	MA08-$
MA20:	LD	(HL),57H	; Color is white (W)
	LD	A,(POSK)	; Position of white King
MA08:	LD	(BRDPOS),A	; Store King position
	LD	(ANBDPS),A	; Again
	CALL	CONVRT		; Convert to norm address
	LD	A,6		; Piece value of the King
	LD	B,10		; Blink parameter
	CALL	BLNKER		; Blink King position
	LD	IY,MA0C 	; Prepare for abnormal call
	PUSH	IY
	PUSH	HL
	PUSH	BC
	PUSH	DE
	PUSH	IX
	PUSH	AF
	JP	IP04		; Call INSPCE
				; Prepare to RIP the King
MA0C:	LD	A,(YPOINT)	; Get Y norm pointer
	DEC	A
	LD	(YSET),A	; Set Y-vector for the cursor
	LD	A,(XPOINT)	; Get X norm pointer
	INC	A
	LD	(XSET),A	; Set X-vector for the cursor
	CALL	CURSOR		; Set the cursor
	LD	E,1
	LD	HL,VIDBIT	; Set up for proper video
	LD	D,(HL)
	CALL	WRCHR
	LD	B,3
	LD	HL,RIP
MA30:	CALL	LINOUT		; Output RIP
	LD	B,10		; Blink again
	LD	A,(ANBDPS)
	LD	(BRDPOS),A
	CALL	BLNKER
	RET			; Return
;***********************************************************************
; SET UP POSITION FOR ANALYSIS
;***********************************************************************
; FUNCTION:	To enable user to set up any position
;		for analysis, or to continue to play
;		the game.  The routine blinks the board
;		squares in turn and the user has the option
;		of leaving the contents unchanged by a
;		carriage return, emptying the square by a 0,
;		or inputting a piece of his choosing.  To
;		enter a piece, type in piece-code, color-code,
;		moved-code. This subroutine also queries the
;		the player if he wishes to analyse a position
;		which is stored in a floppy disc file.
;
;		Piece-code is a letter indicating
;		Piece-code is a letter indicating the
;		desired piece:
;			K  -  King
;			Q  -  Queen
;			R  -  Rook
;			B  -  Bishop
;			N  -  Knight
;			P  -  Pawn
;
;		Color-code is a letter, W for white, or
;		B for black.
;
;		Moved-code is a number.  0 indicates that the
;		piece has never moved.	1 indicates that the
;		piece has moved.
;
;		A backspace will back up inthe sequence of
;		blinked squares. An Escape will terminate
;		the link cycle and verify that the
;		position is correct, then proceed with game
;		initialization.
;
; CALLED BY:	DRIVER
;
; CALLS:	CHARTR	DSPBRD	BLNKER	ROYALT
;		PLYRMV	CPTRMV	JTASK
;
; ARGUMENTS:	None
;***********************************************************************
ANALYS: LD	A,0
	LD	(LINECT),A
	LD	A,128
	LD	(XSET),A
	CALL	LIN1
	LD	B,38
	LD	HL,ANAMSG
AN30:	CALL	LINOUT		; "CARE TO ANALYSE A POSITION?"
	CALL	CHARTR		; Accept answer
	PUSH	AF		; Save the A register
	LD	HL,LINECT	; Increment the line counter
	INC	(HL)
	CALL	LINSET		; New line
	POP	AF		; Retrieve the A register
	CP	4EH		; Is the answer a "N"?
	JR	NZ,AN04-$	; No - Jump
	LD	A,1
	CALL	JTASK		; Return to monitor
AN04:	LD	HL,TEXT6	; "DO YOU HAVE A BOARD POSITION"
				; "STORED IN A FILE? "
	CALL	PTXT
	CALL	CHARTR		; Accept answer
	CP	89		; Is it a "Y"?
	JP	NZ,AN90 	; No - Jump
	LD	D,4
	CALL	RESET1		; CALL GETVEC
	CALL	LINSET
	LD	HL,TEXT7	; "WHAT IS THE NAME OF YOUR BOARD"
				; "POSITION DATA FILE? "
	CALL	PTXT
	LD	B,16
	LD	HL,VEHOLD
AN80:	CALL	RDCHR		; Input the name of the board
	CALL	CHART1		; position file
	LD	(HL),A
	INC	HL
	CP	0DH		; Is the input a Carriage Return?
	JR	Z,AN82-$	; Yes - Jump
	DJNZ	AN80-$
	JR	AN90-$		; Jump to the error address
AN82:	LD	HL,VEHOLD
	LD	A,7
	CALL	JTASK		; CALL CSISYN
	CP	2		; Error bit set?
	JR	Z,AN90-$	; Yes - Jump to the error address
	LD	A,6
	CALL	JTASK		; CALL CSISYN
	CP	0		; Dataset found and parsed?
	JP	NZ,AN90 	; No - Jump to error address
;*********************************************
; STUFF THE INPUT VECTOR AND PREPARE TO OPEN
; THE INPUT FILE FOR A READ
;*********************************************
	LD	(IY+0),4	; Set LUN = 4
	LD	(IY+1),'D'	; Set device to DK:
	LD	(IY+2),'K'
	LD	(IY+15),0	; Request to open for a WRITE
	LD	(IY+16),21H	; Format = Logical Buffer; 1 Rec buff
	LD	(IY+19),0	; Clear Error Return Address
	LD	(IY+20),0
	LD	(IY+22),0	; Clear status flags
	LD	(IY+27),120	; Set USIZE to 120
	LD	(IY+28),0
	CALL	JIOCS		; Open output file
	LD	A,(IY+23)	; Errors?
	AND	A
	JR	NZ,AN90-$	; Yes - Jump to error address
;*********************************************************
; THIS SECTION INPUTS THE CONTENTS OF THE BOARD POSITION
; ARRAY FROM THE DISKETTE
;*********************************************************
	LD	HL,BOARDA
	LD	(IY+25),L	; Store address of the buffer
	LD	(IY+26),H	; BOARDA in UBFFR for reading
	LD	(IY+15),3
	CALL	JIOCS		; Read data from the unit
	LD	(IY+15),2
	CALL	JIOCS		; Close the input file
AN90:	CALL	DSPBRD		; Current board position
	LD	A,21		; First board index
AN08:	LD	(ANBDPS),A	; Save
	LD	(BRDPOS),A
	CALL	CONVRT		; Determine norm address
				; Store in RANK(Y) and FILE(X)
	LD	(M1),A		; Set up board index
	LD	IX,(M1)
	LD	A,(IX+BOARD)	; Get board contents
	CP	0FFH		; Boarder square?
	JR	Z,AN19-$	; Yes - Jump
AN35:	LD	B,4		; Ready to blink square
	CALL	BLNKER		; Blink
	LD	E,1		; Set cursor to home position
	LD	D,30
	CALL	WRCHR
	CALL	CHARTR		; Accept input
	CP	1BH		; Is it an escape?
	JR	Z,AN1B-$	; Yes - Jump
	CP	08H		; Is it a backspace?
	JR	Z,AN1A-$	; Yes - Jump
	CP	0DH		; Is it a carriage return?
	JR	Z,AN19-$	; Yes - Jump
	LD	BC,7		; Number of types of pieces + 1
	LD	HL,PCS		; Address of piece symbol table
	CPIR			; Search
	JR	NZ,AN18-$	; Jump if not found
	CALL	CHARTR		; Accept and ignore separator
	CALL	CHARTR		; Color of piece
	CP	42H		; Is it black?
	JR	NZ,AN50-$	; No - skip
	SET	7,C		; Black piece indicator
AN50:	CALL	CHARTR		; Accept and ignore separator
	CALL	CHARTR		; Moved flag
	CP	31H		; Has piece moved?
	JR	NZ,AN18-$	; No - Jump
	SET	3,C		; Set moved indicator
AN18:	LD	IX,(M1)
	LD	(IX+BOARD),C	; Insert piece into board array
	LD	E,1
	LD	D,25
	CALL	WRCHR
	CALL	DSPBRD		; Update graphics board
AN19:	LD	A,(ANBDPS)	; Current board position
	INC	A		; Next
	CP	99		; Done?
	JR	NZ,AN08-$	; No - Jump
	JP	AN04		; Jump
AN1A:	LD	A,(ANBDPS)	; Prepare to go back a square
	DEC	A		; Decrement
	CP	20		; Off the other end?
	JP	NC,AN25 	; No - Jump
	LD	A,98		; Wrap around to top of screen
AN0B:	JP	AN08		; Jump
AN25:	LD	(ANBDPS),A
	LD	(BRDPOS),A
	CALL	CONVRT
	LD	(M1),A
	LD	IX,(M1)
	LD	A,(IX+BOARD)
	CP	0FFH
	JR	Z,AN1A-$
	JP	AN35
AN1B:	LD	A,128
	LD	(XSET),A
	LD	E,1
	LD	D,30
	CALL	WRCHR
	LD	B,15
	LD	HL,CRTNES
	CALL	LINOUT		; Ask if correct?
	CALL	CHARTR		; Accept answer
	CP	4EH		; Is it "N"?
	JP	Z,AN04		; No - Jump
	CALL	ROYALT		; Update positions of royalty
	LD	B,2
	LD	HL,CLRSCR
	CALL	LINOUT		; Blank screen
	LD	A,-1
	LD	(LINECT),A
	CALL	INTERR		; Accept color choice
AN1C:	CALL	LINSET
	LD	B,18
	LD	HL,WSMOVE
	CALL	LINOUT		; Ask whose move it is
	CALL	CHARTR		; Accept response
	PUSH	AF		; Save the A register
	CALL	DSPBRD		; Display graphics board
	LD	D,30		; Set the cursor
	CALL	WRCHR
	LD	B,15
	LD	HL,TITLE4	; Put up titles
	CALL	LINOUT
	LD	A,-1
	LD	(LINECT),A
	CALL	LIN1
	LD	B,15
	LD	HL,TITLE3
	CALL	LINOUT
	CALL	LINSET		; Set the cursor
	POP	AF		; Restore the A register
	CP	57H		; Is it white's move?
	JP	Z,DRIV04	; Yes - Jump
	LD	B,3
	LD	HL,MVENUM
	CALL	LINOUT		; Print move number
	LD	B,7
AN46:	CALL	SPACE		; Tab to black's move
	DJNZ	AN46-$
	LD	A,(KOLOR)	; Computer's color
	AND	A		; Is computer white?
	JR	NZ,AN20-$	; No - Jump
	CALL	PLYRMV		; Get player's move
	LD	A,128
	LD	(XSET),A
	CALL	LINSET		; New line
	JP	DR0C		; Jump
AN20:	CALL	CPTRMV		; Get computer's move
	LD	A,128
	LD	(XSET),A
	CALL	LINSET		; New line
	JP	DR0C		; Jump
;***********************************************************************
; UPDATE POSITIONS OF ROYALTY
;***********************************************************************
; FUNCTION:	To update the positions of the Kings and Queens
;		after a change of board position in ANALYS.
;
; CALLED BY:	ANALYS
;
; CALLS:	None
;
; ARGUMENTS:	None
;***********************************************************************
ROYALT: LD	HL,POSK 	; Start of Royalty array
	LD	B,4		; Clear all four positions
RY60:	LD	(HL),0
	INC	HL
	DJNZ	RY60-$
	LD	A,21		; First board position
RY04:	LD	(M1),A		; Set up board position
	LD	HL,POSK 	; Address of King position
	LD	IX,(M1)
	LD	A,(IX+BOARD)	; Fetch board contents
	BIT	7,A		; Test color bit
	JR	Z,RY50-$	; Jump if white
	INC	HL		; Offset for black
RY50:	AND	7		; Delete flags, leave piece
	CP	KING		; King?
	JR	Z,RY08-$	; Yes - Jump
	CP	QUEEN		; Queen
	JR	NZ,RY0C-$	; No - Jump
	INC	HL		; Queen position
	INC	HL		; Plus offset
RY08:	LD	A,(M1)		; Index
	LD	(HL),A		; Save
RY0C:	LD	A,(M1)		; Current position
	INC	A		; Next position
	CP	99		; Done?
	JR	NZ,RY04-$	; No - Jump
	RET			; Return
;***********************************************************************
; SQUARE BLINKER
;***********************************************************************
; FUNCTION:	To blink the graphics board square to signal
;		a piece's intention to move, or to highlight
;		the square as being alterable in ANALYS.
;
; CALLED BY:	MAKEMV	ANALYS	MATED
;
; CALLS:	None
;
; ARGUMENTS:	Number of times to blink passed in register B.
;***********************************************************************
BLNKER: PUSH	AF
	PUSH	DE
	PUSH	HL
	PUSH	IX
	PUSH	BC
	CALL	RANFIL
	LD	A,(XPOINT)	; Convert norm address to pointer
	LD	(XSET),A	; address
	LD	A,(YPOINT)
	LD	(YSET),A
	CALL	CURSOR		; Set the cursor
	LD	B,5
	LD	HL,SQHOLD
BL60:	LD	E,0
	LD	D,27		; Read values of the upper half of
	CALL	WRCHR		; the square and store them in
	PUSH	IX		; SQHOLD
	POP	IX
	PUSH	IX
	POP	IX
	LD	D,41
	CALL	WRCHR
	PUSH	IX
	POP	IX
	PUSH	IX
	POP	IX
	CALL	RDCHR
	LD	(HL),A
	INC	HL
	DJNZ	BL60-$
	LD	A,(YPOINT)
	DEC	A
	LD	(YSET),A
	CALL	CURSOR
	LD	HL,SQHOLD+5
	LD	B,5
BL65:	LD	E,0
	LD	D,27		; Read the values of the lower half
	CALL	WRCHR		; of the square and store them in
	PUSH	IX		; SQHOLD
	POP	IX
	PUSH	IX
	POP	IX
	LD	D,41
	CALL	WRCHR
	PUSH	IX
	POP	IX
	PUSH	IX
	POP	IX
	CALL	RDCHR
	LD	(HL),A
	INC	HL
	DJNZ	BL65-$
BL25:	LD	A,(VIDBI)
	LD	D,A
	CALL	WRCHR
	LD	A,(YPOINT)
	LD	(YSET),A
	LD	A,(XPOINT)
	LD	(XSET),A
	CALL	CURSOR
	LD	B,5
	LD	HL,SQHOLD
BL30:	LD	D,(HL)
	CALL	WRCHR
	INC	HL
	DJNZ	BL30-$
	LD	A,(YPOINT)
	DEC	A
	LD	(YSET),A
	CALL	CURSOR
	LD	B,5
	LD	HL,SQHOLD+5
BL35:	LD	D,(HL)
	CALL	WRCHR
	INC	HL
	DJNZ	BL35-$
	LD	D,30
	CALL	WRCHR
	LD	BC,3030H
BL40:	DEC	BC
	LD	A,B
	CP	0
	JR	NZ,BL40-$
	LD	A,C
	CP	0
	JR	NZ,BL40-$
	LD	A,(VIDBIT)
	LD	D,A
	CALL	WRCHR
	LD	A,(YPOINT)
	LD	(YSET),A
	LD	A,(XPOINT)
	LD	(XSET),A
	CALL	CURSOR
	LD	B,5
	LD	HL,SQHOLD
BL80:	LD	D,(HL)
	CALL	WRCHR
	INC	HL
	DJNZ	BL80-$
	LD	A,(YPOINT)
	DEC	A
	LD	(YSET),A
	CALL	CURSOR
	LD	B,5
	LD	HL,SQHOLD+5
BL85:	LD	D,(HL)
	CALL	WRCHR
	INC	HL
	DJNZ	BL85-$
	LD	D,30
	CALL	WRCHR
	LD	BC,3030H
BL90:	DEC	BC
	LD	A,B
	CP	0
	JR	NZ,BL90-$
	LD	A,C
	CP	0
	JR	NZ,BL90-$
	POP	BC		; Restore the B register
	DEC	B
	PUSH	BC		; Store the B register
	JP	NZ,BL25
	LD	D,25
	CALL	WRCHR
	POP	BC
	POP	IX
	POP	HL
	POP	DE
	POP	AF
	RET
;***********************************************************************
; EXECUTE MOVE SUBROUTINE
;***********************************************************************
; FUNCTION:	This routine is the control routine for
;		MAKEMV.  It checks for double moves and
;		sees that they are properly handled.  It
;		sets flags in the B register for double moves.
;			En Passant  -- Bit 0
;			O-O	    -- Bit 1
;			O-O-O	    -- Bit 2
;
; CALLED BY:	PLYRMV	CPTRMV
;
; CALLS:	MAKEMV
;
; ARGUMENTS:   Flags set in the B register as described above.
;***********************************************************************
EXECMV: PUSH	IX		; Save registers
	PUSH	AF
	LD	E,1		; Save present cursor poition
	LD	D,27
	CALL	WRCHR		; Output an "ESCAPE" and a "?"
	LD	D,63
	CALL	WRCHR
	LD	E,0
	CALL	RDCHR
	CALL	RDCHR
	LD	(YSETS),A	; Store the Y-position in YSETS
	CALL	RDCHR
	LD	(XSETS),A	; Store the X-position in XSETS
	LD	IX,(MLPTRJ)	; Index into move list
	LD	C,(IX+MLFRP)	; Move list "from" position
	LD	E,(IX+MLTOP)	; Move list "to" position
	CALL	MAKEMV		; Produce move
	LD	D,(IX+MLFLG)	; Move list flags
	LD	B,0
	BIT	6,D		; Double move?
	JR	Z,EX14-$	; No - Jump
	LD	DE,6		; Move list entry width
	ADD	IX,DE		; Increment MLPTRJ
	LD	C,(IX+MLFRP)	 ; Second "from" position
	LD	E,(IX+MLTOP)	; Second "to" position
	LD	A,E		; Get "to" position
	CP	C		; Same as "from" position?
	JR	NZ,EX04-$	; No - Jump
	INC	B		; Set en passant flag
	JR	EX10-$		; Jump
EX04:	CP	1AH		; White O-O?
	JR	NZ,EX08-$	; No - Jump
	SET	1,B		; Set O-O flag
	JR	EX10-$		; Jump
EX08:	CP	60H		; Black O-O
	JR	NZ,EX0C-$	; No - Jump
	SET	1,B		; Set O-O flag
	JR	EX10-$		; Jump
EX0C:	SET	2,B		; Set move on board
EX10:	CALL	MAKEMV
EX14:	PUSH	DE
	LD	E,1		; Set normal video
	LD	D,25
	CALL	WRCHR
	LD	A,(YSETS)	; Set cursor to its proper position
	SUB	30H		; in the move list
	LD	(YSET),A
	LD	A,(XSETS)
	SUB	30H
	LD	(XSET),A
	CALL	CURSOR
	POP	DE
	POP	AF		; Restore registers
	POP	IX
	RET			; Return
;***********************************************************************
; MAKE MOVE SUBROUTINE
;***********************************************************************
; FUNCTION:	Moves the piece on the board when a move
;		is made. It blinks both the "from" and
;		"to" positions to give notice of the move.
;
; CALLED BY:	EXECMV
;
; CALLS:	CONVRT	BLNKER	INSPCE	CURSOR
;
; ARGUMENTS:	The "from" position is passed in register
;		C, and the "to" position in Register E.
;***********************************************************************
MAKEMV: PUSH	AF		; Save register
	PUSH	BC
	PUSH	HL
	PUSH	DE
	LD	A,C		; "From" position
	LD	(BRDPOS),A	; Set up parameter
	CALL	CONVRT		; Determine norm address
	LD	B,10		; Blink parameter
	CALL	BLNKER		; Blink "from" square
MK56:	LD	HL,YPOINT	; Convert norn address to pointer
	LD	A,(HL)		; address
	LD	(YSET),A
	LD	HL,XPOINT
	LD	A,(HL)
	ADD	A,2
	LD	(XSET),A
	CALL	CURSOR		; Set the cursor
	LD	E,1
	LD	HL,VIDBIT
	LD	D,(HL)
	CALL	WRCHR		; Output video signal (inverse or
	LD	D,32		; normal video)
	CALL	WRCHR		; Output 2 blanks
	LD	D,32
	CALL	WRCHR
	POP	DE		; Restore the E regoster
	PUSH	DE
	LD	A,E		; Get "to" position
	LD	(BRDPOS),A	; Set up parameter
	CALL	CONVRT		; Determine norm address
	LD	B,10		; Blink parameter
	CALL	INSPCE		; Inserts the piece
	CALL	BLNKER		; Blinks "to" square
	POP	DE
	POP	HL
	POP	BC
	POP	AF
	RET
	END
r