The code to check for it was there but a flag that needed to be set before the sub call was missed.

Also, as a way to quickly check for errors, this code can be placed in the MAIN sub just above the BORDER code. Also, place a GOTO 1 after line 20. This will allow for a board to be set up to check for castling.

1 LOCATE 4, 4: COLOR 0, 6: PRINT " R "
LOCATE 4, 24: COLOR 0, 6: PRINT " K "
LOCATE 4, 39: COLOR 0, 6: PRINT " R "
LOCATE 18, 9: COLOR 7, 1: PRINT " K "
LOCATE 10, 39: COLOR 7, 1: PRINT " Q "

Thanks Eric,

Pete

The Corrected code:

REM QB CHESS GAME IN PROGRESS BY PETE.
REM PHASE I COMPLETE. NEEDS BETA TESTING.
REM NEEDED TO COMPLETE PHASE II
REM KING IN CHECK?
REM CHECKMATE?
REM CANNOT CASTLE INTO CHECK.
DECLARE SUB MAIN ()
DECLARE SUB SNAPTOCENTER (X%, Y%)
DECLARE SUB LEGALCHECK (OLDX%, X%, OLDY%, Y%, PIECE$, COLORIT%, LEGAL%, WCASTLE$, BCASTLE$, PLAYER%, CHECK%)
DECLARE SUB BOARDMAP (B$, X%, Y%)
DECLARE SUB KEYBOARD (B$, X%, Y%)
DECLARE SUB MDRIVER (EX%, B$, X%, Y%)
DECLARE SUB MESSAGE (MSG$, CHECKMATE%)
DECLARE SUB KNIGHTCHECK (CKINGX%, CKINGY%, BYPASSKINGCHECK%, CHECKPARA%, OLDX%, OLDY%, X%, Y%, CHECKMATE%)
DECLARE SUB XMATE (PLAYER%, CKINGX%, CKINGY%, OLDX%, OLDY%, AX%, AY%, BYPASSKINGCHECK%, CHECKMATE%)
DECLARE SUB KINGINCHECK (CHECK%, CKINGX%, CKINGY%, PLAYER%)
DECLARE SUB STRAIGHT (BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, LEGAL%, CHECK%, CHECKMATE%, IMATE%)
DECLARE SUB CHECKWATCH (BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, WKINGX%, WKINGY%, BKINGX%, BKINGY%, LEGAL%, CHECK%, CHECKMATE%)
DECLARE SUB DIAGONAL (BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, LEGAL%, CHECK%, CHECKMATE%)

TYPE RegType
AX AS INTEGER
BX AS INTEGER
CX AS INTEGER
DX AS INTEGER
BP AS INTEGER
SI AS INTEGER
DI AS INTEGER
FLAGS AS INTEGER
DS AS INTEGER
ES AS INTEGER
END TYPE

DIM SHARED MOUSE$
DIM SHARED Registers AS RegType
DIM SHARED LB%, RB%, MB%, DX%, CY%
DIM SHARED LM%, TM%, ENPASSANT$, XCHECK%, YCHECK%
CALL MAIN

SYSTEM

SUB BOARDMAP (B$, X%, Y%)
XX = CSRLIN: YY = POS(1)
LOCATE 25, 56: PRINT "Mouse Position: "; : PRINT SPACE$(80 - POS(1));
REM MAP FORMULA

IF (X% - TM%) >= 0 AND (X% - TM%) < 16 AND Y% >= LM% AND Y% - LM% < 40 THEN
NUMBERY$ = LTRIM$(STR$(8 - INT((X% - TM% + 1) / 2.1)))
ALPHAX$ = LCASE$(CHR$(65 + INT((Y% - LM% + 1) / 5.1)))
LOCATE 25, 72: PRINT ALPHAX$; " "; NUMBERY$;
ELSE
B$ = "OUTOFBOUNDS"
END IF

LOCATE XX, YY
END SUB

SUB CHECKWATCH (BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, WKINGX%, WKINGY%, BKINGX%, BKINGY%, LEGAL%, CHECK%, CHECKMATE%)
IF PLAYER% = BYPASSKINGCHECK% THEN EXIT SUB
IF CHECKPARA% <> -1 THEN
REM LOCATE KING
LOCATE TM% + 1, LM% + 2
FOR J% = 1 TO 8
FOR I% = 1 TO 8
IF I% <> 1 THEN LOCATE , POS(1) + 5
IF CHR$(SCREEN(CSRLIN, POS(1))) = "K" THEN
A% = SCREEN(CSRLIN, POS(1), 1)
IF A% = 23 OR A% = 151 THEN
WKINGX% = CSRLIN: WKINGY% = POS(1)
ELSE
BKINGX% = CSRLIN: BKINGY% = POS(1)
END IF
END IF
NEXT I%
PRINT : PRINT : LOCATE , LM% + 2
NEXT J%
IF BYPASSKINGCHECK% = 10 THEN CKINGX% = WKINGX%: CKINGY% = WKINGY% ELSE CKINGX% = BKINGX%: CKINGY% = BKINGY%
END IF

IF CHECKPARA% > 1 THEN
IF BYPASSKINGCHECK% \ 10 = PLAYER% THEN
REM CANNOT MOVE INTO CHECK
LEGAL% = -1
IF CHECKMATE% = 0 AND CHECK% <> -99 THEN MSG$ = "Illegal"
ELSE
REM OPP. HAS BEEN PLACED IN CHECK.
IF CHECK% = -2 THEN
CHECK% = -1
ELSE
CHECK% = -1
MSG$ = "Check!"
END IF
END IF
END IF

IF MSG$ <> "" THEN
CALL MESSAGE(MSG$, CHECKMATE%)
END IF

OLDX% = HOLDX%: OLDY% = HOLDY%
X% = HX%: Y% = HY%

END SUB

SUB DIAGONAL (BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, LEGAL%, CHECK%, CHECKMATE%)
IF LEGAL% = 0 THEN
REM CHECK BLOCKS

