; ************************** AMUS Program Label ****************************** ; Filename: CHESS.M68 Date: 07/05/90 ; Category: GAME Hash Code: 107-752-654-275 Version: 0.1(1) ; Initials: ULTR/AM Name: DAVID PALLMANN ; Company: ULTRASOFT CORPORATION Telephone #: 5163484848 ; Related Files: ; Min. Op. Sys.: AMOSL 1.3B Expertise Level: BEG ; Special: ; Description: Rudimentary chess program; will be improved over time. ; Has a manual mode for piece adjustment and experimentation; allows saving ; and loading of games; automatic play is idiot level w/1 move look-ahead. ; **************************************************************************** ;**************************************************************************** ;* * ;* CHESS * ;* * ;**************************************************************************** ;Copyright (C) 1990 UltraSoft Corporation. All Rights Reserved. ; ;Written by: David Pallmann ; ;Edit History: ;0.1(1) 04-Jul-90 created. /DFP ; ;This is an incomplete chess program. It currently supports manual piece ;arrangement and automatic play. The automatic play is at the idiot level, ;playing for material only with one-move look ahead only. ; ;In addition, the program knows nothing about en-passante, check, checkmate, ;castling, or even when the game is over. (On the other hand, only about ;4 hours work have been put into CHESS so far.) ; ;You need about 70K to run this version of CHESS. ; ;As time allows, CHESS will be steadily improved until, some day in the far ;future, it can hold its own on the playing field of honor. For now, it may ;prove useful as a program example to those learning assembler. VMAJOR =0 VMINOR =1 VSUB =0 VEDIT =1 VWHO =0 SEARCH SYS SEARCH SYSSYM SEARCH TRM ;ASCII charcters $LF =12 $CR =15 $ESC =33 ;parameters MOVMAX =5000. ; number of moves in move list array ;move list entry definition .OFINI .OFDEF MOVFRM, 4 ; from location .OFDEF MOVTO, 4 ; to location .OFDEF MOVVAL, 4 ; value .OFSIZ MOVSIZ ;variables .OFINI .OFDEF FLAGS, 2 ; flags: F$AUTO =1 ; auto mode (computer plays human) F$CMD =2 ; game specified on cmd line F$DEBUG =4 ; debug mode on F$COMP =10 ; computer is going .OFDEF BOARD, 10.*10. ; the playing board plus border .OFDEF SAVBRD, 10.*10. ; saved playing board .OFDEF MOVCNT, 2 ; number of moves .OFDEF MOVES, 40.*4 ; memory for 40 moves .OFDEF FILE, D.DDB ; file DDB .OFDEF LINE, 100. ; input line .OFDEF LOC, 2 ; location coordinates (e.g. "a1) .OFDEF PLAYER, 2 ; player code (0=white, 200=black) .OFDEF VALUE,2 ; temp - value of current move .OFDEF MOVE.COUNT,2 ; move list - count .OFDEF MOVE.VALUE,2 ; highest move value .OFDEF CAPTURE,1 ; what was taken last capture .OFDEF XXXXX, 1 ; even up address .OFDEF MOVE.LIST, MOVMAX*MOVSIZ; move list - moves .OFSIZ MEMSIZ ;piece codes WHITE =0 ; high bit 0 = white BLACK =200 ; high bit 1 = black PAWN =1 ; pawn KNIGHT =3 ; knight BISHOP =4 ; bishop ROOK =5 ; knight QUEEN =9. ; queen KING =10. ; king BORDER =99. ; board border ;macros DEFINE CURSOR ROW,COL MOVB ROW,D1 ROLW D1,#8. MOVB COL,D1 TCRT ENDM DEFINE CRT CODE MOVW #-1_8.+^D,D1 TCRT ENDM DEFINE FCOLOR N MOVW #-2_8.+N,D1 TCRT ENDM DEFINER BCOLOR N MOVW #-3_8.+N,D1 TCRT ENDM DEFINE DING TTYI BYTE 7,0 EVEN ENDM DEFINE BITW SRC,DST MOVW DST,D7 ANDW SRC,D7 ENDM START: PHDR -1,0,PH$REE!PH$REU ; program header GETIMP MEMSIZ,A5 ; get variable memory IDENT: TYPESP UltraCHESS ; VCVT START+2,OT$TRM ; CRLF ; CMDLIN: BYP ; LIN ; BEQ INIT ; ORW #F$CMD,FLAGS(A5) ; INIT: CRT 29 ; INIT FILE(A5) ; MOVW #WHITE,PLAYER(A5) ; CALL SETUP ; TRMRST D0 ; ORW #T$DAT!T$ECS,D0 ; TRMWST D0 ; ;************ ;* GETCMD * ;************ ;Get command GETCMD: BITW #F$CMD,FLAGS(A5) ; JNE LOAD2 ; BITW #F$AUTO,FLAGS(A5) ; JNE AUTOMATIC.PLAY ; CURSOR #23.,#1 ; CRT 11 ; TYPESP Enter command: ; CRT 28 ; CRT 12 ; CRT 9 ; TIN ; UCS ; MOVB D1,D0 ; CRT 29 ; CRT 10 ; CMPB D0,#$ESC ; ESC (quit)? JEQ QUIT ; yes CMPB D0,#'A ; A)uto? JEQ AUTO ; yes CMPB D0,#'C ; C)olor? JEQ COLOR ; yes CMPB D0,#'D ; D)ebug? JEQ DEBUG ; CMPB D0,#'H ; H)elp? JEQ HELP ; yes CMPB D0,#'L ; L)oad? JEQ LOAD ; yes CMPB D0,#'M ; M)anual? JEQ MOVE ; yes CMPB D0,#'N ; N)ew game? JEQ NEW.GAME ; yes CMPB D0,#'R ; R)evert to last saved game? JEQ REVERT ; yes CMPB D0,#'Q ; Q)uit? JEQ QUIT ; yes CMPB D0,#'S ; S)ave? JEQ SAVE ; yes DING ; CURSOR #24.,#1 ; TYPE Press H for help JMP GETCMD ; AUTO: BITW #F$AUTO,FLAGS(A5) ; BNE MANUAL ; ORW #F$AUTO,FLAGS(A5) ; CALL SHOW.MODE ; JMP GETCMD ; MANUAL: ANDW #^C,FLAGS(A5) ; CALL SHOW.MODE ; JMP GETCMD ; AUTOMATIC.PLAY: BITW #1,MOVCNT(A5) ; JEQ HUMAN.MOVE ; ; fall through ;******************* ;* COMPUTER.MOVE * ;******************* ;Computer move COMPUTER.MOVE: ORW #F$COMP,FLAGS(A5) ; CURSOR #23.,#1 ; TYPE Thinking... ; CRT 10 ; CLRB CAPTURE(A5) ; CLRW MOVE.COUNT(A5) ; CLRW MOVE.VALUE(A5) ; LEA A4,MOVE.LIST(A5) ; LEA A0,BOARD+11.(A5) ; MOV #8.,D2 ; 10$: MOV #8.,D3 ; 20$: MOVB @A0,D1 ; blank square? BEQ 30$ ; yes - forget about this square TSTW PLAYER(A5) ; is human white or black? BEQ 22$ ; human is white ;human is black, computer is white TSTB D1 ; is the piece here black? BMI 30$ ; yes - we can't move black BR 25$ ; ;human is white, computer is black 22$: TSTB D1 ; is the piece here white? BPL 30$ ; yes - move can't move white 25$: AND #177,D1 ; CALL FIND.MOVES ; find a move from this square 30$: INC A0 ; advance to next square SOB D3,20$ ; loop across ADD #2,A0 ; point to next row of squares SOB D2,10$ ; loop down TSTW MOVE.COUNT(A5) ; did we come up with any moves? JNE SELECT.MOVE ; yes CANT.MOVE: DING ; CURSOR #24.,#1 ; CRT 9 ; TYPE Computer is unable to move CURSOR #23.,#1 ; CRT 9 ; ANDW #^C,FLAGS(A5) ; JMP MOVE ; we can't move (!) ;we have found a valid move - make it SELECT.MOVE: BITW #F$DEBUG,FLAGS(A5) ; BEQ 5$ ; CALL SHOW.MOVE.LIST ; 5$: LEA A4,MOVE.LIST(A5) ; CLR D4 ; MOVW MOVE.COUNT(A5),D4 ; JEQ CANT.MOVE ; 10$: CMMW MOVVAL(A4),MOVE.VALUE(A5); BEQ 20$ ; ADD #MOVSIZ,A4 ; SOB D4,10$ ; JMP CANT.MOVE ; 20$: MOV MOVFRM(A4),A0 ; MOV MOVTO(A4),A1 ; MOVB @A1,CAPTURE(A5) ; MOVB @A0,@A1 ; CLRB @A0 ; CALL GET.COORDINATES ; MOV D1,D0 ; SAVE A0-A1 ; MOV A1,A0 ; CALL GET.COORDINATES ; AND #177777,D0 ; ROL D0,#8. ; ROL D0,#8. ; ADD D0,D1 ; LEA A6,MOVES(A5) ; CLR D6 ; MOVW MOVCNT(A5),D6 ; MUL D6,#4 ; ADD D6,A6 ; MOV D1,@A6 ; INCW MOVCNT(A5) ; CALL DISPLAY.BOARD ; CALL DISPLAY.MOVES ; REST A0-A1 ; CURSOR #24.,#1 ; CRT 11 ; TYPESP Computer's move: ; CRT 12 ; CALL GET.COORDINATES ; RORW D1,#8. ; TTY ; ROLW D1,#8. ; TTY ; CRT 11 ; TYPE - ; CRT 12 ; MOV A1,A0 ; CALL GET.COORDINATES ; RORW D1,#8. ; TTY ; ROLW D1,#8. ; TTY ; MOVB CAPTURE(A5),D0 ; BEQ 90$ CRT 11 ; TYPE <, > ; CRT 12 ; AND #177,D0 ; CALL PIECE.NAME ; CRT 11 ; TYPE < captured> ; CRT 12 ; 90$: HUMAN.MOVE: ANDW #^C,FLAGS(A5) ; CURSOR #23.,#1 ; CRT 9 ; JMP MOVE ; now let human move ;*********** ;* COLOR * ;*********** ;Change color COLOR: TSTW PLAYER(A5) ; BEQ SET.BLACK ; SET.WHITE: MOVW #WHITE,PLAYER(A5) ; CALL SHOW.COLOR ; CURSOR #24.,#1 ; TYPE Color changed to White ; JMP GETCMD ; SET.BLACK: MOVW #BLACK,PLAYER(A5) ; CALL SHOW.COLOR ; CURSOR #24.,#1 ; TYPE Color changed to Black ; JMP GETCMD ; ;*********** ;* DEBUG * ;*********** ;Toggle debug mode DEBUG: XORW #F$DEBUG,FLAGS(A5) ; CALL SHOW.DEBUG ; JMP GETCMD ; SHOW.DEBUG: BITW #F$DEBUG,FLAGS(A5) ; JEQ DEBUG.OFF ; DEBUG.ON: CURSOR #1,#60. ; TYPE Debug ; RTN ; DEBUG.OFF: CURSOR #1,#60. ; TYPE < > ; RTN ; ;********** ;* MOVE * ;********** ;Move a piece MOVE: TYPESP Move a piece from ; CRT 28 ; 10$: TIN ; CMPB D1,#$ESC ; JEQ ABORT.AUTO ; LCS ; CMPB D1,#'a ; BLO 10$ ; CMPB D1,#'h ; BHI 10$ ; TTY ; MOVB D1,D2 ; 20$: TIN ; CMPB D1,#$ESC ; JEQ ABORT.AUTO ; CMPB D1,#'1 ; BLO 20$ ; CMPB D1,#'8 ; BHI 20$ ; TTY ; MOVB D1,D3 ; TYPE < to > ; 30$: TIN ; CMPB D1,#$ESC ; JEQ ABORT.AUTO ; LCS ; CMPB D1,#'a ; BLO 30$ ; CMPB D1,#'h ; BHI 10$ ; TTY ; MOVB D1,D4 ; 40$: TIN ; CMPB D1,#$ESC ; JEQ ABORT.AUTO ; CMPB D1,#'1 ; BLO 40$ ; CMPB D1,#'8 ; BHI 40$ ; TTY ; MOVB D1,D5 ; CRT 29 ; MOVB D2,LOC(A5) ; MOVB D3,LOC+1(A5) ; CALL INDEX ; JEQ EMPTY ; CMPB D0,PLAYER(A5) ; BEQ 50$ ; CURSOR #24.,#1 ; DING ; BITW #F$AUTO,FLAGS(A5) ; JNE WRONG.COLOR ; TYPESP Not your piece - proceed with move anyway? CRT 28 ; TIN ; UCS ; CMPB D1,#'Y ; BEQ 45$ ; CRT 29 ; TYPE No ; JMP ABORTED.MOVE ; 45$: TYPE Yes ; CRT 29 ; 50$: ;"from" square has been approved ;now, see if move to "to" square is a valid one MOVB D4,LOC(A5) ; MOVB D5,LOC+1(A5) ; CALL INDEX ; MOV A0,A1 ; MOVB D2,LOC(A5) ; MOVB D3,LOC+1(A5) ; CALL INDEX ; CALL MOVE.CHECK ; JNE INVALID.MOVE ; MOVB D2,LOC(A5) ; MOVB D3,LOC+1(A5) ; CALL INDEX ; MOVB @A0,D1 ; PUSH D1 ; CLRB @A0 ; MOVB D4,LOC(A5) ; MOVB D5,LOC+1(A5) ; CALL INDEX ; POP D1 ; MOVB D1,@A0 ; CLR D0 ; MOVW MOVCNT(A5),D0 ; INCW MOVCNT(A5) ; LEA A0,MOVES(A5) ; MUL D0,#4 ; ADD D0,A0 ; MOVB D3,(A0)+ ; MOVB D2,(A0)+ ; MOVB D5,(A0)+ ; MOVB D4,(A0)+ ; CALL DISPLAY.MOVES ; CALL DISPLAY.BOARD ; JMP GETCMD ; ABORT.AUTO: CRT 29 ; JMP AUTO ; EMPTY: DING ; CURSOR #24.,#1 ; TYPE There is no piece on that square BR ABORTED.MOVE ; WRONG.COLOR: DING ; CURSOR #24.,#1 ; TYPE You may only move your own pieces CRT 9 ; BR ABORTED.MOVE ; INVALID.MOVE: DING ; CURSOR #24.,#1 ; CRT 9 ; TYPE That is not a valid move ABORTED.MOVE: BITW #F$AUTO,FLAGS(A5) ; JEQ GETCMD ; CURSOR #23.,#1 ; CRT 9 ; CRT 29 ; JMP MOVE ; ;********** ;* HELP * ;********** ;Help HELP: TYPE Help ; CURSOR #3,#1 ; CRT 10 ; CRT 12 ; TYPECR UltraCHESS Command Summary: CRLF ; TYPECR A ............ toggle between Auto and Manual mode TYPECR C ............ switch your color TYPECR D ............ toggle debug mode on and off TYPECR H ............ help TYPECR L ............ load game TYPECR M ............ move a piece TYPECR N ............ new game TYPECR R ............ revert to last saved game TYPECR S ............ save game TYPECR Q ............ quit CRLF ; TYPECR TYPECR TYPECR CRLF ; TYPECR TYPECR CURSOR #23.,#1 ; CRT 11 ; TYPESP Press any key to resume game: TIN ; CRT 12 ; CALL DISPLAY.SCREEN ; CALL DISPLAY.BOARD ; CALL DISPLAY.MOVES ; JMP GETCMD ; ;********** ;* QUIT * ;********** QUIT: TYPE Quit ; CURSOR #24.,#1 ; TYPESP Okay to quit? ; TIN ; UCS ; CMPB D1,#'Y ; BEQ 10$ ; TYPE N ; JMP GETCMD ; 10$: TYPE Y ; EXIT: BCOLOR 0 ; background black FCOLOR 1 ; foreground white CRT 12 ; CURSOR #24.,#1 ; CRT 9 ; CRT 28 ; EXIT ; ;************** ;* NEW.GAME * ;************** NEW.GAME: TYPE New game ; CURSOR #24.,#1 ; TYPESP Okay to abandon current game? TIN ; UCS ; CMPB D1,#'Y ; BEQ 10$ ; TYPE N ; JMP GETCMD ; 10$: TYPE Y ; CURSOR #1,#70 ; CRT 9 ; CALL DISPLAY.SCREEN ; CALL INIT.BOARD ; CALL DISPLAY.BOARD ; CLRW MOVCNT(A5) ; CLEAR MOVES(A5),40.*4 ; CALL DISPLAY.MOVES ; JMP GETCMD ; ;************ ;* REVERT * ;************ REVERT: TYPE Revert ; TST FILE+D.FIL(A5) ; BEQ 20$ ; CURSOR #24.,#1 ; TYPESP Revert to last saved version of PRNAM FILE+D.FIL(A5) ; TYPESP ? ; TIN ; UCS ; CMPB D1,#'Y ; BEQ 10$ ; TYPE No ; JMP GETCMD ; 10$: TYPE Yes ; JMP LOAD3 ; 20$: DING ; CURSOR #24.,#1 ; TYPE Cannot revert - no game has been loaded or saved JMP GETCMD ; ;********** ;* LOAD * ;********** ;Load game LOAD: TYPE Load game saved under name ______ CRT 5 ; CRT 5 ; CRT 5 ; CRT 5 ; CRT 5 ; CRT 5 ; TRMRST D0 ; ANDW #^C,D0 ; TRMWST D0 ; KBD EXIT ; TRMRST D0 ; ORW #T$DAT!T$ECS,D0 ; TRMWST D0 ; LOAD2: BYP ; LIN ; JEQ GETCMD ; CLR FILE+D.DVR(A5) ; FSPEC FILE(A5),CHS ; LOAD3: LOOKUP FILE(A5) ; JNE NOT.FOUND ; ANDW #^C,FLAGS(A5) ; OPENI FILE(A5) ; MOV #8.,D2 ; LEA A0,BOARD+10.(A5) ; 20$: LEA A2,LINE(A5) ; 22$: FILINB FILE(A5) ; MOVB D1,(A2)+ ; CMPB D1,#$LF ; BNE 22$ ; CLRB @A2 ; INC A0 ; MOV #8.,D3 ; LEA A2,LINE(A5) ; 30$: GTDEC ; MOVB D1,(A0)+ ; BYP ; SOB D3,30$ ; INC A0 ; SOB D2,20$ ; CLRW MOVCNT(A5) ; CLEAR MOVES(A5),40.*4 ; LEA A0,MOVES(A5) ; 40$: LEA A2,LINE(A5) ; 50$: FILINB FILE(A5) ; TST FILE+D.SIZ(A5) ; BEQ 90$ ; MOVB D1,(A2)+ ; CMPB D1,#$LF ; BNE 50$ ; LEA A2,LINE(A5) ; BYP ; ALF ; JNE 40$ ; MOVB (A2)+,D1 ; ROL D1,#8. ; MOVB (A2)+,D1 ; ROL D1,#8. ; INC A2 ; bypass - MOVB (A2)+,D1 ; ROL D1,#8. ; MOVB @A2,D1 ; MOV D1,(A0)+ ; INCW MOVCNT(A5) ; JMP 40$ ; 90$: CLOSE FILE(A5) ; CALL DISPLAY.SCREEN ; CURSOR #1,#70. ; PRNAM FILE+D.FIL(A5) ; CALL DISPLAY.BOARD ; CALL DISPLAY.MOVES ; JMP GETCMD ; NOT.FOUND: BITW #F$CMD,FLAGS(A5) ; BNE 10$ ; CURSOR #24.,#1 ; CRT 12 ; 10$: DING ; TYPESP Game file ; PFILE FILE(A5) ; TYPE < not found> ; BITW #F$CMD,FLAGS(A5) ; BNE 20$ ; JMP GETCMD ; 20$: CRLF ; EXIT ; ;********** ;* SAVE * ;********** ;Save game SAVE: TYPE Save game under name ______ CRT 5 ; CRT 5 ; CRT 5 ; CRT 5 ; CRT 5 ; CRT 5 ; TRMRST D0 ; ANDW #^C,D0 ; TRMWST D0 ; KBD EXIT ; TRMRST D0 ; ORW #T$DAT!T$ECS,D0 ; TRMWST D0 ; BYP ; LIN ; JEQ GETCMD ; CLR FILE+D.DVR(A5) ; FSPEC FILE(A5),CHS ; LEA A2,FILE(A5) ; LOOKUP FILE(A5) ; BNE 10$ ; DSKDEL FILE(A5) ; 10$: OPENO FILE(A5) ; MOV #8.,D2 ; LEA A0,BOARD+10.(A5) ; 20$: MOV #8.,D3 ; INC A0 ; CLR D1 ; 30$: MOVB (A0)+,D1 ; DCVT 0,OT$DDB!OT$TSP ; SOB D3,30$ ; INC A0 ; MOVB #$CR,D1 ; FILOTB @A2 ; MOVB #$LF,D1 ; FILOTB @A2 ; SOB D2,20$ ; CLR D0 ; MOVW MOVCNT(A5),D0 ; BEQ 90$ ; LEA A0,MOVES(A5) ; 40$: MOV (A0)+,D1 ; ROL D1,#8. ; FILOTB @A2 ; ROL D1,#8. ; FILOTB @A2 ; PUSH D1 ; MOVB #'-,D1 FILOTB @A2 ; POP D1 ; ROL D1,#8. ; FILOTB @A2 ; ROL D1,#8. ; FILOTB @A2 ; MOVB #$CR,D1 ; FILOTB @A2 ; MOVB #$LF,D1 ; FILOTB @A2 ; SOB D0,40$ ; 90$: CLOSE FILE(A5) ; CURSOR #1,#70. ; PRNAM FILE+D.FIL(A5) ; JMP GETCMD ; ;*********** ;* SETUP * ;*********** ;Set-up for a new game SETUP: BITW #F$CMD,FLAGS(A5) ; BNE 10$ ; CALL DISPLAY.SCREEN ; display background screen CALL INIT.BOARD ; initialize board CALL DISPLAY.BOARD ; display board 10$: RTN ; return ;**************** ;* INIT.BOARD * ;**************** ;Function: Initialize the chess board for playing INIT.BOARD: SAVE A0-A1,D0 ; LEA A0,BOARD.LIST ; LEA A1,BOARD(A5) ; MOV #10.*10.,D0 ; 10$: MOVB (A0)+,(A1)+ ; SOB D0,10$ ; REST A0-A1,D0 ; RTN ; BOARD.LIST: BYTE BORDER,BORDER,BORDER,BORDER,BORDER,BORDER,BORDER,BORDER,BORDER,BORDER BYTE BORDER,BLACK+ROOK,BLACK+KNIGHT,BLACK+BISHOP,BLACK+KING,BLACK+QUEEN,BLACK+BISHOP,BLACK+KNIGHT,BLACK+ROOK,BORDER BYTE BORDER,BLACK+PAWN,BLACK+PAWN,BLACK+PAWN,BLACK+PAWN,BLACK+PAWN,BLACK+PAWN,BLACK+PAWN,BLACK+PAWN,BORDER BYTE BORDER,0.,0.,0.,0.,0.,0.,0.,0.,BORDER BYTE BORDER,0.,0.,0.,0.,0.,0.,0.,0.,BORDER BYTE BORDER,0.,0.,0.,0.,0.,0.,0.,0.,BORDER BYTE BORDER,0.,0.,0.,0.,0.,0.,0.,0.,BORDER BYTE BORDER,PAWN,PAWN,PAWN,PAWN,PAWN,PAWN,PAWN,PAWN,BORDER BYTE BORDER,ROOK,KNIGHT,BISHOP,KING,QUEEN,BISHOP,KNIGHT,ROOK,BORDER BYTE BORDER,BORDER,BORDER,BORDER,BORDER,BORDER,BORDER,BORDER,BORDER,BORDER ;******************** ;* DISPLAY.SCREEN * ;******************** ;Function:›Display chess background screen DISPLAY.SCREEN: BCOLOR 1 ; background is white FCOLOR 6 ; foreground is green CRT 0 ; CRT 12 ; TYPESP UltraCHESS ; VCVT START+2,OT$TRM ; CALL SHOW.MODE ; CALL SHOW.COLOR ; CALL SHOW.DEBUG ; CURSOR #3,#6 ; TYPE <1 2 3 4 5 6 7 8> CURSOR #21.,#6 ; TYPE <1 2 3 4 5 6 7 8> MOV #5,D2 ; MOV #8.,D3 ; 10$: CURSOR D2,#2 ; MOV D3,D1 ; ADDB #'`,D1 ; TTY ; CURSOR D2,#46. ; MOV D3,D1 ; ADDB #'`,D1 ; TTY ; ADD #2,D2 ; SOB D3,10$ ; ;show move numbers for 40 moves CRT 11 ; MOV #3.,D2 ; row MOV #20.,D3 ; loop count CLR D0 ; 20$: CURSOR D2,#55. ; INC D0 ; MOV D0,D1 ; DCVT 2,OT$TRM!OT$ZER ; TYPE . ; CURSOR D2,#65. ; MOV D0,D1 ; ADD #20.,D1 ; DCVT 2,OT$TRM ; TYPE . ; INCW D2 ; SOB D3,20$ ; CRT 12 ; BITW #F$AUTO,FLAGS(A5) ; BNE 30$ ; CURSOR #24.,#1 ; TYPE Press A to begin automatic play 30$: RTN ; SHOW.MODE: CURSOR #1,#37. ; BITW #F$AUTO,FLAGS(A5) ; BEQ 5$ ; TYPE < Auto > ; BR 7$ ; 5$: TYPE ; 7$: RTN ; SHOW.COLOR: CURSOR #1,#47. ; TSTW PLAYER(A5) ; BEQ 5$ ; TYPE ; BR 7$ ; 5$: TYPE ; 7$: RTN ; ;******************* ;* DISPLAY.BOARD * ;******************* ;Function:›Display entire chessboard (both background and foreground) DISPLAY.BOARD: BCOLOR 1 ; background white FCOLOR 0 ; foreground black CRT 11 ; CURSOR #4,#4 ; TTYL DP1 ; CURSOR #5,#4 ; TTYL DP2 ; CURSOR #6,#4 ; TTYL DP1 ; CURSOR #7,#4 ; TTYL DP2 ; CURSOR #8.,#4 ; TTYL DP1 ; CURSOR #9.,#4 ; TTYL DP2 ; CURSOR #10.,#4 ; TTYL DP1 ; CURSOR #11.,#4 ; TTYL DP2 ; CURSOR #12.,#4 ; TTYL DP1 ; CURSOR #13.,#4 ; TTYL DP2 ; CURSOR #14.,#4 ; TTYL DP1 ; CURSOR #15.,#4 ; TTYL DP2 ; CURSOR #16.,#4 ; TTYL DP1 ; CURSOR #17.,#4 ; TTYL DP2 ; CURSOR #18.,#4 ; TTYL DP1 ; CURSOR #19.,#4 ; TTYL DP2 ; CURSOR #20.,#4 ; TTYL DP1 ; CRT 12 ; high intensity LEA A0,BOARD+10.(A5) ; index board, skip first row MOV #8.,D2 ; set loop count of 8 rows MOV #5,D4 ; set starting screen row of 5 ;execute this for each row 10$: MOV #8.,D3 ; set loop count of 8 columns INC A0 ; bypass border square MOV #6,D5 ; set starting screen column to 6 20$: MOVB (A0)+,D0 ; get square value BEQ 60$ ; empty BMI 30$ ; black piece CURSOR D4,D5 ; white piece - position cursor BCOLOR 0 ; background black FCOLOR 1 ; foreground white TYPE W ; and say W BR 40$ ; 30$: CURSOR D4,D5 ; black piece - position cursor BCOLOR 1 ; background white FCOLOR 0 ; foreground black TYPE B ; and say W 40$: AND #177,D0 ; MOVB #'P,D1 ; CMPB D0,#1 ; BEQ 50$ ; MOVB #'R,D1 ; CMPB D0,#5 ; BEQ 50$ ; MOVB #'N,D1 ; CMPB D0,#3 ; BEQ 50$ ; MOVB #'B,D1 ; CMPB D0,#4 ; BEQ 50$ ; MOVB #'Q,D1 ; CMPB D0,#9. ; BEQ 50$ ; MOVB #'K,D1 ; 50$: TTY ; 60$: ADD #5,D5 ; DEC D3 ; JNE 20$ ; INC A0 ; ADD #2,D4 ; DEC D2 ; JNE 10$ ; BCOLOR 1 ; background white FCOLOR 6 ; foreground green RTN ; DP1: ASCIZ "+----+----+----+----+----+----+----+----+" DP2: ASCIZ "| | | | | | | | |" EVEN ;******************* ;* DISPLAY.MOVES * ;******************* DISPLAY.MOVES: BCOLOR 4 ; background red FCOLOR 1 ; foreground white MOV #3,D2 ; MOV #20.,D3 ; LEA A0,MOVES(A5) ; LEA A1,MOVES+<20.*4>(A5) ; 10$: CURSOR D2,#59. ; MOV (A0)+,D1 ; BCALL 100$ ; CURSOR D2,#69. ; MOV (A1)+,D1 ; BCALL 100$ ; INCW D2 ; SOB D3,10$ ; BCOLOR 1 ; background white FCOLOR 6 ; foreground green RTN ; 100$: TST D1 ; BEQ 190$ ; ROL D1,#8. ; TTY ; ROL D1,#8. ; TTY ; ROL D1,#8. ; PUSH D1 ; CRT 11 ; TYPE - ; CRT 12 ; POP D1 ; TTY ; ROL D1,#8. ; TTY ; 190$: RTN ; ;*********** ;* INDEX * ;*********** ;Function: Given a reference, return index to board position ; ;Inputs: LOC(A5) - location to find (e.g. "a5) ; ;Outputs: A0 - index into BOARD(A5) ; D1 - piece type ; D0 - owner (0=white, 200=black) ; Z - set if we have an empty square INDEX: MOV #'h,D1 ; MOVB LOC(A5),D7 ; SUBB D7,D1 ; MUL D1,#10. ; LEA A0,BOARD+11.(A5) ; ADD D1,A0 ; CLR D1 ; MOVB LOC+1(A5),D1 ; SUBB #'1,D1 ; ADD D1,A0 ; CLR D0 ; MOVB @A0,D1 ; BPL 10$ ; MOVB #200,D0 ; AND #177,D1 ; 10$: TSTB D1 ; RTN ; ;**************** ;* MOVE.CHECK * ;**************** ;Function: Check validity of a move ; ;Inputs: A0 - location of "from" square ; A1 - location of "to" square ; D0 - owner color ; D1 - piece type ; ;Outputs: Z - set if move is legal ; cleared if move is illegal MOVE.CHECK: MOV D1,D7 ; AND #177,D7 ; CMPB D7,#PAWN ; JEQ MC.PAWN ; CMPB D7,#ROOK ; JEQ MC.ROOK ; CMPB D7,#BISHOP ; JEQ MC.BISHOP ; CMPB D7,#KNIGHT ; JEQ MC.KNIGHT ; CMPB D7,#KING ; JEQ MC.KING ; CMPB D7,#QUEEN ; JEQ MC.QUEEN ; JMP MC.ERR ; ;pawn MC.PAWN: TSTW PLAYER(A5) ; BEQ MC.PAWN.WHITE ; MC.PAWN.WHITE: BITW #F$COMP,FLAGS(A5) ; BNE MC.PAWN.BLACK2 ; MC.PAWN.WHITE2: MOV A0,A6 ; SUB #11.,A6 ; CMP A6,A1 ; JEQ MC.OK.CAPTURE ; MOV A0,A6 ; SUB #9.,A6 ; CMP A6,A1 ; JEQ MC.OK.CAPTURE ; MOV A0,A6 ; ADD #11.,A6 ; CMP A6,A1 ; JEQ MC.OK.CAPTURE ; MOV A0,A6 ; ADD #9.,A6 ; CMP A6,A1 ; JEQ MC.OK.CAPTURE ; MOV A0,A6 ; SUB #10.,A6 ; CMP A6,A1 ; JEQ MC.OK.EMPTY ; TSTB @A6 ; JNE MC.ERR ; SUB #10.,A6 ; CMP A6,A1 ; JEQ MC.OK.EMPTY ; JMP MC.ERR ; MC.PAWN.BLACK: BITW #F$COMP,FLAGS(A5) ; BNE MC.PAWN.WHITE2 ; MC.PAWN.BLACK2: MOV A0,A6 ; SUB #11.,A6 ; CMP A6,A1 ; JEQ MC.OK.CAPTURE ; MOV A0,A6 ; SUB #9.,A6 ; CMP A6,A1 ; JEQ MC.OK.CAPTURE ; MOV A0,A6 ; ADD #11.,A6 ; CMP A6,A1 ; JEQ MC.OK.CAPTURE ; MOV A0,A6 ; ADD #9.,A6 ; CMP A6,A1 ; JEQ MC.OK.CAPTURE ; MOV A0,A6 ; ADD #10.,A6 ; CMP A6,A1 ; JEQ MC.OK.EMPTY ; TSTB @A6 ; JNE MC.ERR ; ADD #10.,A6 ; CMP A6,A1 ; JEQ MC.OK.EMPTY ; JMP MC.ERR ; ;rook MC.ROOK: MOV A0,A6 ; MOV #7,D6 ; 10$: ADD #10.,A6 ; CMP A6,A1 ; JEQ MC.OK ; TSTB @A6 ; BNE 15$ ; SOB D6,10$ ; 15$: MOV A0,A6 ; MOV #7,D6 ; 20$: SUB #10.,A6 ; CMP A6,A1 ; JEQ MC.OK ; TSTB @A6 ; BNE 25$ ; SOB D6,20$ ; 25$: MOV A0,A6 ; MOV #7,D6 ; 30$: DEC A6 ; CMP A6,A1 ; JEQ MC.OK ; TSTB @A6 ; BNE 35$ ; SOB D6,30$ ; 35$: MOV A0,A6 ; MOV #7,D6 ; 40$: INC A6 ; CMP A6,A1 ; JEQ MC.OK ; TSTB @A6 ; BNE 45$ ; SOB D6,40$ ; 45$: JMP MC.ERR ; ;bishop MC.BISHOP: MOV A0,A6 ; MOV #7,D6 ; 10$: SUB #9.,A6 ; CMP A6,A1 ; JEQ MC.OK ; TSTB @A6 ; BNE 15$ ; SOB D6,10$ ; 15$: MOV A0,A6 ; MOV #7,D6 ; 20$: SUB #11.,A6 ; CMP A6,A1 ; JEQ MC.OK ; TSTB @A6 ; BNE 25$ ; SOB D6,20$ ; 25$: MOV A0,A6 ; MOV #7,D6 ; 30$: ADD #9.,A6 ; CMP A6,A1 ; JEQ MC.OK ; TSTB @A6 ; BNE 35$ ; SOB D6,30$ ; 35$: MOV A0,A6 ; MOV #7,D6 ; 40$: ADD #11.,A6 ; CMP A6,A1 ; JEQ MC.OK ; TSTB @A6 ; BNE 45$ ; SOB D6,40$ ; 45$: JMP MC.ERR ; ;knight MC.KNIGHT: MOV A0,A6 ; SUB #12.,A6 ; CMP A6,A1 JEQ MC.OK ; MOV A0,A6 ; SUB #8.,A6 ; CMP A6,A1 JEQ MC.OK ; MOV A0,A6 ; ADD #12.,A6 ; CMP A6,A1 JEQ MC.OK ; MOV A0,A6 ; ADD #12.,A6 ; CMP A6,A1 JEQ MC.OK ; MOV A0,A6 ; SUB #19.,A6 ; CMP A6,A1 JEQ MC.OK ; MOV A0,A6 ; SUB #21.,A6 ; CMP A6,A1 JEQ MC.OK ; MOV A0,A6 ; ADD #19.,A6 ; CMP A6,A1 JEQ MC.OK ; MOV A0,A6 ; ADD #21.,A6 ; CMP A6,A1 JEQ MC.OK ; JMP MC.ERR ; ;king MC.KING: MOV A0,A6 ; SUB #9.,A6 ; CMP A6,A1 ; JEQ MC.OK ; MOV A0,A6 ; SUB #10.,A6 ; CMP A6,A1 ; JEQ MC.OK ; MOV A0,A6 ; SUB #11.,A6 ; CMP A6,A1 ; JEQ MC.OK ; MOV A0,A6 ; ADD #9.,A6 ; CMP A6,A1 ; JEQ MC.OK ; MOV A0,A6 ; ADD #10.,A6 ; CMP A6,A1 ; JEQ MC.OK ; MOV A0,A6 ; ADD #11.,A6 ; CMP A6,A1 ; JEQ MC.OK ; MOV A0,A6 ; INC A6 ; CMP A6,A1 ; JEQ MC.OK ; MOV A0,A6 ; DEC A6 ; CMP A6,A1 ; JEQ MC.OK ; JMP MC.ERR ; ;queen MC.QUEEN: MOV A0,A6 ; MOV #7,D6 ; 10$: SUB #9.,A6 ; CMP A6,A1 ; JEQ MC.OK ; TSTB @A6 ; BNE 15$ ; SOB D6,10$ ; 15$: MOV A0,A6 ; MOV #7,D6 ; 20$: SUB #10.,A6 ; CMP A6,A1 ; JEQ MC.OK ; TSTB @A6 ; BNE 25$ ; SOB D6,20$ ; 25$: MOV A0,A6 ; MOV #7,D6 ; 30$: SUB #11.,A6 ; CMP A6,A1 ; JEQ MC.OK ; TSTB @A6 ; BNE 35$ ; SOB D6,30$ ; 35$: MOV A0,A6 ; MOV #7,D6 ; 40$: ADD #9.,A6 ; CMP A6,A1 ; JEQ MC.OK ; TSTB @A6 ; BNE 45$ ; SOB D6,40$ ; 45$: MOV A0,A6 ; MOV #7,D6 ; 50$: ADD #10.,A6 ; CMP A6,A1 ; JEQ MC.OK ; TSTB @A6 ; BNE 55$ ; SOB D6,50$ ; 55$: MOV A0,A6 ; MOV #7,D6 ; 60$: ADD #11.,A6 ; CMP A6,A1 ; JEQ MC.OK ; TSTB @A6 ; BNE 65$ ; SOB D6,60$ ; 65$: MOV A0,A6 ; MOV #7,D6 ; 70$: INC A6 ; CMP A6,A1 ; JEQ MC.OK ; TSTB @A6 ; BNE 75$ ; SOB D6,70$ ; 75$: MOV A0,A6 ; MOV #7,D6 ; 80$: DEC A6 ; CMP A6,A1 ; JEQ MC.OK ; TSTB @A6 ; BNE 85$ ; SOB D6,80$ ; 85$: JMP MC.ERR ; ;come here if move is technically okay, but only if destination square ;is empty MC.OK.EMPTY: TSTB @A1 ; BNE MC.ERR ; BR MC.OK ; ;come here if move is technically okay, but only if destination square ;is a capture MC.OK.CAPTURE: BITW #F$COMP,FLAGS(A5) ; BEQ MC.OK.CAPTURE.HUMAN ; MC.OK.CAPTURE.COMP: MOVB @A1,D7 ; BEQ MC.ERR ; BMI 10$ ; TSTW PLAYER(A5) ; piece is white - are we black? BEQ MC.OK ; yes - okay to make move BR MC.ERR ; 10$: TSTW PLAYER(A5) ; piece is black - are we white? BEQ MC.ERR ; no - don't make move BR MC.OK ; MC.OK.CAPTURE.HUMAN: MOVB @A1,D7 ; BEQ MC.ERR ; BMI 10$ ; TSTW PLAYER(A5) ; piece is white - are we black? BNE MC.OK ; yes - okay to make move BR MC.ERR ; 10$: TSTW PLAYER(A5) ; piece is black - are we white? BNE MC.ERR ; no - don't make move MC.OK: LCC #PS.Z ; set Z (legal move) RTN ; return MC.ERR: LCC #0 ; clear Z (illegal move) RTN ; return ;**************** ;* FIND.MOVES * ;**************** ;Function: Find valid move(s) ; ;Inputs: A0 - location of "from square" ; ;Outputs: A1 - square to move to FIND.MOVES: SAVE A0,D4-D5 ; LEA A1,BOARD+11.(A5) ; MOV #8.,D4 ; 10$: MOV #8.,D5 ; 20$: TSTB @A1 ; JEQ 40$ ; TSTW PLAYER(A5) ; what color is player? BEQ 22$ ; player is white - comp is black ;player is black, computer is white TSTB @A1 ; is piece here black? BMI 40$ ; yes - fair game BR 30$ ; no - we can't take our own piece ;player is white, computer is black 22$: TSTB @A1 ; is piece here white? BPL 40$ ; yes - fair game ;look at next "to" square 30$: INC A1 ; SOB D5,20$ ; ADD #2,A1 ; SOB D4,10$ ; REST A0,D4-D5 ; RTN ; ;we have a potential move; see if it's okay or now 40$: CALL EVALUATE.MOVE ; BR 30$ ; EVALUATE.MOVE: SAVE A1,D0-D5 ; MOV #200,D0 ; CLR D7 ; MOVW PLAYER(A5),D7 ; SUB D7,D0 ; set D0 to computer's color CALL MOVE.CHECK ; JNE EM.RTN ; MOVW #100.,VALUE(A5) ; dummy value of move for now LEA A6,BOARD(A5) ; ADD #44.,A6 ; CMP A6,A1 ; BEQ 41$ ; INC A6 ; CMP A1,A6 ; BEQ 41$ ; LEA A6,BOARD(A5) ; ADD #54.,A6 ; CMP A6,A1 ; BEQ 41$ ; INC A6 ; CMP A1,A6 ; BNE 410$ ; 41$: INCW VALUE(A5) ; add 1 for four central squares ;factor capture into score value 410$: MOVB @A1,D1 ; will we capture anything? BEQ 42$ ; no AND #177,D1 ; keep just the value ADDW D1,VALUE(A5) ; factor capture into value 42$: ;if piece we are to move is our king, subtract two so that we'll be ;reluctant to move it unless we really need to MOVB @A0,D7 ; AND #177,D7 ; CMPB D7,#KING ; BNE 420$ ; SUBW #2,VALUE(A5) ; 420$: ;All righty. we've got a valid move, and have assigned it an initial ;value. To do a good job of value assignment, though, we have to assess ;our threat situation. What we have to do is this: ; ; 1. Save the entire board ; 2. Make this potential move on the board ; 3. Count up threats from the human and subtract them from our value ; 4. Restore the board ;save the board SAVE A0-A1,D0 ; LEA A0,BOARD(A5) ; LEA A1,SAVBRD(A5) ; MOV #10.*10.,D0 ; 421$: MOVB (A0)+,(A1)+ ; SOB D0,421$ ; REST A0-A1,D0 ; ;make our potential move MOVB @A0,@A1 ; CLRB @A0 ; ;count threats SAVE A0-A5,D0-D4 ; CLR D5 ; clear threat count LEA A1,BOARD+11.(A5) ; MOV #8.,D2 ; 100$: MOV #8.,D3 ; 110$: MOVB @A1,D1 ; BEQ 120$ ; TSTW PLAYER(A5) ; is player black or white? BEQ 112$ ; white ;player is black - is this a white (vulnerable) piece? TSTB D1 ; BMI 120$ ; not vulnerable BR 115$ ; ;player is white - is this a black (vulnerable) piece? 112$: TSTB D1 ; BPL 120$ ; not vulnerable ;this is a vulnerable piece - assess threat situation 115$: CALL COUNT.THREATS ; count threats on this square ;on to next square 120$: INC A1 ; SOB D3,110$ ; ADD #2,A1 ; SOB D2,100$ ; REST A0-A5,D0-D4 ; ;at this point, D5 contains threat count ADD D5,D5 ; double threat count ;check if we're talking about our king here ;if so, multiply threat count by 100 MOV @A0,D7 ; AND #177,D7 ; CMPB D7,#10. ; BNE 121$ ; MUL D5,#100. ; 121$: CMPW D5,VALUE(A5) ; is threat count > total value? BHIS 122$ ; yes SUBW D5,VALUE(A5) ; BR 124$ ; 122$: MOVW #1,VALUE(A5) ; leave value of just 1 124$: ;restore the board SAVE A0-A1,D0 ; LEA A0,SAVBRD(A5) ; LEA A1,BOARD(A5) ; MOV #10.*10.,D0 ; 130$: MOVB (A0)+,(A1)+ ; SOB D0,130$ ; REST A0-A1,D0 ; ;we have a valid move - add to the move list TSTW MOVE.COUNT(A5) ; BEQ 47$ ; CMPW MOVE.COUNT(A5),#MOVMAX ; BLT 47$ ; SUB #MOVSIZ,A4 ; BR 49$ ; 47$: INCW MOVE.COUNT(A5) ; update move list array size count 49$: MOV A0,MOVFRM(A4) ; store from square index MOV A1,MOVTO(A4) ; store to square index MOVW VALUE(A5),D1 ; get value MOVW D1,MOVVAL(A4) ; store value in move list entry TSTW MOVE.VALUE(A5) ; BEQ 491$ ; CMPW D1,MOVE.VALUE(A5) ; new high value? BLOS 50$ ; no 491$: MOVW D1,MOVE.VALUE(A5) ; yes 50$: ADD #MOVSIZ,A4 ; EM.RTN: REST A1,D0-D5 ; RTN ; ;count threats ;add into D5 threat point count to square A1 COUNT.THREATS: SAVE A0,D1-D3 ; PUSHW FLAGS(A5) ; ANDW #^C,FLAGS(A5) ; LEA A0,BOARD+11.(A5) ; MOV #8.,D2 ; 10$: MOV #8.,D3 ; 20$: MOVB @A0,D1 ; BEQ 30$ ; TSTW PLAYER(A5) ; is player black or white? BEQ 22$ ; white ;player is black TSTB D1 ; is this a black piece? BMI 25$ ; yes BR 30$ ; no ;player is white 22$: TSTB D1 ; is this a white piece? BMI 30$ ; no ;this is a player piece - see if it can attack square A0 25$: CALL MOVE.CHECK ; valid move? BNE 30$ ; no MOVB @A1,D1 ; AND #177,D1 ; ADD D1,D5 ; 30$: INC A0 ; SOB D3,20$ ; ADD #2,A0 ; SOB D2,10$ ; POPW FLAGS(A5) ; REST A0,D1-D3 ; RTN ; ;********************* ;* GET.COORDINATES * ;********************* ;Function: Given an index into the board, return the "a1" style ; coordinates ; ;Inputs: A0 - index into board ; ;Outputs: D1 - coordinates GET.COORDINATES: SAVE D2-D5 ; LEA A6,BOARD+11.(A5) ; MOVB #'h,D2 ; MOV #8.,D4 ; 10$: MOV #8.,D5 ; MOVB #'1,D3 ; 20$: CMP A6,A0 ; BEQ 80$ ; INC A6 ; INCB D3 ; SOB D5,20$ ; DECB D2 ; ADD #2,A6 ; SOB D4,10$ ; CLR D1 ; BR 90$ ; 80$: CLR D1 MOVB D2,D1 ; ROL D1,#8. ; MOVB D3,D1 ; 90$: REST D2-D5 ; RTN ; ;******************** ;* SHOW.MOVE.LIST * ;******************** ;Function: Display move list SHOW.MOVE.LIST: SAVE A0-A5,D0-D5 ; CURSOR #3,#1 ; CRT 10 ; TYPE Move List ; CURSOR #3,#15. ; CLR D1 ; MOVW MOVE.COUNT(A5),D1 ; DCVT 0,OT$TRM!OT$TSP ; PUSH D1 ; CRT 11 ; POP D1 ; TYPE move ; CMPW D1,#1 ; BEQ 10$ ; TYPE s ; 10$: TYPE < generated> ; CRT 12 ; MOV #5,D2 ; set row MOV #1,D3 ; CLR D5 ; MOVW MOVE.COUNT(A5),D5 ; LEA A4,MOVE.LIST(A5) ; 20$: CURSOR D2,D3 ; MOV MOVFRM(A4),A0 ; CALL GET.COORDINATES ; RORW D1,#8. ; TTY ; ROLW D1,#8. ; TTY ; CRT 11 ; TYPE - ; CRT 12 ; MOV MOVTO(A4),A0 ; CALL GET.COORDINATES ; RORW D1,#8. ; TTY ; ROLW D1,#8. TTY ; TYPESP ; CLR D1 ; MOVW MOVVAL(A4),D1 ; DCVT 4,OT$TRM!OT$ZER ; ADD #MOVSIZ,A4 ; DEC D5 ; JEQ SMLGET ; INCW D2 ; CMPW D2,#23. ; BLE 20$ ; MOV #5,D2 ; ADD #12.,D3 ; CMP D3,#70. ; BLE 20$ ; SMLGET: CRT 11 ; CURSOR #24.,#1 ; TYPESP Press any key to resume play: CRT 12 ; TIN ; CALL DISPLAY.SCREEN ; CALL DISPLAY.BOARD ; CALL DISPLAY.MOVES ; REST A0-A5,D0-D5 ; RTN ; ;**************** ;* PIECE.NAME * ;**************** ;Function: Display piece name ; ;Inputs: D0 - piece value PIECE.NAME: CMPB D0,#PAWN ; BEQ PN.PAWN ; CMPB D0,#KNIGHT ; JEQ PN.KNIGHT ; CMPB D0,#BISHOP ; JEQ PN.BISHOP ; CMPB D0,#ROOK ; JEQ PN.ROOK ; CMPB D0,#QUEEN ; JEQ PN.QUEEN ; CMPB D0,#KING ; JEQ PN.KING ; RTN ; PN.PAWN: TYPE pawn ; RTN ; PN.KNIGHT: TYPE knight ; RTN ; PN.BISHOP: TYPE bishop ; RTN ; PN.ROOK: TYPE rook ; RTN ; PN.KING: TYPE king ; RTN ; PN.QUEEN: TYPE queen ; RTN ; END .