; ; ALL CHANGES MADE BY BDN ARE MARKED WITH A *@ SEQ. ; ; .TITLE RT-11 CHESS PROGRAM .SBTTL DEDICATION ; THIS IS THE RT11 CHESS PROGRAM WRITTEN BY HANK MAURER. ; INSPIRED BY CHEKMO-II, A PDP-8 CHESS PROGRAM WRITTEN BY ; JOHN COMEAU. .SBTTL DEFINITIONS .NLIST BEX ;DON'T LIST EXTRA WORDS ; .NLIST CND ;DON'T LIST UNASSEMBLED CONDITIONALS ;PIECE INDICES EMPTY=0 PAWN=2 KNIGHT=4 BISHOP=6 ROOK=8. QUEEN=10. KING=12. OFF=14. ;PIECE VALUES ONE=128. ;BASE VALUE PVALUE=ONE NVALUE=3*ONE+ BVALUE=3*ONE+ RVALUE=5*ONE QVALUE=9.*ONE KVALUE=15.*ONE ;PSW BIT SETTINGS QRMOVD=1000 KRMOVD=2000 NOCAS=3000 CASTLD=1 ;MDW BIT SETTINGS CAPTUR=100000 QSCAS=1 KSCAS=2 ENPASS=3 PROMN=4 PROMB=5 PROMR=6 PROMQ=7 ;COLORS WHITE=0 BLACK=100000 ;STATIC BOARD EVALUATOR PARAMETERS MD=4. ;MINOR PIECE DEVELOPEMENT BONUS QH=25. ;QUEEN WITHIN ONE SQUARE OF HOME CC=4. ;CENTER SQUARE CONTROLLED CO=4. ;CENTER SQUARE OCCUPIED OO=8. ;CASTLED BONUS PP=8. ;PAWN PUSH BONUS RB=9. ;TRADING WHILE AHEAD BONUS KD=7. ;KING TO KING DISTANCE REDUCTION BONUS KB=6. ;KING MOVES BLOCKED BY CHECK (EACH) MP=4. ;MAJOR PINNED PIECES (EACH) HPF=15. ;HANGING PIECE FACTOR (VALUE*HPF/(HPF+1)) ;HPF MUST ALWAYS BE 2**N-1 HPB=8. ;BONUS FOR EACH EXTRA HANGING PIECE MAXD=7. ;ABSOLUTE MAXIMUM LOOK AHEAD DEPTH DEFD=2. ;DEFAULT DEPTH SETTING DEFW=10. ;DEFAULT WIDTH SETTING EMAX=1. ;MAXIMUM EXTENSION OF LOOK AHEAD HPEXT=/ ;HANGING PIECE BONUS EXTEND THRESHOLD OPNING=7. ;ELIMINATE OPENING EVALUATIONS AFTER 7. MOVES ENDGAM=10. ;ENTER ENDGAME MODE IF LT 10. PIECES REMAINING DEFT=7200. ;DEFAULT CLOCK SETTING PIND=PINLST-QLIST ;OFFSET FROM MOVE DIRECTION LIST TO PIN DIRECTION LIST RANK=RFB-BOARD-42. ;OFFSET FROM BOARD TO RANK NUMBER FILE=RFB-BOARD-41. ;OFFSET FROM BOARD TO FILE NUMBER PINS=PINBRD-BOARD-42. ;OFFSET FROM BOARD TO PIN BOARD LVA=AB-BOARD ;OFFSET FROM BOARD TO ATTACKER BOARD LVD=DB-BOARD ;OFFSET FROM BOARD TO DEFENDER BOARD AC=LVA+1 ;OFFSET FROM BOARD TO ATTACK COUNT BOARD DC=LVD+1 ;OFFSET FROM BOARD TO DEFENCE COUNT BOARD PWNVAL=PVB-BOARD-42. ;OFFSET FROM BOARD TO PAWN PUSH BOARD IOBD=IOBORD-BOARD-42. ;OFFSET FROM BOARD TO IO BOARD P.B1=200 ;PIN DIRECTION BIT SETTINGS P.B2=100 P.B3=40 P.B4=20 P.R1=10 P.R2=4 P.R3=2 P.R4=1 P.B=360 P.R=17 P.Q=377 CK.BLK=400 ;CHECK BLOCKING BIT R0=%0 ;REGISTER DEFINITIONS R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 ;CONDITIONAL ASSEMBLY SWITCHES TREE=1 ;ENABLE TREE OUTPUT TIMER=0 ;ENABLE TIMER STATS=1 ;ENABLE STATISTICS GT40=0 ;ENABLE GT40 SUPPORT BOOKOP=0 ;ENABLE BOOK OPENINGS HISTOG=0 ;DISABLE HISTOGRAM CODE THINKA=0 ;ENABLE THINK AHEAD FEATURE SOLO=0 ;STAND ALONE VERSION .IF NE,SOLO TREE=0 TIMER=0 STATS=0 BOOKOP=0 HISTOG=0 .ENDC .SBTTL MACRO DEFINITIONS .MCALL DIR$,GTIM$S,WTSE$S,CLEF$S,QIO$,EXIT$S .IF NE,BOOKOP .ENDC .MACRO SAVE JSR R0,SAV0T5 .ENDM .MACRO CALL X JSR PC,X .ENDM .MACRO .PRINT X MOV X,R1 JSR PC,PRINT .ENDM .MACRO .ASCIM X .ASCII "X" .BYTE 377 .ENDM .MACRO IMULI COUNT,ADDR T.VAL=COUNT .IF EQ T.VAL CLR ADDR .IFF .IF LT T.VAL T.VAL=-T.VAL NEG ADDR .ENDC T.FLAG=0 T.MASK=040000 .REPT ^D14 .IF LE T.MASK-T.VAL .IF NE T.MASK&T.VAL .IF NE T.MASK-T.VAL .IF EQ T.FLAG MOV ADDR,-(SP) T.FLAG=1 .IFF .IF NE T.MASK-1&T.VAL ADD (SP),ADDR .IFF ADD (SP)+,ADDR T.FLAG=0 .ENDC .ENDC .ENDC .ENDC ASL ADDR .ENDC T.MASK=T.MASK/2 .ENDR .IF NE T.FLAG ADD (SP)+,ADDR .ENDC .ENDC .ENDM .MACRO IDIVI COUNT,ADDR T.VAL=COUNT .REPT ^D14 .IF NE,T.VAL-1 ASR ADDR T.VAL=T.VAL/2 .ENDC .ENDR .ENDM .SBTTL COMMAND INPUT .CSECT .BLKW 10. START: .IF NE,SOLO CLR @#54 ;FUDGE RMON POINTER MOV #4,@#300 ;AND CONFIG WORD CLR @#302 ;AND SCROLLER POINTER CLR LSTAT ;CLEAR LINE STATUS MOV #INBUF,BUFPTR ;RESET BUFFER POINTER CLRB @#177566 ;GET CHAR FLAG UP .ENDC CALL COMRE ;RESET THE GAME STATUS .IF NE,GT40 .GLOBL DISPLAY,DSTART,DSTOP,BTOP,WTOP,BOARD CALL DSTART ;DISPLAY INITIAL BOARD .ENDC .PRINT #VERSON ;PRINT THE VERSION NUMBER .IF NE,HISTOG CALL HISTON ;START UP THE HISTOGRAM CLOCK .ENDC COMMAN: MOV #STACK,SP ;SET UP STACK POINTERS CALL PROMPT ;CALL PROMPTER/MESSAGE OUTPUTTER WHOGOS: MOV #MOVES,R5 ;RESET MOVE STACK POINTER TST WHOSE ;SEE WHO MOVES BNE 30$ ;BLACK TST WHOWHI ;WHO IS PLAYING WHITE ? BNE CMOVE ;THE MACHINE BR USER ;THE USER 30$: TST WHOBLK ;WHO IS PLAYING BLACK ?? BNE CMOVE ;THE MACHINE ;THE USER ; GET THE USER'S INPUT (MOVE OR COMMAND) USER: CALL GETC ;GET THE USER'S FIRST CHARACTER MOV R0,R1 ;SAVE IT IN R1 CALL GETC ;GET THE SECOND CHARACTER SWAB R0 ;PUT 'EM TOGETHER BIS R1,R0 MOV R0,CHRONE ;AND SAVE 'EM MOV #COMLST,R1 ;ADDRESS OF THE COMMAND LIST 10$: MOV (R1)+,R2 ;GET NEXT COMMAND BEQ 20$ ;NO MORE, ASSUME MOVE WAS INPUT CMP R0,R2 ;IS IT THIS COMMAND ? BNE 10$ ;NO, TRY NEXT ONE 20$: JSR PC,@COMADR-COMLST-2(R1) ;CALL THE COMMAND PROCESSOR .IF NE,GT40 CALL DISPLAY ;SHOW NEW BOARD .ENDC CALL FLUSH ;FLUSH UNTIL END OF LINE BR COMMAN .SBTTL COMPUTER MOVE SELECTION ; COMPUTER MOVE SELECTION CMOVE: CALL GETCX ;SEE IF THERE IS A COMMAND BCC USER ;CHAR WAS THERE, GO SEE WHAT THE USER WANTS .IF NE,BOOKOP ; BOOK OPENINGS TST BOOK ;IS THE BOOK CLOSED ? BMI BKOVER ;YES CALL READ ;READ IN OPPONENT'S LIST OF POSSIBLE LAST MOVES MOV (R1)+,R4 ;COUNT ADD #6,R1 10$: MOV R1,R0 ;SAVE START CMP (R0)+,BKFROM ;FIND LAST MOVE MADE BY OPONENT BNE 30$ CMP (R0)+,BKTO BNE 30$ CMP (R0)+,BKMDW BNE 30$ MOV (R0)+,BOOK ;BLOCK NUMBER OF OUR RESPONSES BMI BKOVER ;END OF BOOK CALL READ ;GET OUR RESPONSES ADD #8.,R1 ;SKIP COUNT MOV (R1)+,R3 ;USE FIRST RESPONSE MOV (R1)+,R2 MOV (R1)+,MVMDW CMP WHOWHI,WHOBLK ;IS HUMAN PLAYING OTHER SIDE ? BEQ 24$ ;NO, DON'T SKIP ANYTHING MOV (R1)+,BOOK ;OK, GET BLK NUM OF HUMAN'S POSSIBLE MOVES 24$: CALL OUTMV ;PRINT IT CALL OCRLF ;CR/LF .IF NE,TIMER MOV WHOSE,IOWHO ;CLOCK THE MOVE CALL CLOKIT .ENDC CALL MKMV ;MAKE OUR MOVE .IF NE,GT40 CALL DISPLAY ;SHOW THE MOVE .ENDC .IF NE,GT40 CALL DISPLAY ;SHOW MOVE .ENDC JMP COMMAN ;START AGAIN 30$: ADD #8.,R1 ;BUMP POINTER DEC R4 ;MORE ? BNE 10$ MOV #-1,BOOK ;CLOSE THE BOOK BKOVER: .ENDC .IF NE,TREE TST DEBUG ;DEBUG MODE ? BEQ 10$ ;NO INC LPT ;OUTPUT TO LPT MOV #14,R0 ;OUTPUT TOP OF FORMS CALL OUTC CALL DISPLY ;PRINT POSITION BEING EVALUATED CLR LPT 10$: .ENDC ; KILL LOOKAHEAD IF FORCED MOVE MOV DEPTH,-(SP) ;SAVE THE DEPTH (IN CASE WE CHANGE IT) INC BOGUS ;GET THE MOVER'S MOVE COUNT CALL GNMVSM ;GENERATE THE MOVES BUT DON'T SAVE 'EM CMP GNCNT,#1 ;ONLY ONE POSSIBLE MOVE ? BGT 20$ ;NO, MORE MOV #1,DEPTH ;YES, SET DEPTH = 1 TO FORCE MOVE CLR MDEPTH ;PREVENT ANY LOOKAHEAD EXTENSIONS ; PICK MACHINE'S NEXT MOVE (USE PRE-CALCULATED MOVE IF POSSIBLE) 20$: .IF NE,THINKA TST IKNEW ;DID WE GUESS RIGHT LAST TIME ? BNE 25$ ;YES, USE PRE-CALCULATED MOVE .ENDC CALL LOOK ;DO THE FULL ANALYSIS .IF NE,THINKA 25$: CLR IKNEW ;CLEAR THE "RIGHT GUESS" SWITCH .ENDC ; MAKE THE "BEST" MOVE FOUND (EITHER NOW OR BEFORE) MOV BSTFRM,R3 ;GET THE BEST MOVE AT PLY 0 MOV BSTTO,R2 MOV BSTMDW,MVMDW .IF NE,TREE TST DEBUG ;ARE WE IN DEBUG MODE ? BEQ 30$ ;NO INC LPT ;YES, SET LP OUTPUT SWITCH CALL OUTMV ;OUTPUT THE CHOSEN MOVE CALL OCRLF ;END OF LINE .IF NE,STATS CALL COMPS ;PRINT THE STATISTICS .ENDC CLR LPT ;CLEAR THE LP OUTPUT SWITCH 30$: .ENDC CALL OUTMV ;TELL THE USER WHAT IT WAS CALL OCRLF ;END OF LINE .IF NE,TIMER MOV WHOSE,IOWHO ;CHARGE TIME TO MACHINE CALL CLOKIT ;AND PUNCH THE CLOCK .ENDC CALL MKMV ;MAKE THE "BEST" MOVE ADD #MKMVX,SP ;PURGE STUFF LEFT BY MKMV CALL DISPLY ; TEMP CHANGE *@ CALL PROMPT ;PRINT PROMPTER AGAIN (ALSO CM/SM TEST) .IF NE,GT40 CALL DISPLAY ;DISPLAY NEW BOARD .ENDC MOV (SP),MDEPTH ;RESTORE MAX DEPTH ADD #EMAX,MDEPTH .IF NE,THINKA ; THINK-AHEAD SECTION, GUESS USER'S NEXT MOVE AND CALCULATE RESPONSE CMP WHOWHI,WHOBLK ;IS THE MACHINE PLAYING BOTH SIDES ? BEQ 35$ ;YES, DON'T THINK AHEAD CMP DEPTH,#1 ;WAS DEPTH ONE ? BEQ 35$ ;YES, NO VALID MOVE CALL INMVSU ;SET UP STUFF FOR MOVE INPUT MOV (SP),DEPTH ;RESTORE DEPTH MOV THINKF+2,R3 ;GET THE OPPONENT'S MOST LIKELY RESPONSE MOV THINKT+2,R2 ;WHICH WE WILL MAKE AND THEN MOV THINKM+2,MVMDW ;ATTEMPT TO THINK-AHEAD ABOUT MOV R3,THINKF ;ALSO SAVE THIS MOVE SINCE MOV R2,THINKT ;CALLING LOOK WILL CHANGE IT MOV MVMDW,THINKM ;(I.E. GETS THE NEXT RESPONSE) CALL MKMV INC THINK ;SET THE THINKING AHEAD SWITCH CALL LOOK ;ANALYZE AHEAD OF OPPONENT CLR THINK ;NOW CLEAR THAT SWITCH TST IKNEW ;DID USER INPUT THE GUESSED MOVE ? BNE 38$ ;YES, DON'T UNMAKE IT MOV THINKF,R3 ;RESTORE THE GUESSED MOVE MOV THINKT,R2 MOV THINKM,MVMDW CALL UNMV ;AND UNMAKE IT TST REXIT ;REASON FOR EXIT ? BEQ 40$ ;FINISHED 35$: CLR THINKF ;EXPRESS EXIT, FORGET THE GUESSED MOVE TST REXIT ;WHAT DID HE TYPE ? BPL 40$ ;A COMMAND, GO DO IT MOV IOFROM,R3 ;A NON-GUESSED MOVE MOV IOTO,R2 ;SO DO IT MOV IOMDW,MVMDW CALL MKMV 38$: .IF NE,GT40 CALL DISPLAY ;SHOW USER HIS MOVE .ENDC MOV MKMVX(SP),DEPTH ;RESTORE DEPTH JMP COMMAN ;GO BACK TO PROMPT .ENDC 40$: MOV (SP)+,DEPTH ;RESTORE DEPTH JMP WHOGOS ; PROMPT INPUT PROMPT: INC DOMAP ;PIECE MAP NECESSARY INC BOGUS ;DON'T WANT THE MOVES, JUST THE INFO CALL GNMVSM ;GENERATE MOVES FOR THE SIDE TO MOVE TST GNCHEK ;IS HIS KING IN CHECK ? BEQ 5$ ;NO .PRINT #CHECK ;YES, PRINT CHECK MESSAGE 5$: TST GNCNT ;ANY ? BNE 24$ ;YES, WHO IS TO MOVE ? TST GNCHEK ;CHECKMATE ? BEQ 20$ ;NO .PRINT #CMATE ;YES, PRINT MESSAGE 10$: .IF NE,GT40 CALL DISPLAY ;SHOW FINAL BOARD .ENDC CALL DISPLY ;PRINT FINAL BOARD CALL COMRE ;RESET ALL .IF NE,GT40 CALL DISPLAY ;SHOW RE-INITIALIZED BOARD .ENDC JMP COMMAN ;START AGAIN 20$: .PRINT #SMATE ;STALEMATE BR 10$ 24$: TST WHOSE ;WHO MOVES ? BEQ 25$ ;WHITE .PRINT #BDOT ;BLACK, PRINT B. .IF NE,TIMER MOV CLOCKB,R0 ;GET BLACK'S CLOCK BR 26$ .IFF RTS PC .ENDC 25$: .PRINT #WDOT ;WHITE, PRINT W. .IF NE,TIMER MOV CLOCKW,R0 ;GET WHITE'S CLOCK 26$: BPL 27$ ;FLAG STILL UP .PRINT #FLAG ;PRINT FLAG FALLEN MESSAGE BR 10$ ;WHITE LOSES 27$: CMP R0,WARNT ;TIME FOR A WARNING ? BGT 28$ ;NO CALL OUTVAL ;YES, OUTPUT HIS CLOCK MOV #' ,R0 ;AND A SPACE CALL OUTC 28$: .ENDC RTS PC ;RETURN .IF NE,TIMER ; TIME MOVE AND FLIP CLOCK CLOKIT: CALL TIME ;GET TIME SINCE LAST CALL TST IOWHO ;WHO USED IT ? BPL 10$ ;WHITE SUB R0,CLOCKB ;BLACK, DECREASE HIS CLOCK MOV R0,CLOCKB+2 ;SAVE LAST MOVE TIME RTS PC 10$: SUB R0,CLOCKW ;DECREASE WHITE'S CLOCK MOV R0,CLOCKW+2 ;SAVE HIS LAST MOVE TIME RTS PC .ENDC .SBTTL COMMAND PROCESSORS ; RESET GAME COMRE: CALL OCRLF ;RETURN THE CARRIAGE CLR WHOSE ;CLEAR THE "WHOSE MOVE IS IT" SWITCH MOV #120.,R0 ;COPY THE SAVED BOARD MOV #BOARD,R1 ;INTO THE WORKING BOARD MOV #SAVBRD,R2 ;INCLUDING THE BORDER SQUARES 10$: MOV (R2)+,(R1)+ DEC R0 BNE 10$ ;MORE SQUARES CLR LSTMV ;CLEAR SOME THINGS CLR WPSW CLR BPSW CLR PW CLR MOVE MOV #32.,NPIECS ;INITIALLY 32. PIECES MOV #DEFD,DEPTH ;SET THE DEFAULT DEPTHS MOV #DEFD+EMAX,MDEPTH MOV #MAXD,R0 ;NUMBER OF WIDTHS TO SET MOV #WIDTH,R1 ;ADDRESS OF WIDTH TABLE 2$: MOVB #DEFW,(R1)+ ;SET THE DEFAULT WIDTHS DEC R0 BNE 2$ CLRB (R1)+ ;END WITH A 0 .IF NE,TIMER MOV #DEFT,CLOCKW ;PUT IN DEFAULT CLOCK SETTINGS CLR CLOCKW+2 MOV #DEFT,CLOCKB CLR CLOCKB+2 MOV #,WARNT ;SET UP WARNING TIME .ENDC .IF NE,STATS CLR COUNTE+2 ;CLEAR EVALUATION COUNTS CLR ECOUNT+2 ;IN CASE WE DO PS BEFORE A MOVE .ENDC .IF NE,TREE CLR DEBUG ;FORGET TREE PRINTING .ENDC .IF NE,HISTOG MOV #HISTO,R0 ;ADDRESS OF HISTOGRAM 30$: CLR (R0)+ ;CLEAR IT CMP R0,#HISTO+8192. ;DONE ? BLO 30$ ;NO .ENDC .IF NE,BOOKOP MOV #BOARD,BKFROM ;FUDGE THE "LAST" MOVE MOV #BOARD,BKTO ;TO FAKE THE BOOK OPENER CLR BKMDW ;INCASE THE MACHINE PLAYS WHITE CLR BOOK ;START AT PAGE 0 OF THE BOOK .ENDC ; COMPUTER PLAYS NEITHER COMPN: CLR WHOWHI ;USER PLAYS WHITE CLR WHOBLK ;AND BLACK .IF NE,THINKA CLR THINKF ;PREVENT ANY SCREW UPS WHEN CHANGING MODES CLR IKNEW ;BY FORGETTING ANY THINKING AHEAD .ENDC .IF NE,TIMER CALL TIME ;RESET TIMER .ENDC .IF NE,GT40 CALL BTOP ;PUT BLACK ON TOP .ENDC RTS PC ; COMPUTER PLAYS WHITE COMPW: INC WHOWHI ;COMPUTER PLAYS WHITE .IF NE,THINKA CLR THINKF ;PREVENT ANY SCREW UPS WHEN CHANGING MODES CLR IKNEW ;BY FORGETTING ANY THINKING AHEAD .ENDC .IF NE,TIMER CALL TIME ;RESET TIMER .ENDC .IF NE,GT40 TST WHOBLK ;IS MACHINE PLAYING BLACK ALSO ? BNE 10$ ;YES, LEAVE BLACK ON TOP CALL WTOP ;NO, PUT WHITE ON TOP 10$: .ENDC RTS PC ; COMPUTER PLAYS BLACK COMPB: INC WHOBLK ;COMPUTER PLAYS BLACK .IF NE,THINKA CLR THINKF ;PREVENT ANY SCREW UPS WHEN CHANGING MODES CLR IKNEW ;BY FORGETTING ANY THINKING AHEAD .ENDC .IF NE,TIMER CALL TIME ;RESET TIMER .ENDC .IF NE,GT40 CALL BTOP ;PUT BLACK ON TOP .ENDC RTS PC ; BOARD DISPLAY COMBD: CALL OCRLF ;MAKE SURE WE START ON A CLEAN LINE JMP DISPLY ;PRINT THE BOARD ; SKIP A MOVE COMSK: COM WHOSE ;SKIP A MOVE BY FLIPPING WHOSE .IF NE,THINKA CLR THINKF ;PREVENT ANY SCREW UPS WHEN CHANGING MODES CLR IKNEW ;BY FORGETTING ANY THINKING AHEAD .ENDC RTS PC ; SET DEPTH COMDEQ: CLR CHRONE ;FORGET FIRST TWO CHARACTERS CALL GETNUM ;GET NEW DEPTH BEQ INERRX ;CAN'T BE ZERO CMP R0,#MAXD-EMAX ;COMPARE AGAINST MAX DEPTH BGT INERRX ;OR TOO BIG 10$: MOV R0,DEPTH ;SAVE IT ADD #EMAX,R0 ;GET NEW MAX DEPTH MOV R0,MDEPTH .IF NE,THINKA CLR THINKF ;PREVENT ANY SCREW UPS WHEN CHANGING MODES CLR IKNEW ;BY FORGETTING ANY THINKING AHEAD .ENDC RTS PC ; SET WIDTH(S) COMWEQ: CLR CHRONE ;FORGET FIRST TWO CHARACTERS MOV #WIDTH,R2 ;ADDRESS OF WIDTH TABLE 10$: CALL GETNUM ;GET NEXT WIDTH BEQ INERRX ;NO WIDTH CAN BE ZERO MOVB R0,(R2)+ ;SAVE IT IN THE TABLE CALL GETC ;IS NEXT CHAR A COMMA ? CMP R0,#', BNE 20$ ;NO, END OF COMMAND TSTB (R2) ;IS THIS END OF WIDTH TABLE ? BNE 10$ ;NO 20$: .IF NE,THINKA CLR THINKF ;PREVENT ANY SCREW UPS WHEN CHANGING MODES CLR IKNEW ;BY FORGETTING ANY THINKING AHEAD .ENDC RTS PC INERRX: JMP INERR ;LINK TO INERR .IF NE,TIMER ; SET CLOCK(S) COMCEQ: CLR CHRONE ;KILL C= CALL GETNUM ;GET CLOCK SETTINGS MOV R0,CLOCKW ;SAVE 'EM MOV R0,CLOCKB ASR R0 ;DIVIDE BY 8 TO GET WARNING TIME ASR R0 ASR R0 MOV R0,WARNT CALL GETC ;GET A CHARACTER CMP R0,#', BNE 10$ ;NO SECOND SETTING CALL GETNUM ;GET BLACK'S CLOCK MOV R0,CLOCKB ;SAVE IT 10$: RTS PC .ENDC .IF NE,TREE ; SET TREE PRINTING DEPTH COMTEQ: CLR CHRONE ;DELETE THE "T=" CALL GETNUM ;GET TREE OUTPUT DEPTH MOV R0,DEBUG ;SAVE THE DEBUG VALUE RTS PC .ENDC .IF NE,STATS ; PRINT STATISTICS COMPS: SAVE ;SAVE REGISTERS CALL OCRLF ;START ON A NEW LINE .PRINT #DEPTHM ;PRINT THE DEPTH MOV DEPTH,R0 CALL OUTVAL CALL OCRLF .PRINT #WIDTHM ;NOW THE WIDTH MOV DEPTH,R1 ;ONLY FOR THE FIRST DEPTH-1 PLYS MOV #WIDTH,R4 10$: DEC R1 ;ONLY FOR DEPTH-1 PLYS BLE 20$ ;WIDTH=ALL ON LAST PLY MOVB (R4)+,R0 ;GET NEXT WIDTH CALL OUTVAL ;OUTPUT IT BR 10$ 20$: .PRINT #ALLM ;PRINT ALL FOR LAST PLY .PRINT #MOVEM ;OUTPUT MOVE NUMBER MOV MOVE,R0 CALL OUTVAL CALL OCRLF .PRINT #EVALM ;OUTPUT STATIC EVALUATION COUNT MOV COUNTE+2,R0 ;OUTPUT COUNT FOR PRE-ANALYSIS CALL OUTVAL MOV ECOUNT+2,R0 CALL OUTVAL CALL OCRLF .IF NE,TIMER .PRINT #TIMEW MOV CLOCKW,R0 ;PRINT WHITE'S TIMES CALL OUTVAL MOV CLOCKW+2,R0 CALL OUTVAL CALL OCRLF .PRINT #TIMEB MOV CLOCKB,R0 ;PRIN BLACK'S TIMES CALL OUTVAL MOV CLOCKB+2,R0 CALL OUTVAL CALL OCRLF .ENDC INC BOGUS CALL GNMVSM ;DO A PSEUDO MOVE GENERATION .PRINT #MOVESM ;OUTPUT NUMBER OF MOVES POSSIBLE MOV GNCNT,R0 CALL OUTVAL JMP OCRLF .ENDC .IF NE,HISTOG ; PRINT HISTOGRAM COMHI: MOV #HISTO,R1 ;ADDRESS OF HISTOGRAM INC LPT ;SET LP OUT SWITCH MOV #14,R0 ;FORM FEED CALL OUTC 10$: MOV R1,R0 ;OUTPUT ADDRESS SUB #HISTO,R0 CALL OCTAL ;IN OCTAL MOV #16.,R3 ;OUTPUT 16 COUNTS PER PAGE 20$: MOV (R1)+,R0 ;GET NEXT COUNT CALL OCTAL ;PRINT IT DEC R3 ;MORE ? BNE 20$ ;YES CALL OCRLF ;END OF LINE CMP R1,#HISTO+8192. ;DONE ? BLO 10$ ;NO CLR LPT ;BACK TO CONSOLE RTS PC OCTAL: MOV #5,R2 ;5 DIGIT OCTAL OUTPUT ROL R0 ;DROP FIRST BIT 10$: ROL R0 ;SHIF OVER ONE DIGIT ROL R0 ROL R0 MOV R0,-(SP) ;SAVE SHIFTED THING ROL R0 ;GET BIT IN CARRY BIC #177770,R0 ;ISOLATE 3 BITS ADD #60,R0 ;MAKE IT ASCII CALL OUTC ;PRINT IT MOV (SP)+,R0 ;RESTORE REST OF NUMBER DEC R2 ;MORE DIGITS ? BNE 10$ ;YES MOV #40,R0 ;OUTPUT A SPACE CALL OUTC RTS PC .ENDC ; INPUT A MOVE COMINM: CALL INMVSU ;SET UP FOR MOVE INPUT CALL INMV ;GET IT BCS 10$ ;BAD INPUT .IF NE,TIMER CALL CLOKIT ;CLOCK IT .ENDC MOV IOFROM,R3 ;OK, MAKE IT MOV IOTO,R2 MOV IOMDW,MVMDW .IF NE,BOOKOP MOV R3,BKFROM ;SAVE IT FOR BOOK COMPARISON MOV R2,BKTO MOV MVMDW,BKMDW .ENDC CALL MKMV ADD #MKMVX,SP ;CLEAN STACK 10$: RTS PC ; SET UP FOR MOVE INPUT INMVSU: CALL GNMVSM ;GENERATE LEGAL MOVES MOV R5,IOMOVS ;SAVE ADDRESS OF LEGAL MOVES MOV WKING,IOWK ;SAVE ADDRESS OF WHITE KING MOV BKING,IOBK ;AND BLACK KING MOV WHOSE,IOWHO ;WHO IS INPUTTING MOVE ? MOV #BOARD+42.,R1 ;ADDRESS OF ACTIVE BOARD MOV #IOBORD,R2 ;ADDRESS OF IO BOARD MOV #78.,R3 ;NUMBER OF ACTIVE SQUARES 10$: MOV (R1)+,(R2)+ ;COPY CURRENT BOARD DEC R3 BNE 10$ RTS PC ; INPUT A POSITION COMPEQ: CALL COMRE ;FIRST RESET EVERYTHING CLR CHRONE ;GET MOVE NUMBER CALL GETNUM MOV R0,MOVE ;IN CASE ITS IMPORTANT TO THE POSITION INC DOMAP ;MAKE SURE WE MAP CLR NPIECS ;NO PIECES CLR PW ;ZERO PIECE SUM MOV #BOARD+182.,R4 ;START WITH BLACK'S BACK RANK 10$: CALL FLUSH ;FIND THE END OF THE LINE MOV #8.,R2 ;8. SQUARES IN A RANK 15$: CALL GETC ;GET A CHAR MOV R0,R3 ;SAVE IT IN CASE ITS A PIECE COLOR SUB #71,R0 ;IS IT A NUMBER ? ADD #11,R0 BCC 30$ ;NO, MUST BE A PIECE BEQ 60$ ;ZERO IS ILLEGAL CMP R0,R2 ;ENOUGH SPACE LEFT ? BGT 60$ ;NO, ERROR 20$: CLR (R4)+ ;CLEAR THE SPACES DEC R2 DEC R0 ;DECREMENT THE COUNTS BNE 20$ TST R2 ;ANY ROOM LEFT IN THIS RANK ? 25$: BNE 15$ ;YES SUB #36.,R4 ;NO, POINT AT NEXT RANK CMP R4,#BOARD+42. ;FINISHED YET ? BHIS 10$ ;NOT YET CALL MAPEC ;DO A PIECE MAP TST WKING ;IS A KING MISSING ? BEQ 50$ ;YES, BAD TST BKING ;CHECK BOTH BEQ 50$ .IF NE,BOOKOP MOV #-1,BOOK ;KILL BOOK .ENDC RTS PC ;OK, DONE 30$: CALL INPIEC ;GET THE PIECE VALUE MOV VALUE(R1),R0 ;GET PIECE VALUE CMP R3,#'W ;IS IT WHITE ? BEQ 40$ ;YES, JUST STORE IT CMP R3,#'B ;BLACK ? BNE INERR ;NO, ERROR ADD #BLACK,R1 ;CHANGE THE COLOR NEG R0 ;AND NEGATE THE VALUE 40$: MOV R1,(R4)+ ;PUT IT ON THE BOARD ADD R0,PW ;ADD TO BOARD VALUE INC NPIECS ;AND INCREMENT PIECE COUNT DEC R2 ;REDUCE COUNT BR 25$ ;SEE IF END OF RANK 50$: CALL COMRE ;KING MISSING, RESET BOARD 60$: BR INERR ;AND GIVE ERROR MESSAGE ; INPUT A MOVE INMV: SAVE ;SAVE ALL REGS MOV IOMOVS,R5 ;GET ADDRESS OF LEGAL MOVES CLR IOMDW ;CLEAR MDW FOR INPUT MOVE CLR IOTO ;AND THE TO ADDRESS CLR IOFROM ;AND THE FROM ADDRESS CLR CAPIEC ;CLEAR THE CAPTURED PIECE VALUE CMP CHRONE,#"OO ;CASTLING ? BEQ INCA ;YES CALL INPIEC ;GET THE NAME OF THE PIECE MOVING MOV R1,IOPIEC ;SAVE IT ; LOOK FOR MOVE OPERATION 10$: CALL GETC ;GET THE OPERATOR CHARACTER CMP R0,#'- ;SIMPLE MOVE ? BEQ 30$ ;YES CMP R0,#'* ;CAPTURE ? BEQ 20$ ;YES CMP R0,#'X ;CAPTURE ? BEQ 20$ ;YES CMP R0,#'# ;ENPASSANT CAPTURE ? BEQ 15$ ;YES, TREAT SPECIALLY ; FROM SQUARE DESIGNATION CMP R0,#'/ ;FROM SQUARE DESIGNATOR ? BNE INERR ;NO, BAD INPUT TST IOFROM ;PREVIOUS FROM SQUARE ? BNE INERR ;YES, TWO IS BAD CALL INSQAR ;OK, GET THE FROM SQUARE MOV R1,IOFROM ;AND SAVE IT BR 10$ ;GO BACK FOR REST ; ENPASSANT CAPTURES 15$: MOV #ENPASS+CAPTUR,IOMDW ;MDW FOR ENPASSANT CAPTURE BR CHKLGL ;GO SEE IF LEGAL ; NORMAL CAPTURES 20$: BIS #CAPTUR,IOMDW ;SET CAPTURE BIT CALL INPIEC ;GET PIECE TO BE CAPTURED MOV R1,CAPIEC ; TO SQUARE DESIGNATION CALL GETC ;GET POSSIBLE TO SQUARE DESIGNATOR CMP R0,#'/ ;SLASH PRECEEDS SQUARE NAME BNE 40$ ;NO 30$: CALL INSQAR ;GET TO SQUARE MOV R1,IOTO ;SAVE IT CALL GETC ;POSSIBLE PAWN PROMOTION ? ; PAWN PROMOTIONS 40$: CMP R0,#'= BNE CHKLGL ;NO, JUST CHECK FOR ILLEGAL MOVES CALL INPIEC ;GET NEW PIECE INDEX MOV PROMDW(R1),R1 ;GET MDW OF PROMOTION BEQ INERR ;P=P AND P=K ARE ILLEGAL BIS R1,IOMDW ;ADD SPECIAL MOVE BITS TO MDW BR CHKLGL ;SEE IF MOVE IS LEGAL INERR: .PRINT #ERROR ;SOMETHING WRONG WITH THE INPUT SEC ;SIGNAL ERROR RTS PC ; CASTLING MOVES INCA: CLR CHRONE ;FORGET THE FIRST TWO CHARACTERS MOV IOWK,R1 ;ASSUME WHITE INPUTTING MOVES MOV #KING,IOPIEC ;A KING IS THE MOVING PIECE TST IOWHO ;WHO ACTUALLY IS ? BEQ 10$ ;YES, ITS WHITE MOV IOBK,R1 ;NO, USE BLACK'S KING 10$: MOV R1,IOFROM ;THIS IS THE FROM ADDRESS CMP (R1)+,(R1)+ ;PLUS 4 GIVES KING' TO SQUARE MOV #KSCAS,IOMDW ;SET BIT TO INDICATE O-O CALL GETC ;SEE IF THERE IS ANOTHER "O" CMP R0,#'O BNE 20$ ;NO, NOT QUEENS SIDE CASTLING SUB #10,R1 ;FIX UP TO ADDRESS MOV #QSCAS,IOMDW ;AND MDW 20$: MOV R1,IOTO ;SAVE CASTLING MOVE TO ADDRESS ; CHECK FOR MOVE VALIDITY CHKLGL: CLR R0 ;CLEAR MOVE FOUND ADDRESS 5$: MOV (R5)+,R1 ;MDW OF MOVE MOV (R5)+,R2 ;TO ADDRESS MOV (R5)+,R3 ;FROM ADDRESS BEQ 50$ ;NO MORE MOVES, SEE IF WE FOUND ONE TST IOFROM ;FROM ADDRESS GIVEN ? BEQ 10$ ;NO, ASSUME A MATCH CMP R3,IOFROM ;SAME FROM ADDRESS ? BNE 5$ ;NO, TRY AGAIN 10$: TST IOTO ;TO ADDRESS GIVEN ? BEQ 20$ ;NO, ASSUME A MATCH CMP R2,IOTO ;SAME TO ADDRESS BNE 5$ ;NO, LOOK AGAIN 20$: CMPB IOBD(R3),IOPIEC ;IS IT THE CORRECT PIECE ? BNE 5$ ;NO CMPB IOBD(R2),CAPIEC ;DOES THE CAPTURED PIECE MATCH ? BNE 5$ ;NO MATCH BIC #77770,R1 ;COMPARE CAPTURE AND SPECIAL BITS CMP R1,IOMDW BNE 5$ ;DON'T MATCH ; CHECK FOR MOVE AMBIGUITY TST R0 ;ANY PREVIOUS MATCH ? BEQ 40$ ;NO, ITS OK SO FAR .PRINT #AMBIG ;AMBIGUOUS MOVE SEC ;SIGNAL ERROR RTS PC ;TRY AGAIN 40$: MOV R5,R0 ;SAVE MOVE STACK POINTER OF MATCHING MOVE BR 5$ ;MAKE SURE ITS UNIQUE ; MAKE THE MOVE IF LEGAL 50$: TST R0 ;ANY MATCH ? BNE 60$ ;YES, MOVE OK .PRINT #ILLMOV ;PRINT ILLEGAL MOVE SEC ;SIGNAL ERROR RTS PC 60$: MOV -(R0),IOFROM ;GET THE MATCHING MOVE PARAMETERS MOV -(R0),IOTO MOV -(R0),IOMDW .IF NE,THINKA CLR IKNEW ;CLEAR THE CORRECT GUESS SWITCH CMP IOFROM,THINKF ;COMPARE ACTUAL MOVE MADE BNE 65$ ;WITH MOVE THAT MACHINE GUESSED CMP IOTO,THINKT ;AND IF EQUAL, SET THE I KNEW SWITCH BNE 65$ ;WHICH MEANS THAT IF THE MACHINE IS CMP IOMDW,THINKM ;FINISHED THINKING ABOUT A RESPONSE TO BNE 65$ ;THE GUESSED MOVE, IT CAN USE IT AND INC IKNEW ;APPARENTLY MAKE AN INSTANTANEOUS REPLY 65$: .ENDC CLC ;INDICATE SUCCESS RTS PC ; INPUT A SQUARE NAME INSQAR: CALL GETC ;GET FILE NAME MOV R0,R2 ;FIRST CHARACTER CALL GETC CMP R0,#101 ;IS SECOND CHAR A LETTER ? BGE 1$ ;YES MOVB R0,CHRONE+1 ;NO, PUT IT BACK MOV R2,R0 MOV #40,R2 ;ASSUME BLANK FOR FIRST CHAR 1$: SWAB R0 ;PUT THEM TOGETHER BIS R0,R2 MOV #7,R1 ;FIND FILE NUMBER MOV #NAME+20,R3 ;BY SEARCHING 10$: CMP R2,-(R3) ;THE FILE NAME LIST BEQ 20$ ;GOT IT DEC R1 BPL 10$ ;KEEP LOOKING BR INERRL 20$: CALL GETC ;NOW GET THE RANK NUMBER SUB #71,R0 ADD #10,R0 ;IS IT 1 TO 8 ? BCC INERRL ;NO TST IOWHO ;WHO IS INPUTTING MOVE ? BEQ 30$ ;WHITE COM R0 ;BLACK, FLIP THE RANK NUMBER BIC #177770,R0 30$: ASL R0 ;RANK * 10. ADD R0,R1 ASL R0 ASL R0 ADD R0,R1 ;PLUS FILE PLUS A CONSTANT ASL R1 ;(SHIFTED FOR BYTE ADDRESSING) ADD #BOARD+42.,R1 ;GIVES REAL CORE ADDRESS RTS PC ; INPUT A NUMBER GETNUM: CLR R1 ;CLEAR THE RETURN NUMBER 5$: CALL GETC ;GET NEXT CHAR MOV R0,R3 ;SAVE IT FOR A WHILE SUB #72,R0 ;IS IT A DIGIT ? ADD #12,R0 BCS 10$ ;YES MOVB R3,CHRONE ;NO, REPLACE IT MOV R1,R0 ;GET ONLY DIGIT RTS PC 10$: ASL R1 ;MULTIPLY BY 10 ADD R1,R0 ASL R1 ASL R1 ;THEN ADD IN SECOND DIGIT ADD R0,R1 BR 5$ ;GET NEXT DIGIT ; INPUT A PIECE NAME INPIEC: CALL GETC ;GET THE PIECE NAME CLR R1 ;CLEAR THE PIECE INDEX 10$: INC R1 ;INCREMENT PIECE INDEX CMPB NAMES-1(R1),R0 ;IS THIS THE CORRECT PIECE ? BNE 20$ ;NO ASL R1 ;MAKE IT A WORD INDEX RTS PC 20$: CMP R1,#6 ;LIST EXHAUSTED ? BLE 10$ ;NO INERRL: TST (SP)+ ;FIX STACK JMP INERR ;PRINT MESSAGE .SBTTL MOVE GENERATOR ENTRY POINTS GNMVSM: TST WHOSE ;WHOSE MOVE IS IT ? BMI GNBMV ;BLACK'S, GO GENERATE HIS MOVES GNWMV: CALL MAPEC ;MAP IF NECESSARY CLR COLR ;SET THE COLOR TO WHITE MOV #20.,PONDIR ;SET THE PAWN DIRECTION MOV WKING,CKING ;SET THE ADDRESS OF THE MOVER'S KING MOV #WHTMAP,GMAP ;SET THE ADDRESS OF THE MOVER'S MAP MOV #BLKMAP,OMAP ;SET THE ADDRESS OF THE OPPONENT'S MAP MOV #WPSW,CPSW ;SET THE ADDRESS OF THE MOVER'S PSW BR GNMV ;GO GENERATE WHITE'S MOVES GNBMV: CALL MAPEC ;MAP IF NECESSARY MOV #BLACK,COLR ;EXCEPT COLOR IS DIFFERENT MOV #-20.,PONDIR ;AND PAWNS MOVE BACKWARDS MOV BKING,CKING MOV #BLKMAP,GMAP MOV #WHTMAP,OMAP MOV #BPSW,CPSW GNMV: CLR KNGBLK ;AND KING BLOCK COUNT CLR GNCNT ;CLEAR THE COUNT OF LEGAL MOVES TST BOGUS ;DO WE REALLY GENERATE MOVES ?? BNE GNPINS ;NO, JUST GO THROUGH THE MOTIONS CMP R5,#GUARD+120. ;ANYWHERE NEAR END OF MOVE SPACE ? BHI 10$ ;OK, DON'T RESIGN CALL DISPLY ;PRINT FINAL BOARD .PRINT #RESIGN ;TOO DEEP, PRINT "I RESIGN" CALL COMRE ;RESET ALL PARAMETERS .IF NE,GT40 CALL DISPLAY ;SHOW NEW BOARD .ENDC JMP COMMAN ;RESTART THE PROGRAM 10$: CLR -(R5) ;YES, MARK THE STACK CLR -(R5) ;TWICE CLR -(R5) ;NO, THREE TIMES .SBTTL MOVE GENERATOR ; GENERATE PIN BOARD AND BISHOP, ROOK, QUEEN ATTACKS ON KING GNPINS: CLR PINCNT ;CLEAR THE PIN COUNTER CLR GNCHEK ;CLEAR THE CHECK COUNT MOV #P.R4,R0 ;SET UP INITIAL PIN BIT MOV #QLIST,R3 ;ADDRESS OF DIRECTION LIST 10$: MOV CKING,R2 ;GET KING'S ADDRESS CLR R4 ;CLEAR THE PINNED PIECE'S ADDRESS 15$: ADD (R3),R2 ;MOVE OUTWARD FROM KING MOV (R2),R1 ;GET CONTENTS OF SQUARE BEQ 15$ ;EMPTY, CONTINUE IN SAME DIRECTION CMP R1,#OFF ;IS SQUARE OFF BOARD ? BEQ 60$ ;YES, NO PINS IN THIS DIRECTION ADD COLR,R1 ;MY PIECE ? BMI 20$ ;NO, ONE OF THE ENEMY'S TST R4 ;DO WE ALREADY HAVE A PIN CANDIDATE ? BNE 60$ ;YES, NO PIN IN THIS DIRECTION MOV R2,R4 ;NO, MAKE THIS PIECE THE CANDIDATE BR 15$ 20$: MOVB R1,R1 ;KILL COLOR BIT JMP 25$-2(R1) ;BRANCH ON PIECE INDEX 25$: BR 60$ ;PAWN BR 60$ ;KNIGHT BR 30$ ;BISHOP BR 35$ ;ROOK BR 40$ ;QUEEN BR 60$ ;KING 30$: BIT #P.B,R0 ;MOVING IN A BISHOP DIRECTION ? BNE 40$ ;YES, ITS A PIN OR ATTACK BR 60$ ;NO, NOTHING 35$: BIT #P.R,R0 ;MOVING IN A ROOK DIRECTION ? BEQ 60$ ;NO, NO PINS 40$: TST R4 ;WAS ONE OF MY PIECES IN THE WAY ? BNE 50$ ;YES, ITS PINNED INC GNCHEK ;INCREMENT THE KING ATTACKS COUNT 45$: BIS #CK.BLK,PINS(R2);SET CHECK BLOCKING SQUARE BIT SUB (R3),R2 ;MOVE BACK TOWARD THE KING CMP CKING,R2 ;THERE YET ? BNE 45$ ;NO BR 60$ ;TRY NEXT DIRECTION 50$: BIS R0,PINS(R4) ;SET PIN BIT FOR THIS PIECE IN THIS DIRECTION CMPB (R4),#PAWN ;IS PINNED PIECE A PAWN ? BEQ 60$ ;YES, DON'T COUNT PINNED PAWNS AS A BONUS INC PINCNT ;INCREMENT THE PIN COUNT 60$: ASL R0 ;SHIFT THE PIN BIT TST -(R3) ;BUMP THE DIRECTION POINTER BNE 10$ ;WHICH ALSO DOUBLES AS A COUNTER ; FIND PAWN ATTACKS ON THE KING GPNCK: MOV CKING,R2 ;GET THE KING'S ADDRESS ADD PONDIR,R2 ;GET RANK OF POSSIBLE ATTACKING PAWNS MOV -(R2),R3 ;GET SQUARE VALUE OF LOWER FILE ADD COLR,R3 CMP R3,#BLACK+PAWN ;ENEMY PAWN ? BNE 10$ ;NO BIS #CK.BLK,PINS(R2);SET CHECK BLOCK BIT INC GNCHEK ;INCREMENT COUNT 10$: CMP (R2)+,(R2)+ ;TRY UPPER FILE MOV (R2),R3 ;GET SQUARE VALUE ADD COLR,R3 CMP R3,#BLACK+PAWN ;ENEMY PAWN ? BNE GKNCK ;NO BIS #CK.BLK,PINS(R2);YES, SET THE BIT INC GNCHEK ;AND INCREMENT THE COUNT ; FIND KNIGHT ATTACKS ON THE KING GKNCK: MOV #KNLIST,R3 ;GET ADDRESS OF KNIGHT MOVE LIST 10$: MOV CKING,R2 ;GET KING'S ADDRESS ADD (R3),R2 ;GET ADDRESS OF POSSIBLE KNIGHT ATTACKER MOV (R2),R0 ;GET VALUE OF SQUARE ADD COLR,R0 CMP R0,#BLACK+KNIGHT ;ENEMY KNIGHT ? BNE 20$ ;NO BIS #CK.BLK,PINS(R2);YES, SET THE BIT ON THE PIN BOARD INC GNCHEK ;AND INCREMENT THE KING ATTACKED COUNT 20$: TST -(R3) ;ANY MORE ? BNE 10$ ;YES ; GENERATE CASTLING MOVES GKM: MOV CKING,R0 ;GET KING'S ADDRESS AGAIN MOV (R0),-(SP) ;SAVE HIM CLR (R0) ;REMOVE KING CALL GENATK ;GENERATE ATTACK BOARD MOV (SP)+,(R0) ;RESTORE HIM MOV #QSCAS,GNMDW ;SETUP FOR QUEEN SIDE CASTLING MOV #BOARD+50.,R1 ;KING'S HOME ADDRESS FOR WHITE TST COLR ;IS WHITE MOVING ? BPL 10$ MOV #BOARD+190.,R1 ;NO, USE BLACK'S HOME ADDRESS 10$: CMP R1,R0 ;IS THAT WHERE HE IS ? BEQ 20$ ;YES, CASTLING MAY BE OK BIS #NOCAS,@CPSW ;SET THE NO CASTLING BITS BR GKMNOR ;GENERATE NORMAL KING MOVES 20$: MOV R0,R2 ;GET QUEEN'S ROOK ADDRESS SUB #8.,R2 BIT #QRMOVD,@CPSW ;HAS IT MOVED ? BNE 40$ ;YES MOV (R2)+,R3 ;SEE IF ITS REALLY THERE ADD COLR,R3 CMP R3,#ROOK BEQ 30$ ;YES IT IS BIS #QRMOVD,@CPSW ;NO, PSW LIED BR 40$ ;TRY KING'S SIDE 30$: TST GNCHEK ;IS KING CHECKED ? BNE 40$ ;YES, CASTLING ILLEGAL TST (R2)+ ;IS QUEENS KNIGHT SQUARE EMPTY ? BNE 40$ ;NO, TRY KING'S SIDE MOV R2,R1 ;SAVE KING'S POST CASTLING ADDRESS CALL CASCHK ;IS QB1 EMPTY AND UNATTACKED ? BNE 40$ ;NO, TRY KING'S SIDE CALL CASCHK ;IS Q1 EMPTY AND UNATTACKED ? BNE 40$ ;NO, TRY KING'S SIDE MOV R1,R2 ;RESTORE KING'S POST CASTLING ADDRESS CALL GNSTRX ;SAVE THE MOVE 40$: BIT #KRMOVD,@CPSW ;HAS KING'S ROOK MOVED ? BNE GKMNOR ;YES, NO CASTLING TO HIS SIDE MOV R0,R2 ;COPY KING'S PRE CASTLING ADDRESS MOV 6(R2),R1 ;GET PIECE ON THE SQUARE ADD COLR,R1 CMP R1,#ROOK ;IS IT A ROOK ? BEQ 50$ ;YES BIS #KRMOVD,@CPSW ;PSW LIED BR GKMNOR ;DO OTHER KING MOVES 50$: TST GNCHEK ;WAS HE IN CHECK ? BNE GKMNOR ;YES TST (R2)+ ;ADDRESS OF KB1 CALL CASCHK ;IS KB1 ATTACKED OR OCCUPIED ? BNE GKMNOR ;YUP MOV R2,R1 ;SAVE KING'S POST CASTLING ADDRESS CALL CASCHK ;WHAT ABOUT KN1 BNE GKMNOR ;YUP INC GNMDW ;SET CORRECT BIT IN MDW MOV R1,R2 ;RESTORE KING'S POST CASTLING ADDRESS CALL GNSTRX ;SAVE THE MOVE ; GENERATE NORMAL KING MOVES GKMNOR: MOV #QLIST,R3 ;KING MOVES LIKE SLOW QUEEN 10$: MOV R0,R2 ;COPY PIECE ADDRESS CLR GNMDW ADD (R3),R2 ;GET NEW TO SQUARE ADDRESS MOV (R2),R1 ;WHAT'S THERE ? BEQ 20$ ;NOTHING, SEE IF ITS ATTACKED CMP R1,#OFF ;IS IT OFF THE BOARD ? BEQ 40$ ;YES ADD COLR,R1 ;MY PIECE ? BPL 40$ ;YES, NO MOVE MOV #CAPTUR,GNMDW ;SET THE CAPTURE BIT 20$: TSTB AC(R2) ;IS THE DESTINATION SQUARE ATTACKED ? BEQ 30$ ;NO, MOVE IS LEGAL INC KNGBLK ;YES, KING MOVE BLOCKED BR 40$ 30$: CALL GNSTRX ;SAVE THE MOVE 40$: TST -(R3) ;ANY MORE DIRECTIONS ? BNE 10$ ;YUP CMP GNCHEK,#1 ;HOW MANY CHECKS ? BGT TSCMSM ;MORE THAN ONE, MUST MOVE KING ; GENERATE ENPASSANT CAPTURES GNEP: MOVB LSTMV+1,R2 ;GET THE LAST MOVE HIGH BYTE BIC #177600,R2 ;WAS IT A DOUBLE PAWN PUSH ? BEQ 10$ ;NO, NO ENPASSANT CAPTURE POSSIBLE ASL R2 ;GET BOARD DISPLACEMENT ADD #BOARD+42.,R2 ;TO ADDRESS OF PUSH MOV R2,R1 ;SAVE ADDR OF PAWN TO CAPTURE FOR ENPCHK MOV (R1),R3 ;GET VALUE OF PAWN TO CAPTURE ADD COLR,R3 CMP R3,#BLACK+PAWN ;IS IT AN ENEMY PAWN ? BNE 10$ ;NO, DON'T TRY TO CAPTURE MY OWN MOV R2,R0 ;WILL CREATE FROM ADDR OF POSSIBLE CAPTURE IN R0 ADD PONDIR,R2 ;TO ADDRESS OF EITHER ENPASSANT CAPTURE MOV #ENPASS+CAPTUR,GNMDW ;MDW OF ENPASSANT CAPTURE MOV #PCLFB,R4 ;ADDRESS OF PIN MASK FOR THIS DIRECTION CALL ENPCHK ;CHECK LOWER FILE FIRST ADD #6,R0 ;NOW UPPER MOV #PCHFB,R4 ;ADDRESS OF PIN MASK CALL ENPCHK 10$: MOV GMAP,R4 ;POINTER TO MOVER'S PIECE MAP NXTSQR: MOV (R4)+,R0 ;GET ADDRESS OF NEXT PIECE BNE NOMEND ;NOT END OF MAP YET ; ALL MOVES GENERATED, RETURN TSCMSM: MOV GNCNT,MOBMOD ;COUNT OF TOTAL MOVES MOV KNGBLK,R2 ;COUNT OF KING MOVES ILLEGAL BECAUSE OF CHECK .IF NE,KB-MP IMULI KB,R2 ;MULTIPLIED BY THE KING BLOCKED FACTOR MOV PINCNT,R1 ;GET COUNT OF MAJOR PINNED PIECES IMULI MP,R1 ;MULTIPLIED BY THE MAJOR PIECE PIN FACTOR ADD R1,R2 .IFF ADD PINCNT,R2 ;PLUS COUNT OF MAJOR PINNED PIECES IMULI MP,R2 ;MULTIPLIED BY A FACTOR .ENDC SUB R2,MOBMOD ;SUBTRACTED FROM THE MOBILITY CLR BOGUS ;CLEAR THE DON'T GENERATE MOVES SWITCH RTS PC ; GENERATE MOVES FOR ALL OTHER PIECES NOMEND: MOVB (R0),R3 ;GET PIECE INDEX JMP 5$(R3) ;BRANCH ON IT 5$: BR NXTSQR ;EMPTY BR GPM ;PAWN BR GNM ;KNIGHT BR GBM ;BISHOP BR GRM ;ROOK BR GQM ;QUEEN BR NXTSQR ;KING (DONE ALREADY) BR NXTSQR ;OFF ; GENERATE ALL OTHER PAWN MOVES GPM: CLR GNMDW ;CLEAR THE MOVES MDW BIT #P.B+P.R2+P.R4,PINS(R0) BNE 40$ ;PAWN IS PINNED, NO PUSH MOVES MOV R0,R2 ;COPY THE PAWN'S POSITION CALL PST ;TEST THE SINGLE PUSH MOVE BNE 40$ ;NO GOOD TST COLR ;WHOSE PAWN IS MOVING BMI 20$ ;BLACK'S CMP R0,#BOARD+76. ;IS IT IN THE FIRST RANK ? BGT 40$ ;NO BR 30$ ;YES, DOUBLE PUSH IS OK 20$: CMP R0,#BOARD+162. ;SAME QUESTION FOR BLACK BLT 40$ ;BUT REVERSE SENSE OF TEST 30$: INC DOUBLE ;SET DOUBLE PAWN PUSH SWITCH CALL PST ;TRY THE MOVE CLR DOUBLE ;NOW CLEAR THE SWITCH 40$: MOV R0,R2 ;RESTORE STARTING ADDRESS ADD PONDIR,R2 ;CHECK FOR CAPTURES ADD #2,R2 ;HIGH FILE FIRST MOV #PCHFB,R3 ;ADDRESS OF PIN MASKS CALL CAPTST SUB #4,R2 ;NOW LOW FILE MOV #PCLFB,R3 ;PIN MASKS AGAIN CALL CAPTST BR NXTSQR ; GENERATE KNIGHT MOVES GNM: TST PINS(R0) ;IS IT PINNED ? BNE NXTSQR ;YES, DON'T MOVE IT MOV #KNLIST,R3 ;ADDRESS OF KNIGHT MOVES 1$: MOV R0,R2 ;COPY PIECE ADDRESS CLR GNMDW ADD (R3),R2 ;GET NEW TO SQUARE ADDRESS MOV (R2),R1 ;WHAT'S THERE ? BEQ 3$ ;NOTHING, MOVE IS OK CMP R1,#OFF ;IS IT OFF THE BOARD ? BEQ 5$ ;YES ADD COLR,R1 ;MY PIECE ? BPL 5$ ;YES, NO MOVE MOV #CAPTUR,GNMDW ;SET CAPTURE BIT 3$: CALL GNSTR ;SAVE THE MOVE 5$: TST -(R3) ;ANY MORE DIRECTIONS ? BNE 1$ ;YUP BR NXTSQR ; GENERATE BISHOP, ROOK, QUEEN MOVES GQM: MOV #QLIST,R3 BR LINE GRM: MOV #RLIST,R3 BR LINE GBM: MOV #BLIST,R3 LINE: MOV R0,R2 ;COPY PIECE'S POSITION BIT PIND(R3),PINS(R0);IS PIECE PINNED IN ANY DIRECTION BUT THIS ONE ? BNE 40$ ;YES, CAN'T MOVE IN THIS DIRECTION CLR GNMDW ;FIRST MOVES WILL BE SIMPLE 10$: ADD (R3),R2 ;GET NEW POSITION MOV (R2),R1 ;GET VALUE OF TO SQUARE BNE 30$ ;NOT EMPTY CALL GNSTR ;SAVE IT BR 10$ 30$: CMP R1,#OFF ;IS IT OFF THE BOARD ? BEQ 40$ ;YES ADD COLR,R1 ;MY PIECE ? BPL 40$ ;YES, CAN'T CAPTURE IT MOV #CAPTUR,GNMDW ;SET CAPTURE BIT CALL GNSTR ;STICK THE GENERATED MOVE IN THE STACK 40$: TST -(R3) ;NEXT MOVE DIRECTION BNE LINE ;YES JMP NXTSQR ;NO, DO NEXT PIECE .SBTTL MOVE GENERATOR SUBROUTINES ; PAWN PUSH PST: ADD PONDIR,R2 ;INCREMENT THE MOVING PAWN'S RANK TST (R2) ;ANYTHING THERE ? BNE BADPM ;YES, ILLEGAL MOVE TST DOUBLE ;WAS IT A DOUBLE PAWN MOVE ? BEQ PROMCK ;NO, TEST FOR PROMOTION MOV R2,R1 ;GET THE TO ADDRESS SUB #BOARD+42.,R1 ;GET DISPLACEMENT INTO BOARD ASR R1 ;IT MUST FIT INTO 7 BITS MOVB R1,GNMDW+1 ;SAVE TO ADDRESS IN MDW FOR ENPASSANT STUFF BR PMSTOR ;NO PROMOTION POSSIBLE ; PAWN PROMOTION PROMCK: MOV R2,R1 ;COPY THE TO ADDRESS ADD PONDIR,R1 ;MOVE PAWN AGAIN CMP (R1),#OFF ;IS IT OFF THE BOARD ? BNE PMSTOR ;NO, NO PROMOTION BIS #PROMN,GNMDW ;POSSIBLE PROMOTIONS ARE : CALL GNSTR ;PROMOTION TO KNIGHT INC GNMDW CALL GNSTR ;PROMOTION TO BISHOP INC GNMDW CALL GNSTR ;PROMOTION TO ROOK INC GNMDW PMSTOR: CALL GNSTR ;STORE LEGAL PUSH OR PROMOTION TO QUEEN SEZ ;MOVE WAS OK BADPM: RTS PC ; PAWN CAPTURES CAPTST: MOV (R2),R1 ;WHAT'S THERE ? BEQ NOCAP ;CAN'T CAPTURE OFF THE BOARD CMP R1,#OFF ;OFF THE BOARD ? BEQ NOCAP ;YES, NO CAPTURE ADD COLR,R1 ;MY PIECE ? BPL NOCAP ;YES, NO CAPTURE MOV #CAPTUR,GNMDW ;SET "CAPTURE" BIT TST COLR ;WHICH COLOR ? BEQ 10$ ;WHITE, POINTER OK INC R3 ;BLACK, MOVE POINTER TO BLACK'S PIN MASK 10$: BITB (R3),PINS(R0) ;IS PAWN PINNED IN ANY DIRECTION BUT THIS ONE ? BEQ PROMCK ;NO, CAPTURE IS OK NOCAP: RTS PC ;PINNED PAWN ; ENPASSANT CAPTURES ENPCHK: MOV -(R0),R3 ;GET VALUE OF POSSIBLE ENPASSANT CAPTURER ADD COLR,R3 ;IS IT MY PAWN ? CMP R3,#PAWN BNE 20$ ;NO, FORGET CAPTURE TST COLR ;WHICH COLOR ? BEQ 10$ ;WHITE, PIN MASK ADDRESS IS OK INC R4 ;BLACK, BUMP POINTER 10$: BITB (R4),PINS(R0) ;IS PIECE PINNED IN ANY OTHER DIRECTION ? BNE 20$ ;YES, CAN'T MOVE MOV (R0),(R2) ;MOVE THE CAPTURING PAWN CLR (R0) ;DELETE THE OLD COPY CLR (R1) ;REMOVE THE CAPTURED PAWN CALL GENATK ;GENERATE ATTACKS WITH BOTH PAWNS MOVED MOV (R2),(R0) ;MOVE MY PAWN BACK MOV (R2),(R1) ;AND PUT BACK ENEMY'S PAWN ADD #BLACK,(R1) ;OPPOSITE COLOR TO MINE CLR (R2) ;REMOVE EXTRA PAWN MOV CKING,R3 ;GET KING'S ADDRESS TSTB AC(R3) ;ANY ATTACKS ON HIM AFTER MOVE ? BNE 20$ ;YES, MOVE IS ILLEGAL CALL GNSTR ;OK, ADD IT TO THE LIST 20$: RTS PC ; CASTLING CASCHK: TST (R2)+ ;FIRST SEE IF ITS OCCUPIED BNE 10$ ;YES, ILLEGAL CASTLE TSTB AC-2(R2) ;IS SQUARE ATTACKED ? 10$: RTS PC ;RETURN ANSWER IN COND CODES ; MOVE SAVER GNSTR: TST GNCHEK ;IS THE KING IN CHECK ? BEQ GNSTRX ;NO BIT #CK.BLK,PINS(R2);YES, DOES THIS MOVE BLOCK OR CAPTURE ? BEQ NOMOVE ;NO, ILLEGAL GNSTRX: INC GNCNT ;INCREMENT THE COUNT OF GENERATED MOVES TST BOGUS ;DO WE ACTUALLY SAVE 'EM ? BNE NOMOVE ;NO, TRIAL RUN MOV R0,-(R5) ;SAVE FROM ADDRESS MOV R2,-(R5) ;AND TO ADDRESS MOV GNMDW,-(R5) ;SAVE MOVE DATA WORD NOMOVE: RTS PC .SBTTL ATTACK/DEFENCE BOARD GENERATOR ; GENERATE DEFENCE BOARD DEFGEN: MOV #DEFENC,ATKSUB ;SET UP SUBR POINTER MOV #DB+42.,R3 ;AND BOARD POINTER FOR CLEAR BR ATKDEF ;JUMP TO COMMON CODE ; GENERATE ATTACK BOARD (SAVE REGISTERS ENTRY) GENATK: SAVE ;SAVE REGS FOR CALLS FROM ENPASSANT OR KING MOVE ROUTINE MOV OMAP,R4 ;SET UP POINTER TO ATTACKER'S MAP ; GENERATE ATTACK BOARD ATKGEN: MOV #ATTACK,ATKSUB ;SET UP SUBR POINTER MOV #AB+42.,R3 ;CLEAR ATTACK BOARD ; GENERATE ATTACK/DEFENCE BOARD ATKDEF: MOV #78.,R1 ;78. SQUARES TO DO MOV #KING+1,R0 ;SET TO VALUE GT KING (FOR MIN) 1$: MOV R0,(R3)+ ;SET LEAST VALUED PIECE TO KING+1 DEC R1 BNE 1$ MOV R5,-(SP) ;SAVE R5 2$: MOV (R4)+,R2 ;GET ADDRESS OF AN ATTACKER BNE 5$ ;NOT FINISHED MOV (SP)+,R5 ;RESTORE R5 RTS PC 5$: MOVB (R2),R5 ;GET PIECE INDEX JMP 10$(R5) ;BRANCH ON PIECE TYPE 10$: BR 2$ ;EMPTY BR 15$ ;PAWN BR 40$ ;KNIGHT BR 25$ ;BISHOP BR 20$ ;ROOK BR 30$ ;QUEEN BR 35$ ;KING BR 2$ ;OFF 15$: MOV R2,R0 ;YES, GET ADDRESS OF PAWN'S ATTACK SQUARES SUB PONDIR,R0 ;(PONDIR SET FOR ATTACKEE'S PAWNS) TST (R0)+ ;TRY THE HIGH FILE FIRST CALL @ATKSUB ;SEE IF ITS AN ATTACKABLE SQUARE SUB #4,R0 ;NOW TRY THE LOW FILE CALL @ATKSUB ;CHECK IT OUT BR 2$ ;FINISHED THIS PAWN 20$: MOV #RLIST,R3 ;DIRECTION LIST BR 32$ ;GO TO LINE MOVER 25$: MOV #BLIST,R3 ;DIRECTION LIST BR 32$ ;GO TO LINE MOVER 30$: MOV #QLIST,R3 ;QUEEN IS 8 WAYS 32$: MOV R2,R0 ;COPY PIECE'S STARTING SQUARE 33$: ADD (R3),R0 ;GET NEXT ATTACKABLE SQUARE CALL @ATKSUB ;SEE IF IT IS AN ATTACKABLE SQUARE TST (R0) ;WAS IT EMPTY ? BEQ 33$ ;YES, KEEP MOVING IN THIS DIRECTION TST -(R3) ;NO, TRY ANOTHER DIRECTION BNE 32$ ;YES, STILL MORE BR 2$ 35$: MOV #QLIST,R3 ;DIRECTION LIST FOR KING BR 44$ 40$: MOV #KNLIST,R3 ;GET MOVE LIST FOR KNIGHTS 44$: MOV R2,R0 ;ATTACKER ADDRESS ADD (R3),R0 ;PLUS MOVE CALL @ATKSUB ;CHECK OUT THE ATTACK TST -(R3) ;ANY MORE MOVES ? BNE 44$ ;YES BR 2$ ;NO, ATTACK FAILS ; UPDATE ATTACK BOARDS ATTACK: INCB AC(R0) ;OK, INCREMENT ATTACKER COUNT CMPB R5,LVA(R0) ;IS THIS ATTACKER LESS VALUABLE ? BGE 10$ ;NO, THE SAME OR MORE MOVB R5,LVA(R0) ;YES, MAKE IT THE NEW LEAST VALUABLE 10$: RTS PC ; UPDATE DEFENCE BOARDS DEFENC: INCB DC(R0) ;INCREMENT DEFENCE COUNT CMPB R5,LVD(R0) ;DEFENDER OF LOWEST VALUE ? BGE 10$ ;NO MOVB R5,LVD(R0) ;YES, SAVE HIS VALUE 10$: RTS PC ; REGISTER SAVER SAV0T5: MOV R1,-(SP) ;SAVE REGISTORS 0 THROUGH 5 MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV R5,-(SP) JSR PC,(R0) ;RETURN AND SETUP FOR THE REGISTOR RESTORE MOV (SP)+,R5 MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 RTS PC .SBTTL SINGLE SQUARE ATTACK/DEFENCE GENERATOR ; LINE MOVING PIECES ATKSQ: SAVE ;SAVE REGS CLR WATAKS ;CLEAR WHITE ATTACK COUNT CLR BATAKS ;AND BLACK ATTACK COUNT MOV #P.R4,R0 ;DIRECTION COUNTER MOV #QLIST,R2 ;MOVE DIRECTION LIST 10$: MOV 6(SP),R3 ;GET SQUARE ADDRESS 15$: ADD (R2),R3 ;MOVE ALONG MOVB (R3),R1 ;GET CONTENTS JMP 20$(R1) ;BRANCH ON PIECE INDEX 20$: BR 15$ ;EMPTY BR 60$ ;PAWN BR 60$ ;KNIGHT BR 30$ ;BISHOP BR 35$ ;ROOK BR 40$ ;QUEEN BR 25$ ;KING BR 60$ ;OFF 25$: MOV R3,R4 ;COPY ATTACKING KING'S ADDRESS SUB (R2),R4 ;MOVE BACK ONE TIME CMP R4,6(SP) ;ORIGIONAL SQUARE ? BEQ 40$ ;YES, ATTACK BR 60$ ;NO 30$: BIT #P.B,R0 ;ON A DIAGONAL ? BNE 40$ ;YES, ATTACK BR 60$ ;NO 35$: BIT #P.R,R0 ;ON A RANK/FILE ? BEQ 60$ ;NO, NO ATTACK 40$: CALL ATKS ;INCREMENT ATTACK COUNT 60$: ASL R0 ;SHIFT THE PIN BIT TST -(R2) ;NEXT MOVE DIRECTION BNE 10$ ;YES ; KNIGHT ATTACKS ATKKN: MOV #KNLIST,R2 ;KNIGHT MOVE DIRECTION LIST 10$: MOV 6(SP),R3 ;GET OBJECT SQUARE ADD (R2),R3 ;PLUS MOVE CMPB (R3),#KNIGHT ;IS IT A KNIGHT BNE 20$ ;NO CALL ATKS ;BUMP COUNT 20$: TST -(R2) ;MORE ? BNE 10$ ;YES ; PAWN ATTACKS ATKPWN: MOV 6(SP),R3 ;OBJECT ADDRESS CMP -22.(R3),#PAWN ;WHITE PAWN ATTACK ? BNE 10$ ;NO INC WATAKS ;YES 10$: CMP -18.(R3),#PAWN ;OTHER ONE ? BNE 20$ ;NO INC WATAKS ;YES 20$: CMP 22.(R3),#BLACK+PAWN ;BLACK PAWN ATTACKS ? BNE 30$ ;NO INC BATAKS ;YES 30$: CMP 18.(R3),#BLACK+PAWN ;OTHER BLACK PAWN ? BNE 40$ ;NO INC BATAKS ;YES 40$: RTS PC ; ATTACK COUNT INCREMENTER ATKS: TST (R3) ;WHAT COLOR ATTACKER ? BPL 10$ ;WHITE INC BATAKS ;BLACK RTS PC 10$: INC WATAKS ;WHITE RTS PC .SBTTL MAKE MOVE MKMV: MOV (SP)+,-(R5) ;SAVE THE RETURN ADDRESS ON STACK 2 INC MOVE ;BUMP MOVE COUNTER INC DOMAP ;A PIECE MAP WILL BE NECESSARY COM WHOSE ;FLIP WHOSE MOVE SWITCH MKMVX=12. ;MKMV LEAVES 6 WORDS ON THE STACK MOV (R2),-(SP) ;SAVE VALUE OF THE CAPTURED SQUARE MOV R3,-(SP) ;SAVE FROM AND TO ADDRESSES MOV R2,-(SP) MOV WPSW,-(SP) ;SAVE PSW'S MOV BPSW,-(SP) MOV LSTMV,-(SP) ;SAVE THE MOVE BEFORE THIS ONE MOVB (R2),R1 ;GET CAPTURED SQUARE'S INDEX MOV VALUE(R1),R1 ;NOW ITS VALUE TST (R2) ;WHAT COLOR ? BPL 5$ ;WHITE, ITS POSITIVE NEG R1 ;BLACK IS NEGATIVE 5$: SUB R1,PW ;DELETE ITS VALUE FROM TOTAL MOV (R3),(R2) ;MOVE THE PIECE CLR (R3) ;EMPTY THE OLD SQUARE MOV MVMDW,R1 ;AND MDW BPL 10$ ;IS IT A CAPTURE ? DEC NPIECS ;YES, DECREMENT PIECE COUNT 10$: MOV R1,LSTMV ;NEXT TIME THIS WILL BE THE PREVIOUS MOVE BIC #177770,R1 ;WAS IT A SPECIAL TYPE MOVE BEQ 32$ ;NO, MOVE IS DONE ASL R1 ;MAKE A WORD DISPLACEMENT JMP 20$-2(R1) ;BRANCH ON MOVE TYPE 20$: BR 35$ ;OOO BR 45$ ;OO BR 55$ ;P#P BR 25$ ;=N BR 25$ ;=B BR 25$ ;=R ;=Q 25$: SUB #4,R1 ;GET NEW PIECE INDEX MOVB R1,(R2) ;INTO BOARD MOV VALUE(R1),R1 ;NEW VALUE SUB #PVALUE,R1 ;MINUS PAWN'S VALUE TST (R2) ;WHAT COLOR WAS THE PAWN ? BPL 30$ ;WHITE NEG R1 ;BLACK, NEGATE ITS VALUE 30$: ADD R1,PW ;ADD ITS VALUE TO THE BOARD VALUE 32$: JMP @(R5)+ ;RETURN 35$: MOV -4(R2),2(R2) ;MOVE THE ROOK CLR -4(R2) ;REMOVE OLD COPY TST 2(R2) ;WHO CASTLED ? BMI 50$ ;BLACK 40$: BIS #CASTLD,WPSW ;SET BIT JMP @(R5)+ ;FINISHED 45$: MOV 2(R2),-2(R2) ;MOVE THE ROOK CLR 2(R2) ;REMOVE OLD COPY TST -2(R2) ;WHO CASTLED ? BPL 40$ ;WHITE 50$: BIS #CASTLD,BPSW ;SET BIT JMP @(R5)+ 55$: MOV #20.,R1 ;GET PAWN MOVE VALUE CMP R3,R2 ;WHICH WAY IS IT MOVING ? BHI 60$ ;TOWARDS LOWER ADDRESSES NEG R1 ;HIGHER, CAPTURED PAWN IS AT LOWER ADDRESS 60$: ADD R2,R1 ;GET CAPTURED PAWN'S ADDRESS TST (R1) ;WHAT COLOR WAS THE CAPTURED PAWN ? BPL 65$ ;WHITE ADD #PVALUE,PW ;BLACK, REMOVE HIS VALUE FROM TOTAL CLR (R1) ;DELETE HIM FROM BOARD JMP @(R5)+ 65$: SUB #PVALUE,PW ;WHITE, REMOVE HIS VALUE FROM TOTAL CLR (R1) ;DELETE HIM FROM THE BOARD JMP @(R5)+ .SBTTL UNMAKE MOVE UNMV: MOV (SP)+,-(R5) ;SAVE THE RETURN ADDRESS DEC MOVE ;DECREMENT MOVE COUNTER INC DOMAP ;PIECE MAP IS NECESSARY COM WHOSE ;FLOP WHOSE MOVE IS IT SWITCH MOV LSTMV,R1 ;MDW OF THE MOVE TO UNMAKE MOV (SP)+,LSTMV ;RESTORE MDW OF PREVIOUS MOVE MOV (SP)+,BPSW ;RESTORE PSW'S MOV (SP)+,WPSW MOV (SP)+,R2 ;RESTORE TO ADDRESS OF MOVE TO UNMAKE MOV (SP)+,R3 ;RESTORE FROM ADDRESS MOV (R2),(R3) ;MOVE THE PIECE BACK MOV (SP)+,(R2) ;RESTORE VALUE OF CAPTURED SQUARE MOVB (R2),R4 ;INDEX OF OLD VALUE MOV VALUE(R4),R4 ;OLD VALUE TST (R2) ;WHAT COLOR BPL 5$ ;WHITE NEG R4 ;BLACK 5$: ADD R4,PW ;ADD BACK TO TOTAL MOV R1,MVMDW ;RESTORE MOVE DATA WORD BPL 10$ ;UN-CAPTURING ? INC NPIECS ;YES, UP PIECE COUNT 10$: BIC #177770,R1 ;WAS IT A SPECIAL MOVE ? BEQ 32$ ;NO, FINISHED ASL R1 ;GET A WORD DISPLACEMENT JMP 20$-2(R1) ;BRANCH ON MOVE TYPE 20$: BR 40$ ;OOO BR 35$ ;OO BR 45$ ;P#P BR 25$ ;=N BR 25$ ;=B BR 25$ ;=R ;=Q 25$: MOV VALUE-4(R1),R1 ;VALUE OF DEMOTING PIECE SUB #PVALUE,R1 ;MINUS PAWN VALUE MOVB #PAWN,(R3) ;RESTORE PAWN TO BOARD TST (R3) ;WHAT COLOR ? BPL 30$ ;WHITE NEG R1 ;BLACK IS NEGATIVE 30$: SUB R1,PW ;SUBTRACT FROM TOTAL 32$: JMP @(R5)+ 35$: MOV -2(R2),2(R2) ;PUT THE ROOK BACK CLR -2(R2) ;DELETE THE EXTRA ONE JMP @(R5)+ 40$: MOV 2(R2),-4(R2) ;PUT THE ROOK BACK CLR 2(R2) ;DELETE THE EXTRA ONE JMP @(R5)+ 45$: MOV #20.,R1 ;GET PAWN MOVE VALUE CMP R3,R2 ;WHICH WAY DID THE CAPTURER MOVE ? BHI 50$ ;TO A LOWER NEG R1 ;TO A HIGHER, CAPTURED PAWN IS LOWER 50$: ADD R2,R1 ;GET ADDRESS OF CAPTURED PAWN MOV (R3),(R1) ;PUT IN THE CAPTURING PAWN ADD #BLACK,(R1) ;SWITCH ITS COLOR TST (R1) ;WHAT COLOR IS IT ? BPL 55$ ;WHITE SUB #PVALUE,PW ;BLACK, ADJUST TOTAL JMP @(R5)+ 55$: ADD #PVALUE,PW JMP @(R5)+ .SBTTL MAP PIECES MAPEC: TST DOMAP ;MAP NECESSARY (IE PIECES HAVE MOVED) BEQ 40$ ;NO CLR DOMAP ;MAP IS OK CLR WKING ;IN CASE KING GETS LOST CLR BKING ;BOTH OF 'EM MOV #BOARD+198.,R2 ;ADDRESS OF END OF BOARD MOV #BLKMAP,R1 ;BLACK'S PIECE MAP GOES HERE MOV #WHTMAP,R0 ;AND WHITE'S GOES HERE MOV #78.,R3 ;78 SQUARES TO CHECK 10$: MOV -(R2),R4 ;GET THE SQUARE VALUE BMI 45$ ;ITS A BLACK PIECE JMP 15$(R4) ;BRANCH ON PIECE 15$: BR 30$ ;EMPTY BR 25$ ;WP BR 25$ ;WN BR 25$ ;WB BR 25$ ;WR BR 25$ ;WQ BR 20$ ;WK BR 30$ ;OFF 20$: MOV R2,WKING ;SAVE ADDRESS OF WHITE KING 25$: MOV R2,(R0)+ ;SAVE WHITE PIECE ADDRESSES 30$: CLR PINS(R2) ;CLEAR CORRESPONDING PIN BOARD SQUARE DEC R3 ;ANY MORE SQUARES ?? BNE 10$ ;YES 32$: CLR (R0)+ ;END OF WHITE'S MAP CLR (R1)+ ;END OF BLACK'S MAP 40$: RTS PC 45$: MOVB R4,R4 ;MAKE IT POSITIVE JMP 50$(R4) ;BRANCH ON PIECE INDEX 50$: BR 65$ ;EMPTY BR 60$ ;BP BR 60$ ;BN BR 60$ ;BB BR 60$ ;BR BR 60$ ;BQ BR 55$ ;BK BR 65$ ;OFF 55$: MOV R2,BKING ;SAVE ADDRESS OF BLACK KING 60$: MOV R2,(R1)+ ;SAVE ADDRESSES OF BLACK PIECES 65$: CLR PINS(R2) ;CLEAR PIN BOARD SQUARE DEC R3 ;ANY MORE ? BNE 10$ ;YES BR 32$ ;NO .SBTTL MOVE ANALYSIS ENTRY POINTS ; LOOK AHEAD TOP LEVEL ENTRY POINT LOOK: MOV #-32767.,CVAL ;PREVENT PLY 1 PRUNING CLR PLY ;SET INITIAL PLY LEVEL CLR MOB0 ;CLEAR THE MOBILITIES CLR MOB1 CLR MOBMOD MOV NPIECS,TOPNP ;SAVE NUMBER OF PIECES AT THE TOP CALL KTOK ;GET KING TO KING DISTANCE MOV R1,TOPK2K ;SAVE IT AT THE TOP .IF NE,THINKA CLR REXIT ;CLEAR EXIT REASON .ENDC .IF NE,STATS CLR ECOUNT ;CLEAR THE STATIC EVALUATION COUNTER CLR COUNTE ;CLEAR STATIC EVAL COUNT FOR PRE-ANALYSIS CALL LOOKA ;CALL THE LOOK AHEAD ROUTINE .IF NE,THINKA TST REXIT ;WHY DID WE EXIT ? BNE 10$ ;NOT NORMAL .ENDC MOV ECOUNT,ECOUNT+2 ;TRANSFER THE EVALUATION COUNTS MOV COUNTE,COUNTE+2 10$: RTS PC .ENDC ; LOOK AHEAD RECURSIVE ENTRY POINT LOOKA: .IF NE,THINKA ; THINK AHEAD EXIT CODE TST THINK ;ARE WE IN THINKA AHEAD MODE ? BEQ 50$ ;NO, PROCEED TST REXIT ;IN EXPRESS EXIT MODE ? BNE 40$ ;YES, KEEP GOING CALL GETCX ;SEE IF ANYTHING TYPED YET BCS 50$ ;NO, KEEP THINKING CALL GETC ;YES, BUILD A COMMAND MOV R0,R1 CALL GETC SWAB R0 BIS R1,R0 ;OF TWO CHARACTERS MOV R0,CHRONE ;AND SAVE IT AGAIN MOV #COMLST,R1 ;COMMAND LIST POINTER 10$: MOV (R1)+,R2 ;NEXT COMMAND BEQ 20$ ;END OF LIST CMP R2,R0 ;IS IT THE COMMAND GIVEN ? BNE 10$ ;NO INC REXIT ;YES, LEGITIMATE COMMAND, MUST EXIT RTS PC 20$: CALL INMV ;NO COMMAND, TRY FOR A MOVE BCC 30$ ;GOOD MOVE CALL FLUSH ;GARBAGE, FLUSH THE REST BR 50$ ;KEEP THINKING 30$: .IF NE,TIMER CALL CLOKIT ;CLOCK THE MOVE .ENDC CALL FLUSH ;FLUSH REST OF MOVE TST IKNEW ;WAS MOVE INPUT THE GUESSED ONE ? BNE 45$ ;YES, WE'RE THINKING ALONG THE RIGHT TRACK DEC REXIT ;NO, DO AN EXPRESS EXIT 40$: RTS PC 45$: CLR THINK ;HIS MOVE IS MADE, DON'T INTERRUPT ME AGAIN 50$: .ENDC ; PUSH LOCAL VARIABLES INC PLY ;INCREMENT THE PLY NUMBER MOV GNCHEK,-(SP) ;SAVE UPPER CHECK COUNT MOV UVAL,-(SP) ;PUSH BOARD VALUE OF UPPER LEVEL MOV CVAL,UVAL ;MAKE CURRENT BOARD VALUE UPPER VALUE MOV MOB0,-(SP) ;SAVE MOBILITY OF 2 LEVELS UP MOV MOB1,MOB0 ;BUMP ALL MOBILITIES BY ONE LEVEL MOV MOBMOD,MOB1 CLR MOBMOD ;CURRENT MOBILITY IS 0 CMP PLY,DEPTH ;HOW DEEP ARE WE ? BLE 60$ ;NOT DEEP ENOUGH, KEEP LOOKING ; LOOK AHEAD EXTENSION ON CHECK CMP PLY,MDEPTH ;PAST ABSOLUTE MAX ? BGT STATIC ;YES, NO EXTEND TST GNCHEK ;WAS LAST MOVER CHECKED ? BEQ STATIC ;NO, DON'T EXTEND 60$: JMP LKFUR ;YES, EXTEND LOOK AHEAD .SBTTL STATIC BOARD EVALUATION ; THE STATIC BOARD VALUE IS COMPUTED POSITIVE WITH RESPECT TO WHITE ; AND THEN SIGN FIXED POSITIVE WITH RESPECT TO THE ATTACKER JUST ; BEFORE THE HANGING PIECE ANALYSIS STATIC: .IF NE,STATS INC ECOUNT ;INCREMENT STATIC EVALUATION COUNT .ENDC ; CALCULATE MOBILITY FACTOR MOBGET: TST GNCHEK ;WAS KING IN CHECK BEFORE MOVE JUST MADE ? BNE 10$ ;YES, RECOMPUTE MOBILITY THE LONG WAY MOV MOB0,R0 ;ANY PREVIOUS GOOD MOBILITY INFO ? BNE 20$ ;YES, SAVE SOME TIME 10$: INC BOGUS ;DON'T SAVE THE MOVES GENERATED CALL GNBMV ;BLACK'S MOBILITY MOV MOBMOD,-(SP) ;SAVE IT INC BOGUS ;AGAIN, DON'T SAVE THE GENERATED MOVES CALL GNWMV ;NOW WHITE'S MOBILITY MOV MOBMOD,R0 ;WHITE'S MOBILITY SUB (SP)+,R0 ;MINUS BLACK'S BR 30$ ;GOT MOBILITY 20$: SUB MOB1,R0 ;SUBTRACT MOBILITY OF PLY-1 TST WHOSE ;MAKE MOBILITY POS W RESPECT TO WHITE BEQ 30$ ;IT, WHITE IS MOVING NOW NEG R0 ;BLACK IS MOVING, NEGATE IT 30$: .IF NE,TREE CLR STVALU ;CLEAR STATIC VALUE (OUTPUT ONLY) CALL OUTVF ;OUTPUT MOBILITY .ENDC ; OPENING GAME FACTORS : KNIGHT, BISHOP, AND QUEEN DEVELOPMENT CMP MOVE,#OPNING*2 ;SHOULD WE LOOK AT DEVELOPMENT ? BGT CCEV ;NO, TOO FAR INTO THE GAME MOV #BOARD+56.,R1 ;ADDRESS OF WHITE'S BACK RANK MOV #BOARD+196.,R2 ;ADDRESS OF BLACK'S BACK RANK MOV #6,R3 ;CHECK 6 SQUARES IN BACK RANK BREV: CMP -(R1),#KNIGHT ;IS IT AN UNDEVELOPED WHITE KNIGHT ? BEQ 2$ ;YES, LOSE DEVELOPMENT BONUS CMP (R1),#BISHOP ;UNDEVELOPED WHITE BISHOP ? BNE 3$ ;NO 2$: SUB #MD,R0 ;LOSE MINOR PIECE DEVELOPMENT BONUS 3$: CMP -(R2),#BLACK+KNIGHT ;SAME FOR BLACK BEQ 4$ CMP (R2),#BLACK+BISHOP BNE 5$ 4$: ADD #MD,R0 ;EXCEPT WE ADD BONUS 5$: DEC R3 ;ANY MORE ? BNE BREV ;YES MOV #QSQARS,R2 ;EVALUATE QUEEN'S POSITION MOV #6,R1 ;DON'T LIKE HER MAJESTY TO ROAM TO SOON 10$: MOV (R2)+,R1 ;GET SQUARE ADDRESS BEQ 30$ ;END OF LIST CMP (R1),#QUEEN ;IS WHITE'S QUEEN STILL AT HOME ? BNE 20$ ;NO, NOT ON THIS SQUARE ADD #QH,R0 ;YES, BONUS FOR STAYING THERE 20$: CMP 120.(R1),#BLACK+QUEEN ;IS BLACK'S QUEEN AT (OR NEAR) HOME ? BNE 10$ ;NO, NOT ON THIS SQUARE SUB #QH,R0 ;YES, NEGATIVE BONUS BR 10$ ;GO TO NEXT QUEEN HOME SQUARE 30$: .IF NE,TREE CALL OUTVF ;OUTPUT BACK RANK DEVELOPEMENT VALUE .ENDC ; OPENING AND MIDGAME FACTORS : CENTER CONTROL AND CASTLING CCEV: CMP NPIECS,#ENDGAM ;IN ENDGAME YET ? BLE PWNPSH ;YES, ELIMINATE CENTER AND CASTLING, PUSH PAWNS MOV #CSQARS,R2 ;EVALUATE 4 CENTER SQUARES FOR CONTROL 10$: MOV (R2)+,R3 ;GET CENTER SQUARE POINTER BEQ 30$ ;NO MORE CALL ATKSQ ;GET ATTACKS ON THE SQUARE CMP WATAKS,BATAKS ;WHO HAS MORE ? BEQ 18$ ;NO ONE BGT 16$ ;WHITE SUB #CC,R0 ;BLACK BR 18$ 16$: ADD #CC,R0 ;ADD BONUS FOR CENTER CONTROL 18$: TST (R3) ;WHO OCCUPIES THE SQUARE ? BEQ 10$ ;NO ONE, NO POINTS FOR OCCUPATION BMI 20$ ;BLACK ADD #CO,R0 ;WHITE, ADD OCCUPATION BONUS BR 10$ 20$: SUB #CO,R0 ;BLACK, SUBTRACT OCCUPATION BONUS BR 10$ 30$: .IF NE,TREE CALL OUTVF ;OUTPUT CENTER OCCUPATION VALUE .ENDC BIT #CASTLD,WPSW ;HAS WHITE CASTLED ? BEQ 50$ ;NO ADD #OO,R0 ;YES, ADD CASTLING BONUS 50$: BIT #CASTLD,BPSW ;HAS BLACK CASTLED ? BEQ EXVALU ;NO, GET THE EXCHANGE VALUE SUB #OO,R0 ;YES, SUBTRACT CASTLING BONUS BR EXVALU ;GO ADD IN EXCHANGE VALUE ; ENDGAME FACTORS : PAWN ADVANCEMENT AND KING SEPARATION PWNPSH: MOV #WHTMAP,R4 ;WHITE'S PIECE MAP POINTER 10$: MOV (R4)+,R2 ;GET NEXT PIECE ADDRESS BEQ 20$ ;WHITE IS FINISHED CMP (R2),#PAWN ;IS IT A PAWN ? BNE 10$ ;NO CMP 20.(R2),#BLACK+PAWN ;IS IT BLOCKED BY A PAWN ? BEQ 10$ ;YES, DON'T ADD A BONUS ADD PWNVAL(R2),R0 ;OK, ADD PAWN ADVANCEMENT VALUE BR 10$ 20$: MOV #BLKMAP,R4 ;DO IT FOR BLACK 30$: MOV (R4)+,R2 BEQ KINGD ;GO LOOK AT KING SEPARATION CMP (R2),#BLACK+PAWN BNE 30$ CMP -20.(R2),#PAWN BEQ 30$ ADD PWNVAL(R2),R0 ;SUBTRACT PAWN ADVANCEMENT BONUS SUB #7*PP,R0 ;REMEMBER PAWN PUSH BOARD IS BACKWARDS BR 30$ KINGD: .IF NE,TREE CALL OUTVF ;OUTPUT PAWN PUSH VALUE .ENDC CALL KTOK ;GET CURRENT KING TO KING DISTANCE SUB TOPK2K,R1 ;CLOSER THAN AT THE TOP ? BGT EXVALU ;NO, NO BONUS NEG R1 ;MAKE IT POSITIVE IMULI KD,R1 ;MULTIPLY BY THE BONUS FACTOR TST PW ;WHO GETS IT ? BEQ EXVALU ;NO ONE BPL 10$ ;WHITE IS AHEAD NEG R1 ;BLACK IS AHEAD 10$: ADD R1,R0 ; FACTORS USED THROUGHOUT THE GAME ; MATERIAL BALANCE EXVALU: .IF NE,TREE CALL OUTVF ;OUTPUT KING DISTANCE OR CASTLING VALUE .ENDC ADD PW,R0 ;ADD IN PIECE VALUE SUM ; ENCOURAGE TRADING IF AHEAD IN MATERIAL MOV #RB,R4 ;GET THE BONUS FOR PIECE NUMBER REDUCTION CMP NPIECS,TOPNP ;FEWER PIECES THAN AT THE TOP ? BGE 20$ ;NO, (CAN'T BE GREATER ?) TST PW ;WHO IS AHEAD ? BEQ 20$ ;NO ONE, NO BONUS BPL 10$ ;WHITE, ADD BONUS NEG R4 ;BLACK, NEGATE BONUS 10$: ADD R4,R0 ;ADD BONUS TO SIDE THAT'S AHEAD 20$: .IF NE,TREE CALL OUTVF ;OUTPUT PIECE VALUE SUM .ENDC TST WHOSE ;WHO IS MOVING NOW BEQ 25$ ;WHITE, SIGN IS OK NEG R0 ;BLACK, FLIP SIGN ; HANGING PIECE ANALYSIS 25$: MOV R0,R1 ;ELIMINATE HANGING PIECE ANALYSIS IF NEG R1 ;THIS SUBTREE WILL BE PRUNED CMP R1,UVAL ;SINCE THE HANGING PIECE VALUE BLE NOHIEP ;CANNOT IMPROVE THE VALUE OF THIS BOARD MOV R0,-(SP) ;SAVE THE STATIC VALUE CALL MAPEC ;MAP IF NECESSARY ; GENERATE DEFENCE BOARD MOV #BLKMAP,R4 ;ASSUME WHITE IS THE ATTACKER (BLACK DEFENDS) MOV #20.,PONDIR ;PONDIR SET OPPOSITE TST WHOSE ;WHO IS REALLY ATTACKING ? BPL 40$ ;WHITE, WE GUESSED CORRECTLY MOV #WHTMAP,R4 ;BLACK, THEN WHITE DEFENDS NEG PONDIR 40$: MOV R4,-(SP) ;SAVE DEFENDER'S PIECE MAP POINTER CALL DEFGEN ; GENERATE ATTACK BOARD MOV #BLKMAP,R4 ;LOADER CAN'T DO REL+REL ADD #WHTMAP,R4 SUB (SP),R4 ;GET ATTACKER'S PIECE MAP NEG PONDIR ;FLIP PAWN MOVE DIRECTION CALL ATKGEN ;GENERATE ATTACK BOARD ; BEGIN THE HANGING PIECE ANALYSIS MOV (SP)+,R4 ;RESTORE DEFENDER'S PIECE MAP POINTER CLR HIEPVL ;CLEAR THE EXCHANGE VALUE CLR HIEPCN ;AND THE HANGING PIECE COUNT NXHANG: MOV (R4)+,R2 ;GET ADDRESS OF NEXT POSSIBLY HANGING PIECE BEQ HIEPDN ;NO MORE CANDIDATES FOR HANGING TSTB AC(R2) ;ANY ATTACKERS ? BEQ NXHANG ;NO, CAN'T BE HANGING MOVB (R2),R1 ;GET PIECE INDEX CMP R1,#KING ;IS IT THE KING ? BEQ NXHANG ;YES, CAN'T BE HANGING MOV VALUE(R1),R1 ;GET VALUE OF PIECE ANALYZ: CMPB AC(R2),DC(R2) ;MORE ATTACKERS THAN DEFENDERS ? BLE CHANCE ;NO, PIECE MAY BE SAFE DECB DC(R2) ;HOW MANY DEFENDERS ? BGT CHANCE ;MORE THAN ONE, PIECE MAY BE SAFE BLT LOSS ;NONE, ITS LOST MOV R1,R0 ;VALUE OF PIECE MOVB LVD(R2),R3 ;INDEX OF DEFENDER ADD VALUE(R3),R0 ;PIECE+DEFENDER MOVB LVA(R2),R3 ;INDEX OF ATTACKER SUB VALUE(R3),R0 ;PIECE+DEFENDER-ATTACKER BLE NXHANG ;NO PROBLEM IF ATTACKER>PIECE+DEFENDER CMPB LVA(R2),LVD(R2) ;COMPARE ATTACKER AND DEFENDER BLT LOSS ;ATTACKER= PIECE ? BGE NXHANG ;YES, PIECE ISN'T LOST (PROBABLY) BR LOSS ;LOST AGAIN HIEPDN: MOV HIEPCN,R0 ;GET COUNT OF HANGING PIECES BEQ 10$ ;WEREN'T ANY DEC R0 ;MINUS ONE (THE WORST ONE) IMULI HPB,R0 ;MULTIPLIED BY THE BONUS FACTOR MOV HIEPVL,R2 ;GET MOST VALUABLE HANGING PIECE ADD R2,R0 ;ADD VALUE OF HANGING PIECE IDIVI HPF+1,R2 ;DIVIDE VALUE BY HPF+1 SUB R2,R0 ;TOTAL PENALTY FOR HANGING PIECES 10$: MOV R0,R1 ;SAVE THE HIEP BONUS ADD (SP)+,R0 ;ADD BACK THE REST OF THE STATIC VALUE .IF NE,TREE CALL OUTV ;OUTPUT THE HIEP BONUS .ENDC CMP R1,#HPEXT ;ENOUGH TO EXTEND ? BLT NOHIEP ;NO CMP PLY,MDEPTH ;TOO DEEP ALREADY ? .IF NE,TREE BGT NOHIEP ;YES, NO EXTEND CMP DEBUG,PLY ;ARE WE TREE PRINTING ? BLT 20$ ;NO INC LPT ;TURN ON THE LP CALL OCRLF ;RETURN THE CARRIAGE CLR LPT ;LP OFF 20$: BR LKFUR ;LOOK FURTHER .IFF BLE LKFUR ;NO, GO AND EXTEND .ENDC NOHIEP: JMP LKDONE ;BRANCH TO LOOKA RETURN CODE ; CALCULATE KING SEPARATION KTOK: CALL MAPEC ;FIND KINGS IF NECESSARY MOV WKING,R2 ;GET THE KING ADDRESSES MOV BKING,R3 MOVB RANK(R2),R4 ;GET THE DIFFERENCE IN RANK MOVB RANK(R3),R1 SUB R4,R1 BPL 10$ ;ALWAYS ABSOLUTE VALUE NEG R1 10$: MOVB FILE(R2),R2 ;GET THE FILE DIFFERENCE MOVB FILE(R3),R3 SUB R2,R3 BPL 20$ ;ALSO ABSOLUTE NEG R3 20$: ADD R3,R1 ;SUM OF DIFFERENCES RTS PC .SBTTL PLAUSIBLE MOVE SELECTION LKFUR: CALL GNMVSM ;GENERATE MOVES FOR MOVING SIDE ; STALEMATE/CHECKMATE TESTS CLR R0 ;CLEAR RETURN VALUE INCASE OF STALEMATE MOV GNCNT,R2 ;ANY MOVES POSSIBLE ? BNE 20$ ;YES, CAN'T BE CM OR SM TST GNCHEK ;WAS KING IN CHECK ? BEQ 10$ ;NO, STALEMATE MOV PLY,R0 ;THE FURTHER AWAY THE MATE SUB #32700.,R0 ;THE BETTER 10$: ADD #6,R5 ;ELIMINATE THE MARKER (NO MOVES EXIST) JMP LKDONE ;RETURN FROM LOOKAHEAD ; SET PARAMETERS FOR PRE ANALYSIS 20$: MOV PLY,R4 ;GET CURRENT PLY CMP R4,DEPTH ;COMPARED TO THE DEPTH BGE NOPREA ;DON'T DO PREANALYSIS AT LAST PLY MOVB WIDTH-1(R4),R1 ;AND ASSOCIATED WIDTH MOV R1,-(SP) ;SAVE WIDTH ;NUMBER OF POSSIBLE MOVES IN R2 CMP R2,R1 ;ARE THERE MORE THAN WIDTH MOVES ? BGE 25$ ;YES, JUST TAKE WIDTH OF THEM MOV R2,R1 ;NO, TAKE ALL OF THEM MOVB R1,WIDTH-1(R4) ;SAVE NEW WIDTH (TEMPORARILY) 25$: MOV DEPTH,-(SP) ;SAVE CURRENT DEPTH MOV R4,DEPTH ;SET DEPTH=PLY (ONLY DO STATIC ANALYSIS) MOV R4,MDEPTH ;NO EXTENDS ON PLAUSIBLITY ANALYSIS 30$: SUB #6,SP ;MAKE ROOM FOR MDW, FROM, AND TO MOV #-32767.,-(SP) ;STICK IN INITIAL VALUE FOR THIS LEVEL DEC R1 ;STACK WILL HOLD THE WIDTH BEST MOVES BNE 30$ ; PRE ANALYSIS: PICK WIDTH(PLY) BEST MOVES PREPIK: MOV (R5)+,MVMDW ;GET NEXT GENERATED MOVE MOV (R5)+,R2 ;MDW, TO, FROM MOV (R5)+,R3 BEQ ENDPRE ;NO MORE MOVES MOV (SP),CVAL ;SET CURRENT VALUE TO VALUE OF WORST MOVE .IF NE,STATS MOV ECOUNT,-(SP) ;SAVE STATIC EVAL COUNTER .ENDC .IF NE,TREE MOV DEBUG,-(SP) ;NO TREE ON PRE-ANALYSIS CLR DEBUG .ENDC CALL MKMV ;MAKE A PRE-ANALYSIS MOVE CALL LOOKA ;DO A STATIC ANALYSIS CALL UNMV ;UNMAKE THE MOVE .IF NE,TREE MOV (SP)+,DEBUG ;RESTORE DEBUG SWITCH .ENDC .IF NE,STATS ADD ECOUNT,COUNTE ;ADD TO PRE-ANALYSIS STATIC EVAL COUNT SUB (SP)+,COUNTE ;MINUS COUNT BEFORE START .ENDC MOV PLY,R4 ;GET THE PLY MOVB WIDTH-1(R4),R1 ;ASSOCIATED WIDTH GIVES NUMBER OF BEST MOVES MOV SP,R4 ;POINTER TO THE BEST MOVE LIST 10$: CMP R0,(R4) ;MAXIMIZE BLE 50$ ;MOVE WORSE THAN CURRENT ONE 20$: CMP R4,SP ;A BETTER MOVE, ARE WE TESTING THE WTH BEST ? BNE 30$ ;NO ADD #10,R4 ;YES, JUST DISCARD PREVIOUS WTH BEST BR 40$ ;GO CHECK (W-1)TH BEST 30$: MOV (R4)+,-12(R4) ;COPY NEXT BETTER MOVE DOWN ONE PLACE MOV (R4)+,-12(R4) MOV (R4)+,-12(R4) MOV (R4)+,-12(R4) 40$: DEC R1 ;DID WE CHECK ALL ? BNE 10$ ;NO ;FALL THROUGH AND PUT THE NEW MOVE INTO ;THE PLACE WE MADE FOR IT 50$: CMP R4,SP ;IS MOVE WORSE THAN WTH BEST ? BEQ PREPIK ;YES, DON'T CONSIDER IT FURTHER MOV MVMDW,-(R4) ;PUT NEW BEST MOVE INTO PLACE MOV R2,-(R4) ;IN REVERSE ORDER FROM MOVE STACK MOV R3,-(R4) ;SO THAT LATER THEY CAN BE MOVED BACK EASILY MOV R0,-(R4) ;DON'T FORGET THE VALUE BR PREPIK ; "BEST" MOVES ISOLATED, RESTORE PARAMETERS AND GO ANALYZE THEM FURTHER ENDPRE: MOV PLY,R4 ;GET PLY MOVB WIDTH-1(R4),R1 ;AND ITS WIDTH SUB #6,R5 ;LEAVE MOVE STACK MARKER MOV #-32767.,CVAL ;RESTORE CURRENT VALUE TO MIN 10$: TST (SP)+ ;PURGE PRE-ANALYSIS VALUE MOV (SP)+,-(R5) ;PUT BEST MOVES ONTO MOVE STACK MOV (SP)+,-(R5) ;FOR FURTHER ANALYSIS MOV (SP)+,-(R5) ;MORE DEEPLY DEC R1 ;ANY MORE ? BNE 10$ MOV (SP),DEPTH ;RESTORE DEPTH ADD #EMAX,(SP) ;AND MAX DEPTH MOV (SP)+,MDEPTH MOV (SP)+,R1 ;GET THE WIDTH MOVB R1,WIDTH-1(R4) ;RESTORE IT BR PICK ;GO DO THE DEEPER ANALYSIS ON THE BEST MOVES .SBTTL FINAL MOVE ANALYSIS AND PRUNING ; NO PRE ANALYSIS, TRY PREVIOUS BEST MOVE FOR THIS PLY NOPREA: MOV #-32767.,CVAL ;SET UP CURRENT VALUE MOV PLY,R4 ;GET THE CURRENT PLY NUMBER ASL R4 ;MAKE PLY NUMBER AN INDEX MOV BSTFRM-2(R4),R0 ;GET BEST MOVE FROM ADDRESS MOV BSTTO-2(R4),R1 ;GET BEST MOVE TO ADDRESS ;NOW SEE IF PREVIOUS BEST MOVE FOR THIS ;LEVEL IS STILL LEGAL. IF SO, MAKE SURE IT ;GETS TRIED FIRST -- POSSIBLY CAUSING THE PRUNING ;TO WIN IF IT IS REALLY A GOOD MOVE MOV R5,R4 ;TOP OF MOVE STACK 100$: MOV (R4)+,MVMDW ;MDW OF THE NEXT MOVE MOV (R4)+,R2 ;AND ITS TO ADDRESS MOV (R4)+,R3 ;AND ITS FROM ADDRESS BEQ PICK ;THE PREVIOUS BEST MOVE ISN'T HERE CMP R3,R0 ;DO THE FROM ADDRESSES MATCH ? BNE 100$ ;NO CMP R2,R1 ;AND THE TO ADDRESSES ? BNE 100$ ;NO SUB #6,R4 ;MOVE BACK A BIT MOV (R5)+,(R4)+ ;SAVE CURRENT FIRST MOVE MOV (R5)+,(R4)+ ;IN THE SLOT OCCUPIED BY THE MOVE MOV (R5)+,(R4)+ ;WE HOPE WILL BE THE BEST (AGAIN) BR PICKED ;NOW TRY IT ; TRY A MOVE, ANALYZE, AND PRUNE IF POSSIBLE PICK: MOV (R5)+,MVMDW ;POP OFF ONE OF THE MOVES GENERATED MOV (R5)+,R2 MOV (R5)+,R3 BEQ LKAD ;NO MORE PICKED: .IF NE,TREE CMP DEBUG,PLY ;SHOULD WE PRINT THE TREE AT THIS PLY ? BLT 10$ ;NO INC LPT ;SET THE "LP FOR OUTPUT" SWITCH CALL TABPLY ;TAB TO THE CORRECT PLACE CALL OUTMV ;PRINT IT CLR LPT ;CLEAR THE LP OUTPUT SWITCH 10$: .ENDC CALL MKMV ;MAKE THE MOVE CALL LOOKA ;EVALUATE THE NEW POSITION CALL UNMV ;UNMAKE THE MOVE CMP R0,CVAL ;NEW "BEST" MOVE ? BLE PICK ;NO, TRY NEXT ONE RPLACE: MOV R0,CVAL ;THIS IS THE NEW BOARD VALUE MOV PLY,R4 ;GET THE PLY ASL R4 ;MAKE IT AN INDEX MOV R3,BSTFRM-2(R4) ;PUT IN THE MOVE AS NEW BEST MOVE MOV R2,BSTTO-2(R4) MOV MVMDW,BSTMDW-2(R4) .IF NE,THINKA CMP R4,#2 ;ARE WE AT PLY 1 ? BNE 10$ ;NO MOV BSTFRM+2,THINKF+2 ;YES, NEW TOP LEVEL BEST MOVE SO... MOV BSTTO+2,THINKT+2 ;SAVE THE NEW BEST RESPONSE MOV BSTMDW+2,THINKM+2 ;UPON WHICH TO BASE THE THINK-AHEAD 10$: .ENDC NEG R0 ;NEGATE SIGN FOR COMPARE WITH UPPER LEVEL CMP R0,UVAL ;DOES NEW BEST MOVE KILL THIS SUBTREE ? BGT PICK ;NO, TRY ANOTHER MOVE FOR THIS SUBTREE ALPHAP: ADD #4,R5 ;POP MOVES UNTIL PARTITION TST (R5)+ BNE ALPHAP ;MORE LKAD: MOV CVAL,R0 ;RETURN THE VALUE ; END OF ANALYSIS ROUTINE, RETURN ONE LEVEL LKDONE: .IF NE,TREE MOV DEBUG,R4 ;ARE WE PRINTING THE TREE ? BEQ 3$ ;ABSOLUTELY NOT INC R4 ;ARE WE PRINTING IT AT THIS PLY ? CMP R4,PLY BLT 3$ ;NO INC LPT ;SET THE LPT OUTPUT SWITCH CALL TABPLY ;YES, TAB TO THE CORRECT PLACE CALL OUTVAL ;NOW PRINT THE NUMBER CALL OCRLF ;DON'T FORGET WHERE WE LEFT THE CARRIAGE CLR LPT ;CLEAR THE LPT OUTPUT SWITCH 3$: .ENDC DEC PLY ;DECREMENT PLY, WE'RE SURFACING CAPTAIN MOV MOB1,MOBMOD ;RESTORE MOBILITIES MOV MOB0,MOB1 MOV (SP)+,MOB0 MOV UVAL,CVAL ;RESTORE VALUE OF CURRENT LEVEL MOV (SP)+,UVAL ;RESTORE VALUE OF UPPER LEVEL MOV (SP)+,GNCHEK ;RESTORE UPPER CHECK COUNT NEG R0 ;NEGATE VALUE ON EACH LEVEL CHANGE RTS PC ;RETURN .SBTTL TREE PRINTING SUBROUTINES ; OUTPUT PLY TABS ON TREE OUTPUT DEVICE .IF NE,TREE TABPLY: SAVE MOV PLY,R1 ;WHAT PLY ARE WE DEC R1 ;DO PLY-1 TABS BLE TABBED ;ALREADY THERE ASL R1 ;*2 ASL R1 ;*4 ASL R1 ;*8 ASL R1 ;*16 1$: CMP COLUMN,R1 ;THERE YET ? BGE TABBED ;YES MOV #40,R0 ;PRINT ANOTHER BLANK CALL OUTC BR 1$ ;AGAIN ; PRINT ANALYSIS VALUE OUTVF: SAVE MOV 14(SP),R0 ;GET THE VALUE TST WHOSE ;WHO IS MOVING ? BEQ VOUT ;WHITE, SIGN IS OK NEG R0 ;BLACK, FLIP SIGN BR VOUT ;GO OUTPUT DIFFERENCE FROM LAST VALUE OUTV: SAVE MOV 14(SP),R0 ;GET THE VALUE VOUT: MOV STVALU,R1 ;GET PREVIOUS PARTIAL SUM MOV R0,STVALU ;SAVE NEW PARTIAL SUM SUB R1,R0 ;GET VALUE OF NEW ELEMENT MOV PLY,R4 ;GET THE PLY DEC R4 ;MINUS ONE CMP DEBUG,R4 ;ARE WE TREE PRINTING ? BLT 10$ ;NO INC LPT ;YES, OUTPUT THIS FACTOR CALL TABPLY ;TAB TO THIS PLY CALL OUTVAL ;A LOT OF USELESS REG SAVING HERE MOV #40,R0 ;OUTPUT MINI-TAB 5$: BIT #3,COLUMN ;MINI-TABBED YET ? BEQ 6$ ;YES CALL OUTC BR 5$ ;BACK FOR MORE 6$: CLR LPT 10$: RTS PC .ENDC ; DECIMAL OUTPUT ROUTINE .IF NE,TREE+STATS+TIMER OUTVAL: SAVE MOV #40,R0 ;SIGN = " " MOV 14(SP),R1 ;GET THE NUMBER BPL 1$ ;NOT NEGATIVE NEG R1 ;MAKE POSITIVE MOV #55,R0 ;PRINT THE MINUS 1$: CALL OUTC ;OUTPUT THE SIGN 2$: MOV R1,-(SP) ;REMAINDER WILL GO ON THE STACK CLR R1 ;DIVIDEND WILL BE BACK IN THE REGISTER 3$: INC R1 ;ASSUME DIVIDE SUCCEEDS SUB #10.,(SP) ;SUBTRACT 10. BGE 3$ ;IT FITS, TRY AGAIN ADD #72,(SP) ;DIDN'T FIT, MAKE IT ASCII DEC R1 ;CORRECT DIVIDEND BEQ 4$ ;IT WAS ZERO, STOP THE RECURSION CALL 2$ ;OK, CONVERT THE DIVIDEND 4$: MOV (SP)+,R0 ;GET THE DIGITS BACK CALL OUTC ;OUTPUT THEM TABBED: RTS PC .ENDC .SBTTL MOVE OUTPUT ; MOVE OUTPUT OUTMV: SAVE .IF NE,BOOKOP .IF NE,TREE TST PLY ;IF OUTPUTTING MOVE AT PLY 0 BNE 10$ ;IT IS THE "LAST" MOVE MADE .ENDC MOV R3,BKFROM ;SAVE THE LAST MOVE MADE MOV R2,BKTO ;FOR THE BOOK MOVE STUFF MOV MVMDW,BKMDW 10$: .ENDC MOV MVMDW,R0 ;GET OUTPUT MOVE'S MDW CLR R4 ;PAWN PROMOTION INDICATOR ZEROED BIC #177770,R0 ;SPECIAL MOVE ? ASL R0 JMP 1$(R0) ;GO TO IT 1$: BR 5$ ;STANDARD MOVE BR 40$ ;OOO BR 45$ ;OO BR 5$ ;P#P BR 2$ ;=N BR 2$ ;=B BR 2$ ;=R ;=Q 2$: ASR R0 ;GET BYTE INDEX MOVB NAMES-3(R0),R4 ;GET PROMOTION NAME 5$: MOVB (R3),R1 ;GET INDEX OF PIECE MOVING CALL PNAME ;PRINT PIECE NAME MOV #'/,R0 ;OUTPUT "/" CALL OUTC CALL OUTSQR ;OUTPUT FROM SQUARE MOV #'-,R0 ;OUTPUT "-" BIT #CAPTUR,MVMDW ;WAS IT A CAPTURE ? BEQ 30$ ;NO MOV #'*,R0 ;YES, OUTPUT * INSTEAD OF - MOVB (R2),R1 ;GET INDEX OF PIECE BEING CAPTURED BNE 20$ MOV #PAWN,R1 ;IF TO SQUARE OF A CAPTURE IS EMPTY, IT MUST BE ENPASSANT MOV #'#,R0 ;CHANGE CAPTURE OPERATOR 20$: CALL OUTC ;OUTPUT OPERATOR (- * OR #) CALL PNAME ;OUTPUT PIECE BEING CAPTURED MOV #'/,R0 ;NOW OUTPUT "/" 30$: CALL OUTC MOV R2,R3 CALL OUTSQR ;THEN TO SQUARE TST R4 ;PAWN PROMOTION ? BEQ 35$ ;NO, FINISHED MOV #'=,R0 ;YES, OUTPUT = CALL OUTC MOV R4,R0 ;NOW TE PROMOTION VALUE CALL OUTC 35$: RTS PC 40$: MOV #'O,R0 ;OUTPUT "O" CALL OUTC 45$: MOV #'O,R0 ;OUTPUT "O" CALL OUTC CALL OUTC ;ANOTHER "O" RTS PC ; OUTPUT SQUARE NAME OUTSQR: MOVB FILE(R3),R1 ;GET THE FILE NUMBER ASL R1 ;MAKE IT A WORD INDEX MOV NAME(R1),R0 ;GET THE FILE NAME CMPB R0,#' ;IS IT A SPACE (K OR Q FILE) BEQ 25$ ;YES, DON'T PRINT IT CALL OUTC ;OUTPUT FIRST CHARACTER OF FILE 25$: SWAB R0 ;GET THE SECOND CHAR CALL OUTC ;OUTPUT IT MOV RANK(R3),R0 ;GET THE RANK NUMBER TST WHOSE ;WHOSE MOVE ? BEQ 30$ ;WHITE'S COM R0 ;FLIP THE RANK NUMBER 30$: BIC #177770,R0 ADD #61,R0 ;MAKE IT "1" THROUGH "8" CALL OUTC ;PRINT IT RTS PC ; PRINT A MESSAGE PRINT: MOVB (R1)+,R0 ;GET CHAR TO PRINT BEQ OCRLF ;0 MEANS OUTPUT CR/LF BMI ODONE ;NEGATIVE MEANS NO CR/LF CALL OUTC ;PRINT THE CHAR BR PRINT ; PRINT A CR/LF OCRLF: SAVE MOV #15,R0 ;PRINT CR/LF CALL OUTC MOV #12,R0 CALL OUTC JSR PC,SEND .IF NE,TREE CLR COLUMN ;CLEAR THE COLUMN COUNTER FOR TABS .ENDC ODONE: RTS PC .SBTTL BOARD DISPLAY ; OUTPUT BOARD TO CONSOLE DISPLY: MOV #BOARD+182.,R4 ;ADDRESS OF BOARD MOV #8.,R3 ;NUMBER OF RANKS = 8 10$: MOV #8.,R2 ;NUMBER OF FILES = 8 20$: MOV #' ,R0 ;PRINT A SPACE CALL OUTC MOV #'W,R0 ;ASSUME PIECE IS WHITE MOV (R4)+,R1 ;GET SQUARE VALUE BEQ 50$ ;EMPTY SQUARE BPL 30$ ;ITS WHITE MOVB R1,R1 ;COLOR KILLER MOV #'B,R0 ;PUT "B" INTO R0 30$: CALL OUTC ;OUTPUT THE COLOR CALL PNAME ;OUTPUT THE PIECE NAME 40$: DEC R2 ;MORE FILES ? BNE 20$ ;YES CALL OCRLF ;NO, RETURN THE CARRIAGE SUB #36.,R4 ;GET TO START OF NEXT RANK DEC R3 ;MORE RANKS ? BNE 10$ ;YES RTS PC ;DONE 50$: MOV #'-,R0 ;ASSUME WHITE SQUARE MOV R3,R1 ;GET THE RANK IN 8'S COMPLEMENT ADD R2,R1 ;ADD IN THE FILE IN 8'S COMPLEMENT ROR R1 ;ODD OR EVEN ? BCC 60$ ;EVEN SQUARE, PRINT -- MOV #'*,R0 ;PRINT -- OR ** 60$: CALL OUTC CALL OUTC BR 40$ ; OUTPUT PIECE NAME PNAME: ASR R1 ;BYTE INDEX MOVB NAMES-1(R1),R0 ;GET THE PIECE NAME CALL OUTC ;PRINT IT RTS PC .SBTTL SYSTEM DEPENDENT SUBROUTINES ; GET A CHARACTER FROM CONSOLE GETC: MOVB CHRONE,R0 ;IS THE FIRST CHAR STILL THERE ? BEQ 1$ ;NO, USED IT CLRB CHRONE ;ITS USED NOW RTS PC 1$: MOVB CHRONE+1,R0 ;WHAT ABOUT THE SECOND CHAR ? BEQ 2$ ;ITS USED ALSO CLRB CHRONE+1 ;ITS USED NOW RTS PC 2$: .IF NE,SOLO TST LSTAT ;LINE AVAILABLE ? BNE 50$ ;YES 10$: TSTB @#177560 ;CHARACTER AVAILABLE ? BPL 10$ ;NO, HANG MOVB @#177562,R0 ;GET THE CHARACTER BIC #177600,R0 ;SEVEN BITS CMP R0,#15 ;END OF LINE ? BNE 20$ ;NO CALL OUTC ;OUTPUT CR MOV #12,R0 CALL OUTC ;OUTPUT LF MOVB R0,@BUFPTR ;PUT INTO BUFFER INC LSTAT ;SET LINE PRESENT SWITCH MOV #INBUF,BUFPTR ;SET POINTER TO BUFFER START BR 50$ 20$: CMP R0,#177 ;RUBOUT ? BNE 30$ ;NO CMP BUFPTR,#INBUF ;AT THE START ? BLOS 10$ ;YES, DFON'T BACKUP DEC BUFPTR ;NO, BACKUP MOVB @BUFPTR,R0 ;GET CHACACTER FROM BUFFER CALL OUTC ;PRINT IT BR 10$ 30$: CMP R0,#140 ;LOWER CASE ? BLE 40$ ;NO SUB #40,R0 ;YES, MAKE UPPER 40$: CALL OUTC ;OUTPUT CHARACTER MOVB R0,@BUFPTR ;SAVE IT INC BUFPTR ;BUMP POINTER BR 10$ ;GET ANOTHER 50$: MOVB @BUFPTR,R0 ;GET CHARACTER FROM BUFFER INC BUFPTR ;BUMP POINTER CLC .IFF JSR PC,SEND TST KBIBFC BNE PICKCH MOV R1,-(SP) MOV R2,-(SP) MOV #KBIBUF,R1 MOV #IODPB,R2 MOV R1,14(R2) MOV #IO.RLB,2(R2) MOV #80.,16(R2) CLR 20(R2) DIR$ R2 WTSE$S #1 MOV IOSB+2,R2 MOV R1,KBIBFN ADD R2,R1 MOVB #12,(R1) INC R2 MOV R2,KBIBFC JSR PC,OCRLF MOV (SP)+,R2 MOV (SP)+,R1 PICKCH: MOVB @KBIBFN,R0 INC KBIBFN DEC KBIBFC RTS PC KBIBFC: .WORD 0 KBIBFN: .WORD KBIBUF KBIBUF: .BLKW 40. KBOBFC: .WORD 0 KBOBFN: .WORD KBOBUF KBOBUF: .BLKW 40. IODPB: QIO$ 0,5,1,,IOSB,,<0,0,0,0,0,0> IOSB: .WORD 0,0 .ENDC RTS PC ; TEST IF CHARACTER AVAILABLE FROM CONSOLE GETCX: SEC RTS PC ;YES, RETURN WITH CARRY CLEAR 10$: .IF NE,SOLO TSTB @#177560 ;ANY CHARS WAITING ? BMI 20$ ;YES SEC ;NO, SET CARRY 20$: RTS PC .IFF BIS #100,@#44 ;SET SPECIAL JSW BIT .TTINR ;GET CHAR IF THERE IS ONE BIC #100,@#44 ;CLEAR SPECIAL BIT BCS 20$ ;NO CHARACTER WAITING MOVB R0,CHRONE ;SAVE CHAR IN OUR BUFFER 20$: RTS PC .ENDC ; FLUSH INPUT UNTIL END OF RECORD FLUSH: MOV #KBIBUF,KBIBFN ;LOOK FOR LF CLR KBIBFC CLR CHRONE .IF NE,SOLO CLR LSTAT ;SET LINE EMPTY MOV #INBUF,BUFPTR ;RESET BUFFER POINTER .ENDC RTS PC ;OK, BUFFER CLEAN ; OUTPUT A CHARACTER TO THE CONSOLE (LP: IF TREE PRINTING) OUTC: .IF NE,SOLO 10$: TSTB @#177564 ;READY ? BPL 10$ ;NO MOVB R0,@#177566 ;OUTPUT CHAR RTS PC .IFF .IF NE,TREE+HISTOG LPS=177514 ;LINE PRINTER STATUS LPB=177516 ;LINE PRINTER BUFFER INC COLUMN ;INCREMENT THE COLUMN COUNTER CLR LPT ; TEMP CHANGE. *@ TST LPT ;OUTPUT TO LP ? BNE 1$ ;YES 1$: MOV R2,-(SP) MOVB R0,@KBOBFN INC KBOBFN CMPB #12,R0 BEQ 5$ MOV KBOBFN,R2 SUB KBOBUF,R2 CMP #40.,R2 BNE PUTCHX 5$: JSR PC,SEND PUTCHX: MOV (SP)+,R2 RTS PC SEND: MOV R1,-(SP) CMP KBOBFN,#KBOBUF BEQ SENDX MOV #IODPB,R1 MOV #IO.WLB,2(R1) MOV #KBOBUF,14(R1) MOV KBOBFN,16(R1) SUB #KBOBUF,16(R1) CLR 20(R1) DIR$ R1 WTSE$S #1 MOV #KBOBUF,KBOBFN SENDX: MOV (SP)+,R1 RTS PC .IFF .TTYOU ;ONLY TTY: RTS PC .ENDC .ENDC ; EXIT TO SYSTEM COMEX: .IF NE,HISTOG MOV RTCLOK,@#CLKV ;RESTORE CLOCK INT VECTOR .ENDC CALL FLUSH ;FLUSH UNTIL LF .IF NE,GT40 CALL DSTOP ;STOP DISPLAY .ENDC .IF NE,SOLO HALT .IFF EXIT$S ;EXIT TO THE MONITOR .ENDC .IF NE,TIMER ; GET TIME (IN SECONDS) SINCE LAST CALL TIME: .GTIM #TICKS+4,#TICKS ;GET CURRENT TIME (TICKS SINCE MIDNIGHT) MOV TICKS+2,R1 ;ONLY LOOK AT LOW ORDER SUB OTICKS,R1 ;SUBTRACT OLD VALUE MOV TICKS+2,OTICKS ;SAVE NEW VALUE CLR R0 ;RETURN SECONDS HERE 10$: INC R0 ;INCREMENT SECONDS SUB #60.,R1 ;ANOTHER SECOND'S WORTH OF TICKS ? BCC 10$ ;YES RTS PC .ENDC .IF NE,HISTOG ; ISR FOR HISTOGRAM CLOCK ITIME: MOV (SP),HISTO ;GET INTERRRUPTED ADDRESS CMP HISTO,#8192. ;IN CHESS PROGRAM ? BHIS 20$ ;NO, IGNORE ADD (PC),@#HISTO ;ADD START ADDRESS OF HISTOGRAM BLOCK INC @HISTO ;INCREMENT CORRECT COUNTER INC HISTO+2 ;ALSO INCREMENT TOTAL COUNT BCC 20$ ;NO OVERFLOW INC HISTO+4 20$: JMP @RTCLOK ;GO TO THE RT11 CLOCK HANDLER CLKV=100 ;CLOCK INTERRUPT VECTOR ; TURN ON HISTOGRAM CLOCK HISTON: MOV @#CLKV,RTCLOK ;GET RT11 CLOCK HANDLER ADDRESS MOV #ITIME,@#CLKV ;INTERCEPT CLOCK INTERRUPTS RTS PC .ENDC .IF NE,BOOKOP ; READ ROUTINE FOR BOOK OPENINGS READ: TST BKOPEN ;BOOK FILE OPEN YET ? BNE 10$ .LOOKUP #BKLST,#1,#BOOK.D ;OPEN THE BOOK FILE INC BKOPEN ;SET BOOK FILE OPENED FLAG 10$: MOV BOOK,R1 ;GET THE BLOCK NUMBER ASL R1 ASL R1 MOV R1,R2 CLRB R2 SWAB R2 ;DISK BLOCK NUMBER INC R2 ;PLUS 1 TO SKIP CCB OF SAV FILE ASL R1 BIC #177000,R1 ;OFFSET FROM BUFFER START ADD #BKMOVS,R1 ;POINTER TO DESIRED MOVE LIST .READW #BKLST,#1,#BKMOVS,#256.,R2 ;READ THE BLOCK CONTAINING THE MOVES MOV R1,R0 ;COPY POINTER TO DESIRED MOVES MOV (R0)+,R2 ;COUNT OF MOVES 20$: ADD #6,R0 ;SKIP TO NEXT MOVE ADD #BOARD,(R0)+ ;RELOCATE ADDRESSES ADD #BOARD,(R0) DEC R2 ;MORE MOVES ? BNE 20$ ;YES RTS PC .ENDC .SBTTL TABLES AND TEXT STRINGS ; COMMAND LIST AND JUMP TABLE COMLST: .ASCII "PWPBPNBDRESKW=D=P=EX" .IF NE,TREE .ASCII "T=" .ENDC .IF NE,STATS .ASCII "PS" .ENDC .IF NE,HISTOG .ASCII "HI" .ENDC .IF NE,TIMER .ASCII "C=" .ENDC .WORD 0 COMADR: .WORD COMPW .WORD COMPB .WORD COMPN .WORD COMBD .WORD COMRE .WORD COMSK .WORD COMWEQ .WORD COMDEQ .WORD COMPEQ .WORD COMEX .IF NE,TREE .WORD COMTEQ .ENDC .IF NE,STATS .WORD COMPS .ENDC .IF NE,HISTOG .WORD COMHI .ENDC .IF NE,TIMER .WORD COMCEQ .ENDC .WORD COMINM ; MESSAGES CMATE: .ASCIZ "CHECKMATE" SMATE: .ASCIZ "STALEMATE" RESIGN: .ASCIZ "I RESIGN" .IF NE,TIMER FLAG: .ASCIZ "FLAG DROPPED" .ENDC ERROR: .ASCIZ "WHAT?" ILLMOV: .ASCIZ "ILLEGAL MOVE" AMBIG: .ASCIZ "AMBIGUOUS" VERSON: .ASCIZ "CHESS V001I" CHECK: .ASCIZ "CHECK" WDOT: .ASCIM BDOT: .ASCIM .IF NE,STATS ALLM: .ASCIZ " ALL" DEPTHM: .ASCIM WIDTHM: .ASCIM MOVEM: .ASCIM EVALM: .ASCIM .IF NE,TIMER TIMEB: .ASCIM TIMEW: .ASCIM .ENDC MOVESM: .ASCIM .ENDC .EVEN ; FILE NAME LIST NAME: .ASCII "QRQNQB Q KKBKNKR" ; PIECE NAME LIST NAMES: .ASCII "PNBRQK" ; INITIAL BOARD SAVBRD: .REPT 21. .WORD OFF .ENDR .WORD ROOK .WORD KNIGHT .WORD BISHOP .WORD QUEEN .WORD KING .WORD BISHOP .WORD KNIGHT .WORD ROOK .WORD OFF,OFF .REPT 8. .WORD PAWN .ENDR .WORD OFF .REPT 4 .WORD OFF,0,0,0,0,0,0,0,0,OFF .ENDR .WORD OFF .REPT 8. .WORD BLACK+PAWN .ENDR .WORD OFF,OFF .WORD BLACK+ROOK .WORD BLACK+KNIGHT .WORD BLACK+BISHOP .WORD BLACK+QUEEN .WORD BLACK+KING .WORD BLACK+BISHOP .WORD BLACK+KNIGHT .WORD BLACK+ROOK .REPT 21. .WORD OFF .ENDR ; PAWN PUSH VALUE BOARD PVB: .REPT 10. .WORD 0 .ENDR .REPT 10. .WORD PP .ENDR .REPT 10. .WORD PP*2 .ENDR .REPT 10. .WORD PP*3 .ENDR .REPT 10. .WORD PP*4 .ENDR .REPT 10. .WORD PP*5 .ENDR .REPT 10. .WORD PP*6 .ENDR .REPT 10. .WORD PP*7 .ENDR ; PAWN MOVE PIN MASKS PCHFB: .BYTE P.R+P.B1+P.B3+P.B4 .BYTE P.R+P.B1+P.B2+P.B4 PCLFB: .BYTE P.R+P.B2+P.B3+P.B4 .BYTE P.R+P.B1+P.B2+P.B3 ; MOVE INCREMENT LISTS (BACKWARDS) .WORD 0 .WORD 18. .WORD 22. .WORD -18. BLIST: .WORD -22. .WORD 0 .WORD 20. .WORD 2. .WORD -20. RLIST: .WORD -2. .WORD 0 .WORD 18. .WORD 22. .WORD -18. .WORD -22. .WORD 20. .WORD 2. .WORD -20. QLIST: .WORD -2. .WORD 0 .WORD -42. .WORD -38. .WORD -24. .WORD -16. .WORD 16. .WORD 24. .WORD 38. KNLIST: .WORD 42. ; PIN MASKS .WORD 0 .WORD P.B2+P.B4+P.R .WORD P.B1+P.B3+P.R .WORD P.B2+P.B4+P.R .WORD P.B1+P.B3+P.R .WORD 0 .WORD P.R2+P.R4+P.B .WORD P.R1+P.R3+P.B .WORD P.R2+P.R4+P.B .WORD P.R1+P.R3+P.B .WORD 0 .WORD P.B2+P.B4+P.R .WORD P.B1+P.B3+P.R .WORD P.B2+P.B4+P.R .WORD P.B1+P.B3+P.R .WORD P.R2+P.R4+P.B .WORD P.R1+P.R3+P.B .WORD P.R2+P.R4+P.B PINLST: .WORD P.R1+P.R3+P.B ; CENTER SQUARES LIST CSQARS: .WORD BOARD+108. .WORD BOARD+110. .WORD BOARD+128. .WORD BOARD+130. .WORD 0 ; QUEEN HOME SQUARES LIST QSQARS: .WORD BOARD+46. .WORD BOARD+48. .WORD BOARD+50. .WORD BOARD+66. .WORD BOARD+68. .WORD BOARD+70. .WORD 0 ; RANK/FILE BOARD RFB: .BYTE 0,0,0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,0,0,0 .BYTE 1,0,1,1,1,2,1,3,1,4,1,5,1,6,1,7,0,0,0,0 .BYTE 2,0,2,1,2,2,2,3,2,4,2,5,2,6,2,7,0,0,0,0 .BYTE 3,0,3,1,3,2,3,3,3,4,3,5,3,6,3,7,0,0,0,0 .BYTE 4,0,4,1,4,2,4,3,4,4,4,5,4,6,4,7,0,0,0,0 .BYTE 5,0,5,1,5,2,5,3,5,4,5,5,5,6,5,7,0,0,0,0 .BYTE 6,0,6,1,6,2,6,3,6,4,6,5,6,6,6,7,0,0,0,0 .BYTE 7,0,7,1,7,2,7,3,7,4,7,5,7,6,7,7 ; PIECE VALUE TABLE VALUE: .WORD 0 .WORD PVALUE .WORD NVALUE .WORD BVALUE .WORD RVALUE .WORD QVALUE .WORD KVALUE .WORD 0 ; PAWN PROMOTION MDWS PROMDW: .WORD 0 .WORD 0 .WORD PROMN .WORD PROMB .WORD PROMR .WORD PROMQ .WORD 0 .SBTTL IMPURE AREA .IF NE,SOLO INBUF: .BLKB 72. ;INPUT BUFFER BUFPTR: .WORD INBUF ;BUFFER POINTER LSTAT: .WORD 0 ;LINE STATUS .ENDC AB: .BLKW 120. ;ATTACK BOARD ATKSUB: .WORD 0 ;POINTER TO ATTACK OR DEFENC BATAKS: .WORD 0 ;ATTACKS BY BLACK BSTFRM: .BLKW MAXD ;BEST MOVE FROM ADDRESS BLOCK BSTTO: .BLKW MAXD ;BEST MOVE TO ADDRESS BLOCK BSTMDW: .BLKW MAXD ;BEST MOVE MDW BLOCK BKING: .WORD 0 ;ADDRESS OF THE BLACK KING BLKMAP: .BLKW 17. ;BLACK'S PIECE MAP BOARD: .BLKW 120. ;THE PLAYING BOARD (INCLUDES 56. BOUNDARY SQUARESZ) BOGUS: .WORD 0 ;BOGUS MOVES (YES=1 NO=0) .IF NE,BOOKOP BOOK.D: .RAD50 "SY CBOOK SAV" ;BOOK FILE BOOK: .WORD 0 ;CURRENT BLOCK NUMBER IN BOOK BKOPEN: .WORD 0 ;BOOK FILE OPENED = 1 BKMOVS: .BLKW 256. ;BUFFER FOR BOOK FILE BKLST: .BLKW 5 ;EMT ARG LIST FOR BOOK STUFF BKFROM: .WORD 0 ;FROM ADDRESS OF LAST MOVE (FOR BOOK COMPARISON) BKTO: .WORD 0 ;TO ADDRESS OF LAST MOVE BKMDW: .WORD 0 ;MDW OF LAST MOVE .ENDC BPSW: .WORD 0 ;BLACK'S POSITION STATUS WORD CAPIEC: .WORD 0 ;VALUE OF PIECE TO BE CAPTURED (INPUT MOVE) CHRONE: .WORD 0 ;FIRST TWO CHARACTERS INPUT CKING: .WORD 0 ;ADDRESS OF THE HOMETOWN KING FOR THE MOVE GENERATOR .IF NE,TIMER CLOCKW: .WORD 0,0 ;WHITE'S CLOCK CLOCKB: .WORD 0,0 ;BLACK'S CLOCK .ENDC COLR: .WORD 0 ;COLOR FOR MOVE GENERATOR (W=0 B=100000) .IF NE,TREE+HISTOG COLUMN: .WORD 0 ;COLUMN COUNTER FOR TREE OUTPUT .ENDC .IF NE,STATS COUNTE: .WORD 0,0 ;PRE-ANALYSIS STATIC EVALUATION COUNTER .ENDC CPSW: .WORD 0 ;ADDRESS OF CURRENT POSITION STATUS WORD CVAL: .WORD 0 ;CURRENT VALUE OF BOARD DB: .BLKW 120. ;DEFENCE BOARD .IF NE,TREE DEBUG: .WORD 0 ;TREE PRINT OUT LEVEL .ENDC DEPTH: .WORD 0 ;MAXIMUM DEPTH OF LOOK AHEAD DOMAP: .WORD 0 ;PIECE MAP NEEDED (YES=1 NO=0) DOUBLE: .WORD 0 ;DOUBLE PAWN PUSH SWITCH .IF NE,STATS ECOUNT: .WORD 0,0 ;STATIC EVALUATION COUNTER (TOTAL) .ENDC GMAP: .WORD 0 ;ADDRESS OF PIECE MAP FOR MOVE GENERATION GNCHEK: .WORD 0 ;NUMBER OF CHECKS ON THE KING GNCNT: .WORD 0 ;COUNT OF GENERATED MOVES GNMDW: .WORD 0 ;GENERATED MOVE DATA WORD HIEPCN: .WORD 0 ;COUNT OF HANGING PIECES HIEPVL: .WORD 0 ;EXCHANGE LOSS DUE TO AHNGING PIECE .IF NE,HISTOG HISTO: .BLKW 4096. ;HISTOGRAM .ENDC .IF NE,THINKA IKNEW: .WORD 0 ;SET =1 IF INPUT MOVE SAME AS PREDICTED .ENDC IOMDW: .WORD 0 ;MDW FOR INPUT MOVE IOFROM: .WORD 0 ;INPUT MOVE FROM SQUARE IOPIEC: .WORD 0 ;VALUE OF PIECE MOVING IOTO: .WORD 0 ;AND TO SQUARE IOMOVS: .WORD 0 ;POINTER TO LEGAL MOVES FOR INPUT IOBK: .WORD 0 ;BLACK KING'S ADDRESS FOR INPUT IOWK: .WORD 0 ;WHITE KING'S ADDRESS FOR INPUT IOWHO: .WORD 0 ;WHO IS INPUTTING MOVE IOBORD: .BLKW 78. ;COPY OF BOARD FOR INPUT KNGBLK: .WORD 0 ;NUMBER OF KING MOVES BLOCKED BY CHECKS .IF NE,TREE+HISTOG LPT: .WORD 0 ;LPT FOR OUTPUT SWITCH FOR TREE OUTPUT .ENDC LSTMV: .WORD 0 ;MDW FOR LAST MOVE MADE ("LOOKA") MDEPTH: .WORD 0 ;ABSOLUTE MAXIMUM DEPTH MOBMOD: .WORD 0 ;MOBILITY FACTOR (STATIC EVALUATOR) MOB0: .WORD 0 ;MOBILITY OF TWO LEVELS UP MOB1: .WORD 0 ;MOBILITY OF ONE LEVEL UP MOVE: .WORD 0 ;MOVE COUNTER MVMDW: .WORD 0 ;MOVE DATA WORD FOR MOVE MAKER NPIECS: .WORD 0 ;PIECE COUNT OMAP: .WORD 0 ;ADDRESS OF ATTACKERS PIECE MAP FOR ATTACK CHECKER .IF NE,THINKA THINKF: .WORD 0,0 ;COMPUTER'S GUESS AT HUMAN OPONENT'S THINKM: .WORD 0,0 ;NEXT MOVE. USED TO TRY AND THINK AHEAD THINKT: .WORD 0,0 ;ABOUT THE COMPUTER'S NEXT MOVE THINK: .WORD 0 ;=1 IN LOOKA WHEN THINKING AHEAD .ENDC .IF NE,TIMER OTICKS: .WORD 0 ;OLD TICKS (FROM PREVIOUS TIME CALL) .ENDC PINBRD: .BLKW 78. ;PIN BOARD PINCNT: .WORD 0 ;NUMBER OF PINNED PIECES PLY: .WORD 0 ;CURRENT DEPTH OF LOOK AHEAD PONDIR: .WORD 0 ;PAWN DIRECTION (W=20. B=-20.) PW: .WORD 0 ;TOTAL PIECE VALUE OF BOARD .IF NE,THINKA REXIT: .WORD 0 ;EXIT REASON (0=NORMAL 1=COMMAND -1=NON-GUESSED MOVE) .ENDC .IF NE,HISTOG RTCLOK: .WORD 0 ;POINTER TO RT11 CLOCK HANDLER .ENDC .IF NE,STATS STVALU: .WORD 0 ;PARTIAL SUM FOR STATIC VALUE OUTPUT .ENDC .IF NE,TIMER TICKS: .WORD 0,0,0,0 ;CLOCK TICK COUNTER .ENDC TOPK2K: .WORD 0 ;KING TO KING DISTANCE AT TOP TOPNP: .WORD 0 ;PIECE COUNT BEFORE ANALYSIS UVAL: .WORD 0 ;BOARD VALUE OF UPPER LEVEL .IF NE,TIMER WARNT: .WORD 0 ;WARNING TIME .ENDC WATAKS: .WORD 0 ;ATTACKS BY WHITE WHOBLK: .WORD 0 ;WHO PLAYS BLACK (COMPUTER=1 USER=0) WHOSE: .WORD 0 ;WHOSE MOVE (W=0 B=10000) WHOWHI: .WORD 0 ;WHO PLAYS WHITE (COMPUTER=1 USER=0) WHTMAP: .BLKW 17. ;WHITE'S PIECE MAP WIDTH: .BLKB MAXD+1 ;WIDTH TABLE .EVEN WKING: .WORD 0 ;ADDRESS OF THE WHITE KING WPSW: .WORD 0 ;WHITE'S PSW GUARD: ;MOVE LIST .REPT MAXD*40. ;ROOM FOR MAXD PLYS @ 40. MOVES/PLY .WORD -1,-1,-1 ;AND 3 WORDS PER MOVE .ENDR MOVES: .REPT 400. ;PROGRAM STACK .WORD -1 ;MARK IT SO WE CAN SEE MAX USAGE .ENDR STACK: .END START