IF CHECKPARA% = 0 THEN
REM MOVE A PIECE
IF ABS(OLDX% \ 2 - X% \ 2) <> ABS(OLDY% \ 5 - Y% \ 5) THEN LEGAL% = -1: EXIT SUB
IF OLDX% > X% THEN AX% = -2 ELSE AX% = 2
IF OLDY% > Y% THEN AY% = -5 ELSE AY% = 5
A3% = ABS(OLDX% / 2 - X% / 2)
ELSE
REM CHECK THE KING
A3% = 8
END IF

FOR I% = 1 TO A3%
IF I% <> 1 THEN
LOCATE OLDX% + A1%, OLDY% + A2%
A$ = CHR$(SCREEN(OLDX% + A1%, OLDY% + A2%))
IF CKINGX% + A1% = X% AND CKINGY% + A2% = Y% THEN EXIT FOR: REM ALLOWS A PIECE TO CAPTURE OR BLOCK KING IN CHECK
IF CHECKPARA% = 0 THEN
IF A$ <> " " THEN LEGAL% = -1: EXIT FOR
ELSE
IF RTRIM$(A$) <> "" THEN
A4% = SCREEN(OLDX% + A1%, OLDY% + A2%, 1)
IF CHECKMATE% = 0 THEN INSTRX1$ = "KQBP": INSTRX2$ = "KP" ELSE IF IMATE% = 1 THEN INSTRX1$ = "QB": INSTRX2$ = "P" ELSE INSTRX1$ = "QBP": INSTRX2$ = "P"
IF INSTR(INSTRX1$, A$) <> 0 THEN
IF INSTR(INSTRX2$, A$) <> 0 AND I% = 2 OR INSTR("QB", A$) <> 0 THEN
IF BYPASSKINGCHECK% = 10 AND A4% = 96 OR BYPASSKINGCHECK% = -10 AND A4% = 23 THEN
IF INSTR(INSTRX2$, A$) <> 0 AND I% = 2 THEN
REM PAWNS CANNOT CHECK BACKWARDS
IF BYPASSKINGCHECK% = -10 THEN IF OLDX% + A1% <> CKINGX% + 2 THEN EXIT FOR
IF BYPASSKINGCHECK% = 10 THEN IF OLDX% + A1% <> CKINGX% - 2 THEN EXIT FOR
END IF
CHECKPARA% = CHECKPARA% + 1
IF XCHECK% = 0 THEN XCHECK% = OLDX% + A1%: YCHECK% = OLDY% + A2%
EXIT FOR
END IF
END IF
END IF
IF A4% = 23 OR A4% = 96 THEN EXIT FOR: REM FLASHING PIECES WON'T GET IN THE WAY.
END IF
END IF
END IF
A1% = A1% + AX%: A2% = A2% + AY%
IF OLDX% + A1% < TM% OR OLDX% + A1% > TM% + 8 * 2 THEN EXIT FOR
IF OLDY% + A2% < LM% OR OLDY% + A2% > LM% + 8 * 5 THEN EXIT FOR
NEXT I%
END IF

END SUB

SUB KEYBOARD (B$, X%, Y%)
EX% = 1: CALL MDRIVER(EX%, B$, X%, Y%)
DO
B$ = INKEY$
EX% = 2: CALL MDRIVER(EX%, B$, X%, Y%)
IF B$ = "OUTOFBOUNDS" THEN B$ = ""
LOOP UNTIL B$ <> ""
EX% = -1: CALL MDRIVER(EX%, B$, X%, Y%)
END SUB

SUB KINGINCHECK (CHECK%, CKINGX%, CKINGY%, PLAYER%)
REM CHECK EACH SPACE TO MOVE OUT OF CHECK
REDIM A1%(8), A2%(8)
A1%(1) = -2: A2%(1) = -5
A1%(2) = -2: A2%(2) = 0
A1%(3) = -2: A2%(3) = 5
A1%(4) = 0: A2%(4) = -5
A1%(5) = 0: A2%(5) = 5
A1%(6) = 2: A2%(6) = -5
A1%(7) = 2: A2%(7) = 0
A1%(8) = 2: A2%(8) = 5
FOR II% = 1 TO 8
A1% = A1%(II%): A2% = A2%(II%)
IF CKINGX% + A1% > 8 * 2 + TM% OR CKINGX% + A1% < TM% OR CKINGY% + A2% > 8 * 5 + LM% OR CKINGY% + A2% < LM% THEN
ELSE
LOCATE CKINGX% + A1%, CKINGY% + A2%
CKINGX% = CKINGX% + A1%: CKINGY% = CKINGY% + A2%
IF PLAYER% = 1 THEN BYPASSKINGCHECK% = -10 ELSE BYPASSKINGCHECK% = 10
CALL CHECKWATCH(BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, WKINGX%, WKINGY%, BKINGX%, BKINGY%, LEGAL%, CHECK%, CHECKMATE%)
BYPASSKINGCHECK% = PLAYER%: REM CANCELS ADDITIONAL CHECK WHEN A KING IS MOVED.
END IF
NEXT II%
END SUB

SUB KNIGHTCHECK (CKINGX%, CKINGY%, BYPASSKINGCHECK%, CHECKPARA%, OLDX%, OLDY%, X%, Y%, CHECKMATE%)
REDIM AX%(8), AY%(8)
AX%(1) = 2: AY%(1) = -1
AX%(2) = 2: AY%(2) = 1
AX%(3) = 1: AY%(3) = -2
AX%(4) = 1: AY%(4) = 2
AX%(5) = -1: AY%(5) = -2
AX%(6) = -1: AY%(6) = 2
AX%(7) = -2: AY%(7) = -1
AX%(8) = -2: AY%(8) = 1
FOR II% = 1 TO 8
A1% = AX%(II%) * 2: A2% = AY%(II%) * 5
IF CKINGX% + A1% > 8 * 2 + TM% OR CKINGX% + A1% < TM% OR CKINGY% + A2% > 8 * 5 + LM% OR CKINGY% + A2% < LM% THEN
ELSE
A$ = CHR$(SCREEN(CKINGX% + A1%, CKINGY% + A2%))
LOCATE CKINGX% + A1%, CKINGY% + A2%
IF A$ = "N" THEN
A4% = SCREEN(CKINGX% + A1%, CKINGY% + A2%, 1)
IF BYPASSKINGCHECK% = 10 AND A4% = 96 OR BYPASSKINGCHECK% = -10 AND A4% = 23 THEN
IF CKING% + A1% <> X% AND CKINGY% + A2% <> Y% THEN
CHECKPARA% = CHECKPARA% + 1
IF XCHECK% = 0 THEN XCHECK% = OLDX% + A1%: YCHECK% = OLDY% + A2%
EXIT FOR
END IF
END IF
END IF
END IF
NEXT II%

IF SCREEN(X%, Y%, 1) = COLORIT% THEN
IF PIECE$ <> "K" THEN LEGAL% = -1: EXIT DO: REM SAME COLOR PIECE
END IF

SELECT CASE PIECE$
CASE "K"
IF CHR$(SCREEN(X%, Y%)) = "R" THEN
IF PLAYER% = 1 AND SCREEN(X%, Y%, 1) = 23 OR PLAYER% = -1 AND SCREEN(X%, Y%, 1) = 96 THEN
REM CHECK FOR CASTLING
IF PLAYER% = 1 THEN
IF Y% > 5 THEN
IF MID$(WCASTLE$, 2, 1) = " " THEN LEGAL% = -1: EXIT DO
ELSE
IF MID$(WCASTLE$, 1, 1) = " " THEN LEGAL% = -1: EXIT DO
END IF
ELSE
IF Y% > 5 THEN
IF MID$(BCASTLE$, 2, 1) = " " THEN LEGAL% = -1: EXIT DO
ELSE
IF MID$(BCASTLE$, 1, 1) = " " THEN LEGAL% = -1: EXIT DO
END IF
END IF

REM CHECK FOR FREE SPACE IN BETWEEN PIECES
IF OLDY% > Y% THEN A% = -1 ELSE A% = 1
FOR I% = 1 TO ABS(Y% - OLDY%) STEP 5
IF I% <> 1 THEN IF SCREEN(OLDX%, OLDY% + A% * (I% - 1)) <> 32 THEN LEGAL% = -1: EXIT FOR
NEXT I%
IF LEGAL% = 0 THEN GOSUB CASTLING
EXIT DO
END IF
END IF

IF ABS(OLDX% - X%) > 2 OR ABS(OLDY% - Y%) > 5 THEN LEGAL% = -1
IF SCREEN(X%, Y%, 1) = COLORIT% THEN LEGAL% = -1

IF LEGAL% = 0 THEN
REM CANCEL ABILITY TO CASTLE
IF PLAYER% = 1 THEN WCASTLE$ = SPACE$(2) ELSE BCASTLE$ = SPACE$(2)
REM CHECK MOVE INTO CHECK
IF PLAYER% = 1 THEN BYPASSKINGCHECK% = 10 ELSE BYPASSKINGCHECK% = -10
CHECKPARA% = -1: CKINGX% = X%: CKINGY% = Y%
CALL CHECKWATCH(BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, WKINGX%, WKINGY%, BKINGX%, BKINGY%, LEGAL%, CHECK%, CHECKMATE%)
BYPASSKINGCHECK% = PLAYER%: REM CANCELS ADDITIONAL CHECK WHEN A KING IS MOVED.
END IF

CASE "N"
GOSUB KNIGHTMOVES

CASE "Q"
IF OLDX% <> X% AND OLDY% <> Y% THEN
CALL DIAGONAL(BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, LEGAL%, CHECK%, CHECKMATE%)
ELSE
CALL STRAIGHT(BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, LEGAL%, CHECK%, CHECKMATE%, IMATE%)
END IF

CASE "B"
IF OLDX% = X% OR OLDY% = Y% THEN LEGAL% = -1
CALL DIAGONAL(BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, LEGAL%, CHECK%, CHECKMATE%)

CASE "R"
IF OLDX% <> X% AND OLDY% <> Y% THEN LEGAL% = -1
CALL STRAIGHT(BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, LEGAL%, CHECK%, CHECKMATE%, IMATE%)
IF LEGAL% = 0 THEN
REM CHECK FOR CASTLING
IF PLAYER% = 1 AND OLDPOSX% = 1 THEN
IF RTRIM$(WCASTLE$) = "" THEN EXIT DO
IF OLDY% > 5 THEN MID$(WCASTLE$, 2, 1) = " " ELSE MID$(WCASTLE$, 1, 1) = " "
END IF
IF PLAYER% = -1 AND OLDPOSX% = 8 THEN
IF RTRIM$(BCASTLE$) = "" THEN EXIT DO
IF OLDY% > 5 THEN MID$(BCASTLE$, 2, 1) = " " ELSE MID$(BCASTLE$, 1, 1) = " "
END IF
END IF

CASE "P"
REM PAWNS
IF ENPASSANT$ <> "" THEN
IF VAL(ENPASSANT$) < 0 AND PLAYER% > 0 OR VAL(ENPASSANT$) > 0 AND PLAYER% < 0 THEN
IF ABS(OLDPOSX% - NEWPOSX%) = 1 AND X% = VAL(MID$(ENPASSANT$, 2, INSTR(ENPASSANT$, "|") - 1)) AND Y% = VAL(MID$(ENPASSANT$, INSTR(ENPASSANT$, "|") + 1)) THEN
C% = SCREEN(X% + 1, Y%, 1): COLOR C% MOD 16, C% \ 16
LOCATE OLDX%, Y% - 1
PRINT SPACE$(3);
LEGAL% = 0
EXIT DO
END IF
END IF
END IF
IF OLDPOSX% = 7 AND PLAYER% = -1 OR OLDPOSX% = 2 AND PLAYER% = 1 THEN
REM FIRST MOVE ALLOW ONE OR TWO SPACES
IF PLAYER% = 1 THEN
IF OLDPOSX% - NEWPOSX% < -2 OR OLDPOSX% - NEWPOSX% > -1 THEN LEGAL% = -1
ELSE
IF OLDPOSX% - NEWPOSX% > 2 OR OLDPOSX% - NEWPOSX% < 1 THEN LEGAL% = -1
END IF
ELSE
REM LIMIT PAWN TO ONE MOVE FORWARD UNLESS CAPTURING
IF NEWPOSX% - OLDPOSX% <> 1 * PLAYER% THEN LEGAL% = -1
END IF
REM CHECK FOR BLOCK
IF LEGAL% = 0 THEN
IF ABS(OLDPOSX% - NEWPOSX%) = 1 THEN
IF SCREEN(X%, Y%) <> 32 AND Y% = OLDY% THEN LEGAL% = -1
ELSE
IF SCREEN(X%, Y%) <> 32 OR SCREEN(X% + PLAYER% * 2, Y%) <> 32 THEN LEGAL% = -1
END IF
END IF
IF LEGAL% = 0 THEN
REM CHECK IF IN-LINE OR CAPTURING
IF Y% <> OLDY% THEN
IF ABS(OLDPOSX% - NEWPOSX%) > 1 THEN LEGAL% = -1
IF SCREEN(X%, Y%) = 32 THEN LEGAL% = -1
IF SCREEN(X%, Y%, 1) = SCREEN(OLDX%, OLDY%, 1) THEN LEGAL% = -1
END IF
END IF
IF LEGAL% = 0 AND ABS(OLDPOSX% - NEWPOSX%) = 2 THEN
L% = Y% - 5: R% = Y% + 5
IF L% > 0 THEN IF CHR$(SCREEN(X%, L%)) = "P" THEN ENPASSANT$ = LTRIM$(STR$(X% + (2 * PLAYER%))) + "|" + LTRIM$(STR$(Y%))
IF R% < 80 THEN IF CHR$(SCREEN(X%, R%)) = "P" THEN ENPASSANT$ = LTRIM$(STR$(X% + (2 * PLAYER%))) + "|" + LTRIM$(STR$(Y%))
IF ENPASSANT$ <> "" THEN IF PLAYER% < 0 THEN ENPASSANT$ = "-" + ENPASSANT$: EXIT DO ELSE ENPASSANT$ = "+" + ENPASSANT$: EXIT DO
END IF
REM CHECK EN PASSANT

CASE ELSE
END SELECT

IF LEGAL% = 0 THEN ENPASSANT$ = ""
EXIT DO
LOOP

IF LEGAL% = -1 THEN
REM ILLEGAL MOVE
A$ = CHR$(SCREEN(X%, Y%))
C% = SCREEN(X%, Y%, 1)
LOCATE X%, Y%: COLOR 14 + 16, 4: PRINT "X"; : SLEEP 1
LOCATE X%, Y%: COLOR C% MOD 16, C% \ 16: PRINT A$;
COLOR 7, 1
ELSE
IF ABS(BYPASSKINGCHECK%) <> 1 THEN IF PLAYER% = 1 THEN BYPASSKINGCHECK% = 10 ELSE BYPASSKINGCHECK% = -10
CALL CHECKWATCH(BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, WKINGX%, WKINGY%, BKINGX%, BKINGY%, LEGAL%, CHECK%, CHECKMATE%)
BYPASSKINGCHECK% = 0
END IF
EXIT SUB

CASTLING:
REM EXAMINE FOR CASTLING WHILE IN CHECK
IF PLAYER% = 1 THEN BYPASSKINGCHECK% = 10 ELSE BYPASSKINGCHECK% = -10
CALL CHECKWATCH(BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, WKINGX%, WKINGY%, BKINGX%, BKINGY%, LEGAL%, CHECK%, CHECKMATE%)
REM EXAMINE FOR CASTLING INTO CHECK
IF PLAYER% = 1 THEN IF Y% <= 5 + LM% THEN CKINGX% = OLDX%: CKINGY% = OLDY% - 5 * 2: BYPASSKINGCHECK% = 10 ELSE CKINGX% = OLDX%: CKINGY% = OLDY% + 5 * 2: BYPASSKINGCHECK% = 10
IF PLAYER% = -1 THEN IF Y% <= 5 + LM% THEN CKINGX% = OLDX%: CKINGY% = OLDY% - 5 * 2: BYPASSKINGCHECK% = -10 ELSE CKINGX% = OLDX%: CKINGY% = OLDY% + 5 * 2: BYPASSKINGCHECK% = -10
CHECKPARA% = -1
CALL CHECKWATCH(BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, WKINGX%, WKINGY%, BKINGX%, BKINGY%, LEGAL%, CHECK%, CHECKMATE%)
IF LEGAL% = -1 THEN RETURN
IF PLAYER% = 1 THEN WCASTLE$ = SPACE$(2) ELSE BCASTLE$ = SPACE$(2)
A% = SCREEN(OLDX% - 1, OLDY%, 1)
LOCATE OLDX%, OLDY% - 1: COLOR A% MOD 16, A% \ 16: PRINT SPACE$(3);
A% = SCREEN(X% - 1, Y%, 1)
LOCATE X%, Y% - 1: COLOR A% MOD 16, A% \ 16: PRINT SPACE$(3);
IF Y% > 5 THEN
COLOR COLORIT% MOD 16, COLORIT% \ 16
LOCATE OLDX%, OLDY% + 2 * 5 - 1: PRINT " K ";
LOCATE OLDX%, OLDY% + 1 * 5 - 1: PRINT " R ";
ELSE
COLOR COLORIT% MOD 16, COLORIT% \ 16
LOCATE OLDX%, OLDY% - 2 * 5 - 1: PRINT " K ";
LOCATE OLDX%, OLDY% - 1 * 5 - 1: PRINT " R ";
END IF
COLOR 7, 1
LEGAL% = 9
RETURN

KNIGHTMOVES:
IF ABS(OLDX% - X%) = 2 OR ABS(OLDY% - Y%) = 5 THEN
IF ABS(OLDX% - X%) = 2 AND ABS(OLDY% - Y%) <> 10 THEN LEGAL% = -1
IF ABS(OLDY% - Y%) = 5 AND ABS(OLDX% - X%) <> 4 THEN LEGAL% = -1
IF ABS(OLDX% - X%) = 4 AND ABS(OLDY% - Y%) <> 5 THEN LEGAL% = -1
IF ABS(OLDY% - Y%) = 10 AND ABS(OLDX% - X%) <> 2 THEN LEGAL% = -1
ELSE
LEGAL% = -1
END IF
RETURN

END SUB

SUB MAIN
WCASTLE$ = "RR"
BCASTLE$ = "RR"
PLAYER% = 1: REM WHITE (DEFAULT)
COLOR 7, 1: CLS
LM% = 3: TM% = 3: LEVEL% = 1
LOCATE TM%, LM%, 0
FOR H = 1 TO 8
FOR J = 1 TO 2
FOR I = 1 TO 8
IF H / 2 = H \ 2 THEN
IF I / 2 = I \ 2 THEN COLOR 0, 7 ELSE COLOR 7, 0
ELSE
IF I / 2 = I \ 2 THEN COLOR 7, 0 ELSE COLOR 0, 7
END IF
PRINT SPACE$(5);
NEXT I
IF H = 8 AND J = 2 THEN ELSE PRINT : LOCATE , LM%
NEXT J
NEXT H

FOR J = 1 TO 2
IF J = 1 THEN COLOR 0, 6 ELSE COLOR 7, 1: LEVEL% = 15
X = 1
A$ = "RNBQKBNR"
FOR I = 1 TO 8
LOCATE TM% + LEVEL%, X + LM%: PRINT " " + MID$(A$, I, 1) + " ";
X = X + 5
NEXT I
X = 1
FOR I = 1 TO 8
IF J = 1 THEN LOCATE TM% + LEVEL% + 2, X + LM% ELSE LOCATE TM% + LEVEL% - 2, X + LM%
PRINT " P ";
X = X + 5
NEXT I
NEXT J

REM BORDER
COLOR 7, 0
LOCATE TM% - 1, LM% - 1
PRINT CHR$(218); STRING$(40, 196); CHR$(191)
LOCATE , LM% - 1
FOR I = 1 TO 17
PRINT CHR$(179)
LOCATE , LM% - 1
NEXT I
LOCATE TM%, LM% - 1
FOR I = 1 TO 17
LOCATE , 40 + LM%
PRINT CHR$(179)
NEXT I
LOCATE TM% - 2 + 18, LM% - 1
PRINT CHR$(192); STRING$(40, 196); CHR$(217)

REM NUMBERING
LOCATE TM% + 17: COLOR 7, 1
LOCATE , LM% + 2
FOR I = 1 TO 8
PRINT LCASE$(CHR$(64 + I)) + SPACE$(4);
NEXT I

LOCATE TM% + 1, 40 + LM% + 2
FOR I = 1 TO 8
PRINT CHR$(57 - I);
LOCATE CSRLIN + 2, 40 + LM% + 2
NEXT I

LOCATE 25, 5: PRINT "Press Esc to end";
GOSUB PLAYERDISPLAY

DO
DO
CALL KEYBOARD(B$, X%, Y%)
IF B$ = "L-CLICK" THEN
CALL SNAPTOCENTER(X%, Y%)
IF MOVESTAT% = 0 THEN
LOCATE X%, Y%
IF PLAYER% = 1 AND SCREEN(X%, Y%, 1) <> 23 THEN LEGAL% = -2: GOSUB PLAYERDISPLAY: EXIT DO
IF PLAYER% = -1 AND SCREEN(X%, Y%, 1) <> 96 THEN LEGAL% = -2: GOSUB PLAYERDISPLAY: EXIT DO
OLDX% = X%: OLDY% = Y%
PIECE$ = CHR$(SCREEN(X%, Y%))
IF PIECE$ = CHR$(32) THEN
B$ = "": REM DO OVER EMPTY SQUARE
ELSE
COLORIT% = SCREEN(X%, Y%, 1)
COLOR COLORIT% MOD 16 + 16, COLORIT% \ 16
PRINT PIECE$;
COLOR 7, 1: B$ = ""
IF COLORIT% = 23 THEN MOVESTAT% = 1 ELSE MOVESTAT% = -1
END IF
ELSE
IF OLDX% = X% AND OLDY% = Y% THEN
REM CANCEL MOVE
LOCATE X%, Y%
COLOR COLORIT% MOD 16, COLORIT% \ 16
PRINT PIECE$;
COLOR 7, 1
MOVESTAT% = 0
B$ = ""
LEGAL% = -3: EXIT DO
ELSE
REM ********************Evaluate legal move here!
CALL LEGALCHECK(OLDX%, X%, OLDY%, Y%, PIECE$, COLORIT%, LEGAL%, WCASTLE$, BCASTLE$, PLAYER%, CHECK%)
CHECKPARA% = 0: REM RESET VALUE HERE
IF LEGAL% = 0 THEN
MOVESTAT% = 0
C% = SCREEN(OLDX% - 1, OLDY%, 1)
COLOR C% MOD 16, C% \ 16
LOCATE OLDX%, OLDY% - 1
PRINT SPACE$(3);
COLOR COLORIT% MOD 16, COLORIT% \ 16
LOCATE X%, Y% - 1
IF PIECE$ = "P" THEN
REM PAWN - QUEEN
IF 8 - INT((X% - TM% + 1) / 2.1) = 8 OR 8 - INT((X% - TM% + 1) / 2.1) = 1 THEN PIECE$ = "Q"
END IF
PRINT " " + PIECE$ + " ";
IF PLAYER% = 1 THEN BYPASSKINGCHECK% = -10 ELSE BYPASSKINGCHECK% = 10
X% = 0: Y% = 0: REM ZERO THESE VALUES WHEN STATIC TO AVOID INCLUSION IN MOVE ANALYSIS FOR CHECK
CALL CHECKWATCH(BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, WKINGX%, WKINGY%, BKINGX%, BKINGY%, LEGAL%, CHECK%, CHECKMATE%)
IF CHECKPARA% > 2 THEN CHECKMATE% = -2: REM MULTIPLE CHECK.
IF CHECK% <> 0 THEN
IF CHECK% = -1 THEN
III% = 0
CHECK% = 0
REDIM A1%(8), A2%(8)
A1%(1) = -2: A2%(1) = -5
A1%(2) = -2: A2%(2) = 0
A1%(3) = -2: A2%(3) = 5
A1%(4) = 0: A2%(4) = -5
A1%(5) = 0: A2%(5) = 5
A1%(6) = 2: A2%(6) = -5
A1%(7) = 2: A2%(7) = 0
A1%(8) = 2: A2%(8) = 5
END IF

DO
IF PLAYER% = 1 THEN CKINGX% = BKINGX%: CKINGY% = BKINGY% ELSE CKINGX% = WKINGX%: CKINGY% = WKINGY%: REM OPPOSITE - OPPONITE
III% = III% + 1
IF III% > 8 THEN CHECK% = 99: EXIT DO
A1% = A1%(III%): A2% = A2%(III%)
CKINGX% = CKINGX% + A1%: CKINGY% = CKINGY% + A2%
IF CKINGX% + A1% > 8 * 2 + TM% OR CKINGX% + A1% < TM% OR CKINGY% + A2% > 8 * 5 + LM% OR CKINGY% + A2% < LM% THEN
ELSE
LOCATE CKINGX%, CKINGY%
A4% = SCREEN(CKINGX%, CKINGY%, 1)
IF PLAYER% = 1 AND A4% = 96 OR PLAYER% = -1 AND A4% = 23 THEN
REM OCCUPIED SQUARE SAME PLAYER PIECE
IF CHECK% = 8 THEN CHECK% = 0: EXIT DO
ELSE
REM OPEN SPACE OR OPP. PIECE
CHECKPARA% = -1: CHECK% = -2
CALL CHECKWATCH(BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, WKINGX%, WKINGY%, BKINGX%, BKINGY%, LEGAL%, CHECK%, CHECKMATE%)
IF CHECK% <> -1 THEN EXIT DO: REM ESCAPE SPACE FOUND - NOT CHECKMATE
END IF
END IF
LOOP
IF CHECK% = 99 THEN
IF CHECKMATE% = -2 THEN
REM CHECKMATE - MULTIPLE CHECK AND NO ESCAPE
CHECKMATE% = -99
ELSE
REM POSSIBLE CHECKMATE!
CALL XMATE(PLAYER%, CKINGX%, CKINGY%, OLDX%, OLDY%, AX%, AY%, BYPASSKINGCHECK%, CHECKMATE%)
END IF
END IF
IF CHECKMATE% = -99 THEN
MSG$ = "Checkmate! Press Esc to end.": CALL MESSAGE(MSG$, CHECKMATE%): REM CHECKMATE!
DO: LOOP UNTIL INKEY$ = CHR$(27)
EXIT DO
END IF
CHECK% = 0: CHECKMATE% = 1: XCHECK% = 0: YCHECK% = 0
END IF
COLOR 7, 1
END IF
B$ = ""
END IF
END IF
END IF

CHECKPARA% = 0: CHECK% = 0: XCHECK% = 0: YCHECK% = 0: REM RESET VALUES
IF LEGAL% = 9 THEN LEGAL% = 0: MOVESTAT% = 0
IF LEGAL% = 0 AND MOVESTAT% = 0 THEN
CHECKMATE% = 0: PLAYER% = PLAYER% * -1: GOSUB PLAYERDISPLAY
ELSE
LEGAL% = 0: REM ILLEGAL MOVE, TRY AGAIN
END IF

IF B$ = CHR$(27) THEN EXIT DO
LOOP
IF LEGAL% <> -3 THEN EXIT DO ELSE LEGAL% = 0: REM OUT OF TURN
LOOP
EXIT SUB

PLAYERDISPLAY:
DO
COLOR 7, 1
IF LEGAL% = -2 THEN SOUND 100, 1: COLOR 7 + 16, 1
IF PLAYER% = 1 THEN A$ = "White" ELSE A$ = "Black"
LOCATE 25, 32: PRINT "Player: " + A$;
IF LEGAL% = -2 THEN SLEEP 1: LEGAL% = -3 ELSE EXIT DO
LOOP
COLOR 7, 1
RETURN

REM INITIATE MOUSE
IF MOUSEACT% = 0 THEN
Registers.AX = 0: GOSUB CALLI
MOUSEACT% = 1
END IF

IF EX% = -1 THEN
REM HIDES MOUSE IF A KEY WAS PRESSED FOR NEXT MOUSE LOOP
LB1 = 0
Registers.AX = 2: GOSUB CALLI
EX% = 2
EXIT SUB
END IF

IF EX% = 1 THEN Registers.AX = 1: GOSUB CALLI

Registers.AX = 3: GOSUB CALLI

REM MOUSE LOCATION (USES X% AND Y% TO CONVERT TO 25 * 80 SCREEN SIZE)
DX% = Registers.DX%
CX% = Registers.CX%
X% = DX% \ 8 + 1: Y% = CX% \ 8 + 1

IF X% <> OLDX% OR Y% <> OLDY% THEN
CALL BOARDMAP(B$, X%, Y%)
END IF

REM MOUSE BUTTONS
LB% = Registers.BX% AND 1
RB% = (Registers.BX% AND 2) \ 2
MB% = (Registers.BX% AND 4) \ 4
IF LB% <> 0 THEN
CALL BOARDMAP(B$, X%, Y%)
REM PLACE OTHER MOUSE FEATURES HERE
IF B$ = "OUTOFBOUNDS" THEN B$ = "" ELSE B$ = "L-CLICK": REM LEFT MOUSE CLICK
END IF

REM DELAY TO SMOOTH THINGS OUT.
IF LB1 <> -1 AND LB% <> 0 THEN
DO
REGISTER.AX% = 3: GOSUB CALLI
LB% = Registers.BX% AND 1
RB% = (Registers.BX% AND 2) \ 2
MB% = (Registers.BX% AND 4) \ 4
IF LB% = 0 THEN EXIT DO
LOOP
END IF

SUB MESSAGE (MSG$, CHECKMATE%)
XX = CSRLIN: YY = POS(1)
COLOR 7, 1
LOCATE 25, 47: PRINT SPACE$(80 - POS(1));
LOCATE 25, 47: PRINT MSG$;
SLEEP 1
IF CHECKMATE% <> -99 THEN LOCATE 25, 47: PRINT SPACE$(LEN(MSG$));
LOCATE XX, YY
END SUB

SUB SNAPTOCENTER (X%, Y%)
CNTY% = Y% - LM%
Y% = Y% - (3 - (5 - CNTY% MOD 5))
IF X% \ 2 <> X% / 2 THEN X% = X% + 1
END SUB

SUB STRAIGHT (BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, LEGAL%, CHECK%, CHECKMATE%, IMATE%)
IF LEGAL% = 0 THEN
REM CHECK BLOCKS

IF CHECKPARA% = 0 THEN
IF OLDX% <> X% THEN
IF OLDX% > X% THEN AX% = -2 ELSE AX% = 2
FOR I% = OLDX% + AX% TO X% STEP AX%
LOCATE I%, OLDY%
IF SCREEN(I%, OLDY%) <> 32 AND I% <> X% THEN LEGAL% = -1: EXIT FOR
NEXT I%
ELSE
IF OLDY% > Y% THEN AX% = -5 ELSE AX% = 5
FOR I% = OLDY% + AX% TO Y% STEP AX%
IF SCREEN(OLDX%, I%) <> 32 AND I% <> Y% THEN LEGAL% = -1: EXIT FOR
NEXT I%
END IF
ELSE

LOCATE CKINGX%, CKINGY%
FOR I% = 1 TO 8
A1% = A1% + AX%: A2% = A2% + AY%
IF CKINGX% + A1% > 8 * 2 + TM% OR CKINGX% + A1% < TM% OR CKINGY% + A2% > 8 * 5 + LM% OR CKINGY% + A2% < LM% THEN EXIT FOR
A$ = CHR$(SCREEN(CKINGX% + A1%, CKINGY% + A2%))
LOCATE CKINGX% + A1%, CKINGY% + A2%
IF CKINGX% + A1% = X% AND CKINGY% + A2% = Y% THEN EXIT FOR: REM ALLOWS A PIECE TO CAPTURE OR BLOCK KING IN CHECK
IF RTRIM$(A$) <> "" THEN
A4% = SCREEN(CKINGX% + A1%, CKINGY% + A2%, 1)
IF CHECKMATE% = 0 THEN INSTRX1$ = "KQR": INSTRX2$ = "K" ELSE INSTRX1$ = "QRP": INSTRX2$ = "P"
IF INSTR(INSTRX1$, A$) <> 0 THEN
IF INSTR(INSTRX2$, A$) <> 0 AND I% = 1 AND CHECKMATE% = 0 OR INSTR("QR", A$) <> 0 OR CHECKMATE% <> 0 AND INSTR("P", A$) <> 0 AND I% <= 2 AND A2% = 0 THEN
IF BYPASSKINGCHECK% = 10 AND A4% = 96 OR BYPASSKINGCHECK% = -10 AND A4% = 23 THEN
IF CHECKMATE% <> 0 AND INSTR("P", A$) <> 0 THEN
REM SPECIAL TO PAWNS
IF IMATE% <> 1 THEN
REM PAWNS CANNOT GO BACKWARDS
IF A4% = 96 AND A1% < 0 OR A4% = 23 AND A1% > 0 THEN
REM PAWNS CANNOT MOVE MORE THAN ONE SPACE UNLESS IN SECOND ROW
IF I% = 1 OR I% = 2 AND A4% = 96 AND 8 - INT((CKINGX% + A1% - TM% + 1) / 2.1) = 7 OR I% = 2 AND A4% = 96 AND 8 - INT((CKINGX% + A1% - TM% + 1) / 2.1) = 2 THEN
CHECKPARA% = CHECKPARA% + 1: XCHECK% = OLDX% + A1%: YCHECK% = OLDY% + A2%: EXIT FOR
END IF
END IF
END IF
ELSE
CHECKPARA% = CHECKPARA% + 1: XCHECK% = OLDX% + A1%: YCHECK% = OLDY% + A2%: EXIT FOR
END IF
END IF
END IF
END IF
IF A4% = 23 OR A4% = 96 THEN EXIT FOR: REM FLASHING PIECES WON'T GET IN THE WAY.
END IF

NEXT I%
END IF
END IF

END SUB

SUB XMATE (PLAYER%, CKINGX%, CKINGY%, OLDX%, OLDY%, AX%, AY%, BYPASSKINGCHECK%, CHECKMATE%)
LOCATE CKINGX%, CKINGY%
IF PLAYER% = 1 THEN BYPASSKINGCHECK% = 10 ELSE BYPASSKINGCHECK% = -10
CHECKMATE% = -1
IF ABS(XCHECK% \ 2 - CKINGX% \ 2) = ABS(YCHECK% \ 5 - CKINGY% \ 5) THEN
REM DIAGONAL - DETERMINE DIRECTION
A3% = ABS(XCHECK% \ 2 - CKINGX% \ 2)
IF XCHECK% > CKINGX% AND YCHECK% < CKINGY% THEN A1% = -2: A2% = 5
IF XCHECK% > CKINGX% AND YCHECK% > CKINGY% THEN A1% = -2: A2% = -5
IF XCHECK% < CKINGX% AND YCHECK% < CKINGY% THEN A1% = 2: A2% = 5
IF XCHECK% < CKINGX% AND YCHECK% > CKINGY% THEN A1% = 2: A2% = -5
CKINGX% = XCHECK%: CKINGY% = YCHECK%
HOLDOLDX% = OLDX%: HOLDOLDY% = OLDY%
FOR IMATE% = 1 TO A3%
CHECKPARA% = 1
OLDX% = CKINGX%: OLDY% = CKINGY%
REDIM AX%(4), AY%(4)
AX%(1) = -2: AY%(1) = -5
AX%(2) = 2: AY%(2) = 5
AX%(3) = -2: AY%(3) = 5
AX%(4) = 2: AY%(4) = -5
FOR JJ% = 1 TO 4
AX% = AX%(JJ%): AY% = AY%(JJ%)
LOCATE CKINGX%, CKINGY%
CALL DIAGONAL(BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, LEGAL%, CHECK%, CHECKMATE%)
IF CHECKPARA% > 1 THEN EXIT FOR
NEXT JJ%
IF CHECKPARA% > 1 THEN EXIT FOR
CKINGX% = CKINGX% + A1%: CKINGY% = CKINGY% + A2%
NEXT IMATE%

CKINGX% = XCHECK%: CKINGY% = YCHECK%
CHECKPARA% = 1
FOR IMATE% = 1 TO A3%
OLDX% = CKINGX%: OLDY% = CKINGY%
REDIM AX%(4), AY%(4)
AX%(1) = -2: AY%(1) = 0
AX%(2) = 2: AY%(2) = 0
AX%(3) = 0: AY%(3) = 5
AX%(4) = 0: AY%(4) = -5
FOR JJ% = 1 TO 4
AX% = AX%(JJ%): AY% = AY%(JJ%)
LOCATE CKINGX%, CKINGY%
CALL STRAIGHT(BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, LEGAL%, CHECK%, CHECKMATE%, IMATE%)
IF CHECKPARA% > 1 THEN EXIT FOR
NEXT JJ%
IF CHECKPARA% > 1 THEN EXIT FOR
CKINGX% = CKINGX% + A1%: CKINGY% = CKINGY% + A2%
NEXT IMATE%

ELSE
REM STRAIGHT - DETERMINE DIRECTION
IF XCHECK% > CKINGX% AND YCHECK% = CKINGY% THEN A1% = -2: A2% = 0: A3% = ABS(XCHECK% \ 2 - CKINGX% \ 2)
IF XCHECK% < CKINGX% AND YCHECK% = CKINGY% THEN A1% = 2: A2% = 0: A3% = ABS(XCHECK% \ 2 - CKINGX% \ 2)
IF XCHECK% = CKINGX% AND YCHECK% > CKINGY% THEN A1% = 0: A2% = -5: A3% = ABS(XCHECY% \ 5 - CKINGY% \ 5)
IF XCHECK% = CKINGX% AND YCHECK% < CKINGY% THEN A1% = 0: A2% = 5: A3% = ABS(XCHECY% \ 5 - CKINGY% \ 5)
CKINGX% = XCHECK%: CKINGY% = YCHECK%
HOLDOLDX% = OLDX%: HOLDOLDY% = OLDY%
FOR IMATE% = 1 TO A3%
CHECKPARA% = 1
OLDX% = CKINGX%: OLDY% = CKINGY%
REDIM AX%(4), AY%(4)
AX%(1) = -2: AY%(1) = -5
AX%(2) = 2: AY%(2) = 5
AX%(3) = -2: AY%(3) = 5
AX%(4) = 2: AY%(4) = -5
FOR JJ% = 1 TO 4
AX% = AX%(JJ%): AY% = AY%(JJ%)
LOCATE CKINGX%, CKINGY%
CALL DIAGONAL(BYPASSKINGCHECK%, CHECKPARA%, PLAYER%, X%, OLDX%, Y%, OLDY%, AX%, AY%, CKINGX%, CKINGY%, LEGAL%, CHECK%, CHECKMATE%)
IF CHECKPARA% > 1 THEN
HOLDX% = OLDX%: HOLDY% = Y%: OLDX% = CSRLIN: OLDY% = POS(1)
BYPASSKINGCHECK% = 0
PLAYER% = -PLAYER%
A% = SCREEN(CSRLIN, POS(1), 1)
PIECE$ = CHR$(SCREEN(CSRLIN, POS(1)))
COLOR A% MOD 16 + 16, A% \ 16: PRINT PIECE$;
LOCATE OLDX%, OLDY%
X% = CKINGX%: Y% = CKINGY%: CHECK% = -99
CALL LEGALCHECK(OLDX%, X%, OLDY%, Y%, PIECE$, COLORIT%, LEGAL%, WCASTLE$, BCASTLE$, PLAYER%, CHECK%)
LOCATE OLDX%, OLDY%: COLOR A% MOD 16, A% \ 16: PRINT PIECE$; : LOCATE OLDX%, OLDY%
PLAYER% = -PLAYER%: OLDX% = HOLDX%: OLDY% = HOLDY%: REM X%,Y%,PIECE$ ARE NOT PASSED VARIABLES.
IF LEGAL% = 0 THEN EXIT FOR ELSE CHECKPARA% = 1: LEGAL% = 0: REM CANNOT MAKE BLOCK OR CAPTURE WITHOUT PLACING KING IN CHECK
END IF
IF CHECKPARA% > 1 THEN EXIT FOR
NEXT JJ%
IF CHECKPARA% > 1 THEN EXIT FOR
CKINGX% = CKINGX% + A1%: CKINGY% = CKINGY% + A2%
NEXT IMATE%
END IF
OLDX% = HOLDOLDX%: OLDY% = HOLDOLDY%
IF CHECKPARA% = 1 THEN
CHECKMATE% = -99: REM CHECKMATE
ELSE
CHECKMATE% = 0
END IF
CHECK% = 0