Index | wersja polska |
Written by dr. Samir Ribić, Sarajevo, Bosnia and Herzegovina, 25. Aug 2014
In 1990 I typed in my first Chess program for Casio fx-8000G. However, I was aware of the limitations that the machine had. The language (let's call it FGL, shortcut of Wikipedia's First Generation Language) was very slow, so it could not go in depth. The algorithm was: look all available moves (except castling and e.p.) and take the best capture or closest field to the center, then (only on level 2) look all the opponent counter moves, and if you lose more than you gain try the next move. It took about 5 minutes thinking per move and about 1 minute to draw the board, because there was no Unplot command. I called this chess Stupido chess, but I promised to myself, one day I will make better chess program. I knew it was possible, ZX-81 had 1K chess, but it was written in then unavailable for casio fx-8000G machine code.
This day is here. H.G.Muller wrote the smallest chess program in C (about 1800 bytes), called Micro-Max, which still knows all the rules (including castling, en passant and pawn promotion), uses alpha-beta search with move ordering heuristics and evaluates material, position and pawn structure. Piotr Piatek discovered machine code programming. So, I manually translated Micro-Max chess to upd1007 assembly language, added graphical presentation, modified some parameters to fit into Casio low memory and processing power, removed transposition tables, converted program to maximal usage of registers. So this chess typically processes about 100-5000 positions in 3-100 seconds per move, and depending on position it can think up to 8 half moves in depth.
How to play? Use the arrow keys to select the piece and press Range. Now move the cursor to the destination field and press Range again. When you want that the calculator makes a move, press Graph. Press AC for leave the program. This simple approach allows you to play Man vs. Computer, Computer vs. Human, Human vs. Human, Computer vs. Computer or matches where Computer temporary replaces Human player.
The program takes about 1870 bytes. Together with startup code, it fills up the complete file editor, and uses graphic printer buffer for recursion, leaving Program editor area intact.
To enter CHESS follow the procedure:
Xmin -10 max 10 scl 1 Ymin -10 max 10 scl 1
Xmin -10 max 10 scl 0 Ymin -10 max 10 scl 0
Ans→B S<2⇒Goto 0 0→M 0.3594→A[42] 1.00419048E41→A[43]~A[44] 1.00419848E41→A[45] 1.0007705E41→A[46] Lbl 0 S=0⇒Goto 1 Range 1,95,0,1,63,0 Cls 8→C Lbl 3 " " Dsz C Goto 3 11→A Lbl 1 53→C 32→D B<0⇒B+2xy32→B Lbl 2 Frac .5B=0⇒Plot A,C Frac .5B≠0⇒Isz M Int .5B→B Isz C C=57⇒49→C Frac ((D-1)÷8)=0⇒Dsz A Dsz D Goto 2 A+8→A 0→S Plot 0,0
(˗5÷9)×(1E˗44)→Z[356]~Z[358]
2→S Hex 423FFF40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 FF4046AA:Prog 0 41472B42:Prog 0 CC006000:Prog 0 0841C800:Prog 0 56920856:Prog 0 83805789:Prog 0 4060452A:Prog 0 5C8041FB:Prog 0 815E82E0:Prog 0 FB835E84:Prog 0 205D85C0:Prog 0 5C87605E:Prog 0 90085E91:Prog 0 02604510:Prog 0 60405060:Prog 0 451D5695:Prog 0 Dec M◿
2→S Hex 42403F40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 0960459A:Prog 0 23912074:Prog 0 40160792:Prog 0 18704016:Prog 0 40CC0142:Prog 0 472C9900:Prog 0 E0991020:Prog 0 4D0A1B89:Prog 0 41FBB5FB:Prog 0 B1FBB2FB:Prog 0 925E93E0:Prog 0 FBB754B5:Prog 0 030AB501:Prog 0 2311037F:Prog 0 40805EB7:Prog 0 017040B3:Prog 0 Dec M◿
2→S Hex 42407F40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 2B900874:Prog 0 40B32396:Prog 0 FE7440B3:Prog 0 5EB70123:Prog 0 82047F40:Prog 0 9B2BB504:Prog 0 7740B354:Prog 0 B1C154B2:Prog 0 E1049777:Prog 0 5EB5022B:Prog 0 93E07440:Prog 0 B35EC10A:Prog 0 88C1442B:Prog 0 B7007C44:Prog 0 F754B103:Prog 0 5CB4035C:Prog 0 Dec M◿
2→S Hex 4240BF40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 A70354B2:Prog 0 0304B080:Prog 0 5CB70356:Prog 0 B0012335:Prog 0 037F40DC:Prog 0 FB925E93:Prog 0 E07040E8:Prog 0 5485035C:Prog 0 92035486:Prog 0 035C9303:Prog 0 128941A0:Prog 0 A7035CA5:Prog 0 03040003:Prog 0 7C44A454:Prog 0 A50304B0:Prog 0 075CA603:Prog 0 Dec M◿
2→S Hex 4240FF40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 5CA00302:Prog 0 B0105CC0:Prog 0 03A2C003:Prog 0 03B0015C:Prog 0 A30356B0:Prog 0 02232603:Prog 0 7F41262C:Prog 0 A0807C41:Prog 0 26E82070:Prog 0 41310AA3:Prog 0 01A2A303:Prog 0 E0305CA0:Prog 0 032BA000:Prog 0 7C44A454:Prog 0 A7035CB0:Prog 0 035EA280:Prog 0 Dec M◿
2→S Hex 42413F40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 5EA1802B:Prog 0 B7007C41:Prog 0 5554B203:Prog 0 0737035C:Prog 0 B0037041:Prog 0 5B54A003:Prog 0 0A300354:Prog 0 B0035CB3:Prog 0 032CB088:Prog 0 7444A12B:Prog 0 87807C41:Prog 0 99A08703:Prog 0 23B0007C:Prog 0 419954B0:Prog 0 03030703:Prog 0 03B00224:Prog 0 Dec M◿
2→S Hex 42417F40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 B0807C41:Prog 0 99548703:Prog 0 03300303:Prog 0 B00224B0:Prog 0 807C4199:Prog 0 FB925E93:Prog 0 202BA603:Prog 0 7F41AB54:Prog 0 B0032307:Prog 0 037441AB:Prog 0 0FB310A0:Prog 0 B3035CA4:Prog 0 03F3B154:Prog 0 B0030327:Prog 0 0304B007:Prog 0 7C41C256:Prog 0 Dec M◿
2→S Hex 4241BF40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 B101FBC0:Prog 0 2BA4007C:Prog 0 41CD5EC0:Prog 0 01034023:Prog 0 FBC02BA6:Prog 0 037F41DB:Prog 0 5EC0010C:Prog 0 402354A4:Prog 0 03040003:Prog 0 0E400374:Prog 0 44A154A4:Prog 0 0304B007:Prog 0 5CC00342:Prog 0 4744A2C0:Prog 0 035C9603:Prog 0 42474CA2:Prog 0 Dec M◿
2→S Hex 4241FF40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 C0035C97:Prog 0 0342472C:Prog 0 2C97807C:Prog 0 4213FB92:Prog 0 5E932054:Prog 0 92635493:Prog 0 83130383:Prog 0 24B4807C:Prog 0 44B354B5:Prog 0 035CB603:Prog 0 54B00323:Prog 0 10037C42:Prog 0 340BB601:Prog 0 2BB6007C:Prog 0 44045F9C:Prog 0 A0F3B52B:Prog 0 Dec M◿
2→S Hex 42423F40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 A6067F42:Prog 0 6354A703:Prog 0 02B0085C:Prog 0 C003A0C0:Prog 0 831A14A3:Prog 0 54B00302:Prog 0 B0085CC0:Prog 0 03A0C083:Prog 0 1B14A3F3:Prog 0 B080A103:Prog 0 80B30380:Prog 0 A70354A5:Prog 0 0306B020:Prog 0 80B00354:Prog 0 A10304B0:Prog 0 8874428C:Prog 0 Dec M◿
2→S Hex 42427F40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 54800302:Prog 0 B00680A2:Prog 0 031A9CBE:Prog 0 2BA6037F:Prog 0 42F156B4:Prog 0 0AF3B554:Prog 0 A70303B0:Prog 0 025CC003:Prog 0 04B08874:Prog 0 42AFA0C0:Prog 0 03032503:Prog 0 7C42B21B:Prog 0 14A354A7:Prog 0 0302B002:Prog 0 5CC00304:Prog 0 B0887442:Prog 0 Dec M◿
2→S Hex 4242BF40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 CAA0C003:Prog 0 0325037C:Prog 0 42CD1B14:Prog 0 A31A14A3:Prog 0 54B00302:Prog 0 200302B0:Prog 0 0104B080:Prog 0 7C42F1A0:Prog 0 B00306B0:Prog 0 0780B003:Prog 0 56B68456:Prog 0 B7031A16:Prog 0 E3549223:Prog 0 54934313:Prog 0 01437C43:Prog 0 1224B280:Prog 0 Dec M◿
2→S Hex 4242FF40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 74431255:Prog 0 9263E102:Prog 0 635CC043:Prog 0 5CC16370:Prog 0 431E5581:Prog 0 43E10143:Prog 0 5CC0235C:Prog 0 C1436045:Prog 0 100F8018:Prog 0 558383E1:Prog 0 03835C81:Prog 0 635C8283:Prog 0 54C0035C:Prog 0 830354C1:Prog 0 035C8403:Prog 0 5494A354:Prog 0 Dec M◿
2→S Hex 42433F40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 95C31A05:Prog 0 C35496A3:Prog 0 5497C31A:Prog 0 05C3E905:Prog 0 C054A203:Prog 0 5C870354:Prog 0 B0035C90:Prog 0 0354B603:Prog 0 5C910360:Prog 0 40506045:Prog 0 1D5C9401:Prog 0 5C9521E9:Prog 0 14A02396:Prog 0 FE7C43B2:Prog 0 2B95E07C:Prog 0 43AC2B27:Prog 0 Dec M◿
2→S Hex 42437F40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 C17443AC:Prog 0 2B30E174:Prog 0 43AC2B90:Prog 0 087443AC:Prog 0 5485C354:Prog 0 86E31216:Prog 0 E3E106E3:Prog 0 9737C0B3:Prog 0 05C054A2:Prog 0 60548301:Prog 0 54842158:Prog 0 9F1340BB:Prog 0 14A05480:Prog 0 0302B006:Prog 0 80A103F3:Prog 0 B080A203:Prog 0 Dec M◿
2→S Hex 4243BF40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 80B00354:Prog 0 A50380A7:Prog 0 0354A403:Prog 0 80B30354:Prog 0 94435495:Prog 0 63131263:Prog 0 7C43F924:Prog 0 B3807443:Prog 0 F99F1580:Prog 0 BB126054:Prog 0 A7035CB1:Prog 0 0356B080:Prog 0 04220306:Prog 0 30035CB2:Prog 0 032BB700:Prog 0 7C4404FB:Prog 0 Dec M◿
2→S Hex 4243FF40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 B7704137:Prog 0 56B00223:Prog 0 26037F44:Prog 0 6C54A323:Prog 0 03B10754:Prog 0 A64303B2:Prog 0 035CC023:Prog 0 0E40432B:Prog 0 C0007444:Prog 0 6E54A703:Prog 0 02B00354:Prog 0 A023F631:Prog 0 04B1075C:Prog 0 A1030F21:Prog 0 23A0A103:Prog 0 03000303:Prog 0 Dec M◿
2→S Hex 42443F40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 B0065CC0:Prog 0 032BC000:Prog 0 74446E54:Prog 0 A10307B0:Prog 0 015CC103:Prog 0 A0C12354:Prog 0 A10307B0:Prog 0 025CC103:Prog 0 A0C1435C:Prog 0 C0230E40:Prog 0 4370446E:Prog 0 FBC054A5:Prog 0 0304B020:Prog 0 06400354:Prog 0 A7230220:Prog 0 23033023:Prog 0 Dec M◿
2→S Hex 42447F40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 5CC0030E:Prog 0 40237C44:Prog 0 952BA605:Prog 0 7F449B0A:Prog 0 A4017044:Prog 0 9B54B003:Prog 0 5CA2032B:Prog 0 A4007C41:Prog 0 43704112:Prog 0 0AA7090C:Prog 0 A77754A7:Prog 0 03033403:Prog 0 7440EB2B:Prog 0 931F7744:Prog 0 C22B93E2:Prog 0 7F44C25E:Prog 0 Dec M◿
2→S Hex 4244BF40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 B5622B93:Prog 0 E07444F4:Prog 0 6045100F:Prog 0 8018FB81:Prog 0 5E82E0FB:Prog 0 835E8420:Prog 0 FB85FB86:Prog 0 5E87805E:Prog 0 90805E91:Prog 0 01604050:Prog 0 60451D5C:Prog 0 92015C93:Prog 0 21E91260:Prog 0 70406C54:Prog 0 92A35493:Prog 0 C31305C3:Prog 0 Dec M◿
2→S Hex 4244FF40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 24B6807C:Prog 0 45091A9A:Prog 0 61549201:Prog 0 54932158:Prog 0 9900E099:Prog 0 10E09920:Prog 0 E09930E0:Prog 0 58BD3700:Prog 0 BD2700BD:Prog 0 1700BD07:Prog 0 0058579E:Prog 0 E9569544:Prog 0 FB870495:Prog 0 7760459A:Prog 0 F8075EB3:Prog 0 021BBA61:Prog 0 Dec M◿
2→S Hex 42453F40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 7C453259:Prog 0 C0FE4077:Prog 0 0000FE40:Prog 0 774583FE:Prog 0 40774587:Prog 0 FE407745:Prog 0 77FE4077:Prog 0 457DFE40:Prog 0 77456BFE:Prog 0 40774571:Prog 0 70453D03:Prog 0 95107045:Prog 0 32029510:Prog 0 70453203:Prog 0 95017045:Prog 0 32029501:Prog 0 Dec M◿
2→S Hex 42457F40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 70453256:Prog 0 96FE585C:Prog 0 B1A12396:Prog 0 09744596:Prog 0 54B1C170:Prog 0 453254B1:Prog 0 E1589772:Prog 0 009F7200:Prog 0 405A8041:Prog 0 5D80600F:Prog 0 9940CC01:Prog 0 415A905E:Prog 0 8108F394:Prog 0 FB86C900:Prog 0 5E8208A8:Prog 0 032B06A1:Prog 0 Dec M◿
2→S Hex 4245BF40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 7445CC2B:Prog 0 87007445:Prog 0 CC5E8308:Prog 0 0C830F74:Prog 0 45D50A03:Prog 0 81EC83EC:Prog 0 83EC8342:Prog 0 462B0794:Prog 0 015E8408:Prog 0 A2836123:Prog 0 06C17445:Prog 0 F5239509:Prog 0 7C45F5F0:Prog 0 1381134A:Prog 0 010B8401:Prog 0 7445E40A:Prog 0 Dec M◿
2→S Hex 4245FF40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 86010B82:Prog 0 017445BB:Prog 0 07940148:Prog 0 08491F0A:Prog 0 86080B81:Prog 0 017445B6:Prog 0 0CD23F97:Prog 0 07006006:Prog 0 20B300E0:Prog 0 BB7040B3:Prog 0 704058EF:Prog 0 EFEFEFEF:Prog 0 EFEF0000:Prog 0 00000000:Prog 0 000000EF:Prog 0 AFAC28AC:Prog 0 Dec M◿
2→S Hex 42463F40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 AFEF00EF:Prog 0 2E2A202A:Prog 0 2EEF00EC:Prog 0 A8A12020:Prog 0 28EF00EF:Prog 0 AC2A2028:Prog 0 ACEF00EF:Prog 0 A92C282C:Prog 0 A9EF00EB:Prog 0 282E282E:Prog 0 28EB0018:Prog 0 18181818:Prog 0 181818EF:Prog 0 AFAC2AAC:Prog 0 AFEF0000:Prog 0 E72400E7:Prog 0 Dec M◿
2→S Hex 42467F40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 02E700EF:Prog 0 2EAAA0AA:Prog 0 2EEF00EC:Prog 0 AAA524A7:Prog 0 28EF00EF:Prog 0 AC2B272B:Prog 0 ACEF00EF:Prog 0 A92CA92C:Prog 0 A9EF00EB:Prog 0 28AEA8AE:Prog 0 28EB0016:Prog 0 14151713:Prog 0 1514161C:Prog 0 15100D0C:Prog 0 0D101512:Prog 0 12121212:Prog 0 Dec M◿
2→S Hex 4246BF40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 12121216:Prog 0 0F0A0908:Prog 0 070A0F00:Prog 0 00000000:Prog 0 00000012:Prog 0 0B060302:Prog 0 03060B00:Prog 0 00000000:Prog 0 00000010:Prog 0 09040100:Prog 0 01040900:Prog 0 00000000:Prog 0 00000010:Prog 0 09040100:Prog 0 01040900:Prog 0 00000000:Prog 0 Dec M◿
2→S Hex 4246FF40:Prog 0 5AF7415B:Prog 0 37600008:Prog 0 70000000:Prog 0 00000012:Prog 0 0B060302:Prog 0 03060B09:Prog 0 09090909:Prog 0 09090916:Prog 0 0F0A0908:Prog 0 070A0F0E:Prog 0 0C0D0F0B:Prog 0 0D0C0E1C:Prog 0 15100D0C:Prog 0 0D101500:Prog 0 F0F1EF00:Prog 0 01100001:Prog 0 100F1100:Prog 0 0E121F21:Prog 0 00080007:Prog 0 Dec M◿
2→S Hex 42473F40:Prog 0 5AF7415B:Prog 0 34600008:Prog 0 70000000:Prog 0 0C090407:Prog 0 006464FE:Prog 0 2C2CF484:Prog 0 000000FE:Prog 0 01010103:Prog 0 00704001:Prog 0 47554755:Prog 0 47554755:Prog 0 47203A30:Prog 0 EC3A5D38:Prog 0 35335B5A:Prog 0 0E5D3033:Prog 0 34875B5A:Prog 0 01434D00:Prog 0 53534548:Prog 0 43000000:Prog 0 Dec M◿
0000: ORG &h4000 4000: FF DB &hFF ; This byte is not excuted, it is file editor EOF marker (backwards) 4001: 4001: CHESSSTART: 4001: 4046AA LDW IX,BOARD-1 ; Initialized board will be relocated to printer screen buffer 4004: 41472B LDW IY,STEPVECS-1 4007: 42CC00 LDW IZ,&hCC01-1 ; Here will be the board 400A: 600008 CAL &h0008 ; Relocate routine 400D: 41C800 LDW IY,&hC800 ; StackPos=0 in memory for large screen buffer 4010: 569208 LD R74,8 ; GameSide=8 for White, 16 for Black 4013: ; LDM R64..R71,0 ; Initialise some global variables 4013: 568380 ld R67,128 4016: ; R72..R73,0 ; FunctionValue=0 4016: ; R69..R70 ; RootEval=0 4016: ; LDM R69..R70,0 4016: ; R65..R66,0 ; N=0 4016: ; R67 ; RootEp 4016: LEVEL EQU 4 4016: 4016: LP: ; do { Main game loop 4016: 578940 LDM R65..R66,0 ; N=0 4019: 4019: 60452A CAL ENTERMOVE ; Display board and return variables InputFrom and InputTo after Graph is pressed or Range twice 401C: ; Now prepare parameters to call main search routine 401C: 5C8041 LD R0,R74 ; Side=GameSide; 401F: FB81 BYD R1 ; Alpha=-INF; 4021: 5E82E0 LD R2,&hE0 4024: FB83 BYD R3 ; Beta=INF; 4026: 5E8420 LD R4,&h20 4029: 5D85C0 LDM R5..R6,R69..R70 ; Eval=RootEval; 402C: 5C8760 LD R7,R67 ; epSqr=RootEp; 402F: 5E9008 LD R8,8 ; LastTo=8; 8 is illegal square, this value indicates root of search tree 4032: 5E9102 LD R9,2 ; Depth=2; 4035: 4035: 604510 CAL SAVEALL ; SaveAll(); 4038: 4038: 604050 CAL SEARCH ; Search(); 403B: 403B: 60451D CAL RESTALL ; RestoreAll(); 403E: 403E: 569509 LD R77,9 ;Cursor out of board 4041: 60459A CAL DISP 4044: ; For the move entered on keyboard, we will return Beta, it will remain INF (&h2000) if we are not in check, and the move is valid 4044: 4044: ; if (FunctionValue==INF) GameSide ^= 24; Move is legal, flip GameSide between 8 and 16 4044: 239120 TSB R73,&h20 4047: 744016 JMP NZ,LP ; Invalid move 404A: 079218 XR R74,&h18 404D: 704016 JMP LP ; } while (1); 4050: ; db 0 ; accidentally one jump has FF in it 4050: SEARCH: 4050: 40CC01 LDW IX,&hCC01 ; IX points to Board 4053: 42472C LDW IZ,STEPVECS ; IZ points to StepVecs 4056: 9900E0 STM +(IY),R0..R7 ; Store parameter in registers to memory , IY is stack for local variables 4059: 991020 STM +(IY),R8..R9 405C: 4D0A SBW IY,10 405E: ; Alpha--; 405E: 1B8941 SBM R1..R2,1 4061: ; IterDepth = BestFrom = BestTo = 0; 4061: FBB5 BYD R29 4063: FBB1 BYD R25 4065: FBB2 BYD R26 4067: 4067: ; BestScore=-INF; 4067: FB92 BYD R10 4069: 5E93E0 LD R11,&hE0 ; 406C: ; Completely stupid full-width search in principle tries anything, even the most idiotic moves like taking a defended Pawn with a Queen. 406C: ; Going into the search 'depth first', on the other hand, tends to dive deep into idiotic variations before realizing they were idiotic, 406C: ; when accidentally hitting upon the proper refutation. 406C: ;while( 1) { Iterative deeping loop 406C: ITDLOOP: 406C: ; h=0; Variable h will be zero if we need to exit iterative deeping loop 406C: FBB7 BYD R31 406E: ; if (IterDepth++ < Depth) Depth below 2 half moves 406E: 54B503 LD R88,R29 4071: 0AB501 AD R29,1 4074: 231103 TSB R88,R9 4077: 7F4080 JMP NC,ITDDELSE 407A: ; h=1; 407A: 5EB701 LD R31,1 407D: 7040B3 JMP ITDENDIF 4080: ITDDELSE: 4080: ; else 4080: ; if (LastTo==8 & InputFrom==0xFE) { We are at thinked move, root of search 4080: 2B9008 TSB R8,8 4083: 7440B3 JMP NZ,ITDENDIF 4086: 2396FE TSB R78,&hFE 4089: 7440B3 JMP NZ,ITDENDIF 408C: 408C: ; h=1; 408C: 5EB701 LD R31,1 408F: ; if (!(N<2048 & IterDepth<4)) { // Increasing these constants will make the game smarter, but much slower. Do not increase IterDepth above 12, due to allocated stack space 408F: 238204 TSB R66,LEVEL ; 4 * 256 positions to check 4092: 7F409B JMP NC,SETIT 4095: 2BB504 TSB R29,LEVEL ; 4 half moves depth 4098: 7740B3 JMP C,ITDENDIF 409B: SETIT: 409B: ; InputFrom=BestFrom; // So, we are at root, thinked move and exhausted limit of moves or iteration depth. Set up the best move as it was entered 409B: 54B1C1 LD R78,R25 409E: ; InputTo=BestTo&~M; 409E: 54B2E1 LD R79,R26 40A1: 049777 AN R79,&h77 40A4: ; IterDepth=2; 40A4: 5EB502 LD R29,2 40A7: ; if (BestScore==-INF) 40A7: ; printf ("Check mate\n"); 40A7: 2B93E0 TSB R11,&hE0 ; Write by putting Sprite CM 40AA: 7440B3 JMP NZ,ITDENDIF 40AD: 5EC10A LD R33,10 40B0: 88C144 ST (IX+&h44),R33 40B3: ; } 40B3: ; } 40B3: ITDENDIF: 40B3: ; if (! h) 40B3: ; break; Exit the iterative deeping root 40B3: 2BB700 TSB R31,0 40B6: 7C44F7 JMP Z,ENDITDLOOP 40B9: ;/* Each iteration consist of a move-generation run, immediately searching */ 40B9: ; /* all moves as they are generated. The best move from the previous iter- */ 40B9: ; /* ation (still contained in BestFrom, BestTo) is slipped in front, though. */ 40B9: ; /* To make this easier, move generation starts at StartSqr = BestFrom. */ 40B9: ; /* The highest -bit of BestTo indicates if there is a valid best move to try. */ 40B9: ; FromSqr = StartSqr = BestFrom; Start from previous best move 40B9: 54B103 LD R88,R25 40BC: 5CB403 LD R28,R88 40BF: 5CA703 LD R23,R88 40C2: ; h = BestTo & S; 40C2: 54B203 LD R88,R26 40C5: 04B080 AN R88,128 40C8: 5CB703 LD R31,R88 40CB: ; if (IterDepth > 1) /* unconsidered:static eval */ 40CB: 56B001 LD R88,1 40CE: 233503 TSB R88,R29 40D1: 7F40DC JMP NC,IFITELSE 40D4: ; BestScore = -INF; 40D4: FB92 BYD R10 40D6: 5E93E0 LD R11,&hE0 40D9: 7040E8 JMP ENDIFIT 40DC: ; else 40DC: IFITELSE: 40DC: ; BestScore = Eval; 40DC: 548503 LD R88,R5 40DF: 5C9203 LD R10,R88 40E2: 548603 LD R88,R6 40E5: 5C9303 LD R11,R88 40E8: 40E8: ENDIFIT: 40E8: ; N=N+1; /* node count (for timing) */ 40E8: 128941 ADM R65..R66,1 40EB: ; do { 40EB: MAINDO: 40EB: ; Piece = Board[FromSqr]; /* scan board looking for piece */ 40EB: A0A703 LD R88,(IX+R23) 40EE: 5CA503 LD R21,R88 40F1: ; if (Piece & Side) { /* This players piece */ 40F1: 040003 AN R88,R0 40F4: 7C44A4 JMP Z,ENDPCSIDE 40F7: ; StepVec = PieceType = Piece & 7; /* set StepVec > 0 */ 40F7: 54A503 LD R88,R21 40FA: 04B007 AN R88,7 40FD: 5CA603 LD R22,R88 4100: 5CA003 LD R16,R88 4103: ; j = StepVecs[PieceType + 16]; /* first step vector Piece */ -1 to avoid FF in file editor 4103: 02B010 AD R88,16 4106: 5CC003 LD R32,R88 4109: A2C003 LD R88,(IZ+R32) 410C: 03B001 SB R88,1 410F: 5CA303 LD R19,R88 4112: ; while (1) { 4112: DIRLOOP: 4112: 4112: ; if (PieceType > 2 & StepVec < 0) /* loop over directions o[] */ 4112: 56B002 LD R88,2 4115: 232603 TSB R88,R22 4118: 7F4126 JMP NC,BIDIRECT 411B: 2CA080 TAN R16,128 411E: 7C4126 JMP Z,BIDIRECT 4121: 4121: ; StepVec = -StepVec; 4121: E820 CMP R16 4123: 704131 JMP ENDBIDIR 4126: ; else 4126: BIDIRECT: 4126: ; StepVec = -StepVecs[++j]; 4126: 0AA301 AD R19,1 4129: A2A303 LD R88,(IZ+R19) 412C: E030 CMP R88 412E: 5CA003 LD R16,R88 4131: ENDBIDIR: 4131: ; if (StepVec == 0) 4131: ; break; 4131: 2BA000 TSB R16,0 4134: 7C44A4 JMP Z,ENDDIRLOOP 4137: ; A: /* resume normal after best */ 4137: RESUMENORMAL: 4137: ; ToSqr = FromSqr; 4137: ; /* For each direction we scan ToSqr along the ray startig at FromSqr. */ 4137: 4137: 54A703 LD R88,R23 413A: 5CB003 LD R24,R88 413D: ; SkipSqr = RookSqr = S; /* S = 0x80 = dummy square */ 413D: 5EA280 LD r18,128 4140: 5EA180 ld r17,128 4143: ; do { 4143: ; /* FromSqr, ToSqr here scan through all tentative moves. If there */ 4143: ; /* is an old best move to try first, this is indicated in the 8-bit */ 4143: ; /* of BestTo (which was copied from the S-bit), and we overrule the */ 4143: ; /* generated ToSqr (which might ly at other distance or in direction) */ 4143: ; /* We then test if ToSqr is on the board, if we have an e.p. capture, */ 4143: ; /* are blocked by an own piece, and if Pawn moves are valid. */ 4143: 4143: DOCAPT: 4143: ; if (h != 0) 4143: 2BB700 TSB R31,0 4146: 7C4155 JMP Z,SETNEWTO 4149: ; ToSqr = BestTo ^ h; /* sneak-in prev. best move */ 4149: 54B203 LD R88,R26 414C: 073703 XR R88,R31 414F: 5CB003 LD R24,R88 4152: 70415B JMP SETCAPTSQR 4155: ; else 4155: SETNEWTO: 4155: ; ToSqr += StepVec; 4155: 54A003 LD R88,R16 4158: 0A3003 AD R24,R88 415B: SETCAPTSQR: 415B: ; CaptSqr = ToSqr; 415B: 54B003 LD R88,R24 415E: 5CB303 LD R27,R88 4161: ; if (ToSqr & M) break; /* board edge hit (M=0x88) */ 4161: 2CB088 TAN R24,&h88 4164: 7444A1 JMP NZ,ENDDOCAPT 4167: ; We can not castle if in check, or fields that we pass with king are attacked 4167: ; if ((epSqr - S && Board[epSqr] && ToSqr - epSqr < 2 & epSqr - ToSqr < 2)) 4167: 2B8780 TSB R7,128 416A: 7C4199 JMP Z,CHECKENPAS 416D: A08703 LD R88,(IX+R7) 4170: 23B000 TSB R88,0 4173: 7C4199 JMP Z,CHECKENPAS 4176: 54B003 LD R88,R24 4179: 030703 SB R88,R7 417C: 03B002 SB R88,2 417F: 24B080 TAN R88,128 4182: 7C4199 JMP Z,CHECKENPAS 4185: 548703 LD R88,R7 4188: 033003 SB R88,R24 418B: 03B002 SB R88,2 418E: 24B080 TAN R88,128 4191: 7C4199 JMP Z,CHECKENPAS 4194: ; BestScore = INF; /* castling-on-Pawn-check bug fixed */ 4194: FB92 BYD R10 4196: 5E9320 LD R11,&h20 4199: CHECKENPAS: 4199: ; if (PieceType < 3 & ToSqr == epSqr) /* shift CaptSqr if e.p. */ 4199: 2BA603 TSB R22,3 419C: 7F41AB JMP NC,SETVICTIM 419F: 54B003 LD R88,R24 41A2: 230703 TSB R88,R7 41A5: 7441AB JMP NZ,SETVICTIM 41A8: ; CaptSqr ^= 16; 41A8: 0FB310 XR R27,16 41AB: SETVICTIM: 41AB: ; Victim = Board[CaptSqr]; Take piece we capture 41AB: A0B303 LD R88,(IX+R27) 41AE: 5CA403 LD R20,R88 41B1: ; if (Victim & Side /* capture own */ 41B1: ; | PieceType < 3 & !(ToSqr - FromSqr & 7) - !Victim) /* bad pawn move */ 41B1: F3B1 BYD R89 41B3: 54B003 LD R88,R24 ; ToSqr 41B6: 032703 SB R88,R23 ; From Sqr 41B9: 04B007 AN R88,7 41BC: 7C41C2 JMP Z,SV1 41BF: 56B101 LD R89,1 41C2: SV1: 41C2: FBC0 BYD R32 41C4: 2BA400 TSB R20,0 41C7: 7C41CD JMP Z,SV2 41CA: 5EC001 LD R32,1 41CD: SV2: 41CD: 034023 SB R89,R32 41D0: FBC0 BYD R32 41D2: 2BA603 TSB R22,3 41D5: 7F41DB JMP NC,SV3 41D8: 5EC001 LD R32,1 41DB: SV3: 41DB: 0C4023 AN R32,R89 41DE: 54A403 LD R88,R20 41E1: 040003 AN R88,R0 41E4: 0E4003 OR R32,R88 41E7: ; break; 41E7: 7444A1 JMP NZ,ENDDOCAPT 41EA: ; i = PieceVal[Victim & 7]; /* value of victim piece.16 bit */ 41EA: 54A403 LD R88,R20 41ED: 04B007 AN R88,7 41F0: 5CC003 LD R32,R88 41F3: 424744 LDW IZ,PIECEVAL 41F6: A2C003 LD R88,(IZ+R32) 41F9: 5C9603 LD R14,R88 41FC: 42474C LDW IZ,PIECEVALHI 41FF: A2C003 LD R88,(IZ+R32) 4202: 5C9703 LD R15,R88 4205: 42472C LDW IZ,STEPVECS 4208: ; if (i < 0) /* King capture gives maximal score */ 4208: 2C9780 TAN R15,128 420B: 7C4213 JMP Z,TESTCUT 420E: ; BestScore = INF ; /* castling-on-Pawn-check bug fixed */ 420E: FB92 BYD R10 4210: 5E9320 LD R11,&h20 ; 4213: 4213: TESTCUT: 4213: ; if (BestScore >= Beta) /* abort on fail high */ 4213: 549263 LD R91,R10 4216: 549383 LD R92,R11 4219: 130383 SBM R91..R92,R3..R4 421C: 24B480 TAN R92,128 421F: 421F: ; goto CutOff; 421F: 7C44B3 JMP Z,CUTOFF 4222: ; /* We now have a move to search. If there is depth left, we different- */ 4222: ; /* ially update the evaluation, Make the move, Search it recursively */ 4222: ; /* UnMake it, and update the best score & move. If not, we ignore it. */ 4222: 4222: TEST: 4222: ; if (s = IterDepth - (ToSqr != LastTo)) { /* remaining depth(-recapt.)*/ 4222: 54B503 LD R88,R29 4225: 5CB603 LD R30,R88 4228: 54B003 LD R88,R24 422B: 231003 TSB R88,R8 422E: 7C4234 JMP Z,SETITDEP 4231: 0BB601 SB R30,1 4234: 4234: SETITDEP: 4234: 2BB600 TSB R30,0 4237: 7C4404 JMP Z,ENDSCOREIF 423A: ; if (PieceType < 6) /* center positional pts. */ 423A: 5F9CA0 LDM R12..R13,0 423D: F3B5 BYD R93 423F: 2BA606 TSB R22,6 4242: 7F4263 JMP NC,STARTMOVE 4245: ; Score = Board[FromSqr + 8] - Board[ToSqr + 8]; 4245: 54A703 LD R88,R23 4248: 02B008 AD R88,8 424B: 5CC003 LD R32,R88 424E: A0C083 LD R92,(IX+R32) 4251: 1A14A3 ADM R12..R13,R92..R93 4254: 54B003 LD R88,R24 4257: 02B008 AD R88,8 425A: 5CC003 LD R32,R88 425D: A0C083 LD R92,(IX+R32) 4260: 1B14A3 SBM R12..R13,R92..R93 4263: 4263: ; else 4263: ; Score = 0; 4263: 4263: STARTMOVE 4263: ; /* Make move & evaluate */ 4263: 4263: ; Board[RookSqr] = Board[CaptSqr] = Board[FromSqr] = 0; 4263: F3B0 BYD R88 4265: 80A103 ST (IX+R17),R88 4268: 80B303 ST (IX+R27),R88 426B: 80A703 ST (IX+R23),R88 426E: 426E: ; Board[ToSqr] = Piece | 32; /* do move, set non-virgin bit (Piece moved)*/ 426E: 54A503 LD R88,R21 4271: 06B020 OR R88,32 4274: 80B003 ST (IX+R24),R88 4277: ; if (!(RookSqr & M)) /* castling */ 4277: 54A103 LD R88,R17 427A: 04B088 AN R88,&h88 427D: 74428C JMP NZ,TESTPAWN 4280: ; Board[SkipSqr] = Side + 6, Score += 30; Put Rook and Score 4280: 4280: 548003 LD R88,R0 4283: 02B006 AD R88,6 4286: 80A203 ST (IX+R18),R88 4289: 1A9CBE ADM R12..R13,30 428C: TESTPAWN: 428C: ; if (PieceType < 3) { /* pawns: */ 428C: 2BA603 TSB R22,3 428F: 7F42F1 JMP NC,SETNEWBETA 4292: ; Score -= 9 * ((FromSqr - 2 & M || Board[FromSqr - 2] - Piece) + /* structure, undefended */ 4292: ; (FromSqr + 2 & M || Board[FromSqr + 2] - Piece) - 1); /* squares plus bias */ 4292: 56B40A LD R92,10 4295: F3B5 BYD R93 4297: 54A703 LD R88,R23 429A: 03B002 SB R88,2 429D: 5CC003 LD R32,R88 42A0: 04B088 AN R88,&h88 42A3: 7442AF JMP NZ,PAWNPUNIS1 42A6: A0C003 LD R88,(IX+R32) 42A9: 032503 SB R88,R21 42AC: 7C42B2 JMP Z,PAWNCHECK2 42AF: PAWNPUNIS1: 42AF: 1B14A3 SBM R12..R13,R92..R93 42B2: PAWNCHECK2 42B2: 54A703 LD R88,R23 42B5: 02B002 AD R88,2 42B8: 5CC003 LD R32,R88 42BB: 04B088 AN R88,&h88 42BE: 7442CA JMP NZ,PAWNPUNIS2 42C1: A0C003 LD R88,(IX+R32) 42C4: 032503 SB R88,R21 42C7: 7C42CD JMP Z,PAWNAWARD 42CA: PAWNPUNIS2: 42CA: 1B14A3 SBM R12..R13,R92..R93 42CD: PAWNAWARD: 42CD: 1A14A3 ADM R12..R13,R92..R93 42D0: 42D0: ; if (ToSqr + StepVec + 1 & S) /* promote Pawn */ 42D0: 54B003 LD R88,R24 42D3: 022003 AD R88,R16 42D6: 02B001 AD R88,1 42D9: 04B080 AN R88,128 42DC: 7C42F1 JMP Z,SETNEWBETA 42DF: ; Board[ToSqr] |= 7, i += 800; /* promote Pawn to Queen, update score */ 42DF: A0B003 LD R88,(IX+R24) 42E2: 06B007 OR R88,7 42E5: 80B003 ST (IX+R24),R88 42E8: 56B684 LD R94,&h84 42EB: 56B703 LD R95,3 42EE: 1A16E3 ADM R14..R15,R94..R95 42F1: 42F1: ; } 42F1: ; Now recursive call of Eval function to calculate value of reply 42F1: ; Set new Beta value to -MAX(BestScore,Alpha) 42F1: SETNEWBETA: 42F1: ; if (BestScore > Alpha) 42F1: 549223 LD R89,R10 42F4: 549343 LD R90,R11 42F7: 130143 SBM R89..R90,R1..R2 42FA: 7C4312 JMP Z,NEWALP1 42FD: 24B280 TAN R90,128 4300: 744312 JMP NZ,NEWALP1 4303: ; NewBeta = -BestScore; 4303: 559263 LDM R90..R91,R10..R11 4306: E10263 CMPM R90..R91 4309: 5CC043 LD R32,R90 430C: 5CC163 LD R33,R91 430F: 70431E JMP REPLYEVAL 4312: 4312: ; else NewBeta = -Alpha; 4312: NEWALP1: 4312: 558143 LDM R89..R90,R1..R2 4315: E10143 CMPM R89..R90 4318: 5CC023 LD R32,R89 431B: 5CC143 LD R33,R90 431E: 431E: ; // Score = -Search(24 - Side, -Beta, NewBeta, -Eval - Score - i, SkipSqr, ToSqr, s); 431E: REPLYEVAL: 431E: ; if (StackPos < 24*32) { 431E: ; TSB r121,&hCB IY Stack checking 431E: ; JMP NC,REPLYFINISH 431E: ; SaveAll(); All local variables to IY stack 431E: 604510 CAL SAVEALL 4321: ; Side=24-Side; Flip side 4321: 0F8018 XR R0,24 4324: ; Alpha=-Beta; 4324: 4324: 558383 LDM R91..R92,R3..R4 4327: E10383 CMPM R91..R92 432A: 5C8163 LD R1,R91 432D: 5C8283 LD R2,R92 4330: ; Beta=NewBeta; 4330: 54C003 LD R88,R32 4333: 5C8303 LD R3,R88 4336: 54C103 LD R88,R33 4339: 5C8403 LD R4,R88 433C: ; Eval=(-Eval-Score-i); /* New Eval */ 433C: 5494A3 LD R93,R12 433F: 5495C3 LD R94,R13 4342: 1A05C3 ADM R5..R6,R93..R94 4345: 5496A3 LD R93,R14 4348: 5497C3 LD R94,R15 434B: 1A05C3 ADM R5..R6,R93..R94 434E: E905C0 CMPM R5..R6 4351: 4351: ; epSqr=SkipSqr; /* New en passant square */ 4351: 54A203 LD R88,R18 4354: 5C8703 LD R7,R88 4357: ; LastTo=ToSqr; 4357: 54B003 LD R88,R24 435A: 5C9003 LD R8,R88 435D: ; Depth=s; 435D: 54B603 LD R88,R30 4360: 5C9103 LD R9,R88 4363: 4363: ; Search(); Recursion 4363: 604050 CAL SEARCH 4366: ; RestoreAll(); Back from IY stack 4366: 60451D CAL RESTALL 4369: ; Score= -FunctionValue; Oponent reply is negative 4369: 5C9401 LD R12,R72 436C: 5C9521 LD R13,R73 436F: E914A0 CMPM R12..R13 4372: ; } 4372: REPLYFINISH: 4372: ; /* If the Search routine was called as move-legality checker, we */ 4372: ; /* now return before unmaking the move if it was the input move. */ 4372: 4372: ; if (InputFrom != 0xFE) Here we are if we entered the move, recursion was used for legality check 4372: 2396FE TSB R78,&hFE 4375: 7C43B2 JMP Z,TAKEBACK 4378: ; if (Score + INF && FromSqr == InputFrom & ToSqr == InputTo & LastTo == 8) { // Move found 4378: 2B95E0 TSB R13,&hE0 437B: 7C43AC JMP Z,ALTENTERSC 437E: 2B27C1 TSB R23,R78 4381: 7443AC JMP NZ,ALTENTERSC 4384: 2B30E1 TSB R24,R79 4387: 7443AC JMP NZ,ALTENTERSC 438A: 2B9008 TSB R8,8 438D: 7443AC JMP NZ,ALTENTERSC 4390: 4390: 4390: ; RootEval = -Eval - i; /* update eval, material */ 4390: 5485C3 LD R94,R5 4393: 5486E3 LD R95,R6 4396: 1216E3 ADM R94..R95,R14..R15 4399: E106E3 CMPM R94..R95 439C: 9737C0 STM -(SP),R95..R94 439F: B305C0 LDM R69..R70,(SP)+ 43A2: ; RootEp = SkipSqr; 43A2: 54A260 LD R67,R18 43A5: ; if (Board[ToSqr] - Piece & 7 && P - InBuf > 5) 43A5: ; Board[ToSqr] -= InBuf[4] & 3; /* under-promotions */ 43A5: ; NOT IMPLEMENTED 43A5: ; FunctionValue=Beta; /* Not in check signal */ 43A5: 548301 LD R72,R3 43A8: 548421 LD R73,R4 43AB: ; return; 43AB: 58 RTN 43AC: ; } 43AC: ALTENTERSC: 43AC: ; Score = BestScore; /* (prevent fail-lows on K-capt. replies) */ 43AC: 9F1340 STM -(SP),R11..R10 43AF: BB14A0 LDM R12..R13,(SP)+ 43B2: 43B2: ; } 43B2: TAKEBACK: 43B2: ; undo move,RookSqr can be dummy 43B2: ; Board[RookSqr] = Side + 6; 43B2: 548003 LD R88,R0 43B5: 02B006 AD R88,6 43B8: 80A103 ST (IX+R17),R88 43BB: ; Board[SkipSqr] = Board[ToSqr] = 0; 43BB: F3B0 BYD R88 43BD: 80A203 ST (IX+R18),R88 43C0: 80B003 ST (IX+R24),R88 43C3: ; Board[FromSqr] = Piece; 43C3: 54A503 LD R88,R21 43C6: 80A703 ST (IX+R23),R88 43C9: 43C9: ; Board[CaptSqr] = Victim; 43C9: 54A403 LD R88,R20 43CC: 80B303 ST (IX+R27),R88 43CF: 43CF: ; /* Process score. If the move just searched was a previous best */ 43CF: ; /* move that was tried first, we take its Score and redo the first */ 43CF: ; /* ray of this piece. Otherwise update best score and move. */ 43CF: 43CF: 43CF: ; if (Score > BestScore) 43CF: 549443 LD R90,R12 43D2: 549563 LD R91,R13 43D5: 131263 SBM R90..R91,R10..R11 43D8: 7C43F9 JMP Z,TESTH 43DB: 24B380 TAN R91,128 43DE: 7443F9 JMP NZ,TESTH 43E1: 43E1: ; BestScore = Score, BestFrom = FromSqr, BestTo = ToSqr | S & SkipSqr; /* Update and mark non-castling with S */ 43E1: 9F1580 STM -(SP),R13..R12 43E4: BB1260 LDM R10..R11,(SP)+ 43E7: 54A703 LD R88,R23 43EA: 5CB103 LD R25,R88 43ED: 56B080 LD R88,128 43F0: 042203 AN R88,R18 43F3: 063003 OR R88,R24 43F6: 5CB203 LD R26,R88 43F9: 43F9: 43F9: TESTH: 43F9: ; if (h) { 43F9: 2BB700 TSB R31,0 43FC: 7C4404 JMP Z,ENDSCOREIF 43FF: 43FF: ; h = 0; 43FF: FBB7 BYD R31 4401: ; goto A; Best is first done, now normal search 4401: 704137 JMP RESUMENORMAL 4404: ; } 4404: ; } 4404: ENDSCOREIF: 4404: ; /* Determine if we have to continue scanning this ray. We must stop */ 4404: ; /* on a capture, or if the piece is a non-slider, with the exceptions */ 4404: ; /* of double moves for Pawns and King (castlings!). Such double moves */ 4404: ; /* cause setting of the SkipSqr, that otherwise is equal to the dummy S*/ 4404: ; if(PieceType>2) { 4404: 56B002 LD R88,2 4407: 232603 TSB R88,R22 440A: 7F446C JMP NC,NOPCM 440D: ; PieceMask=PieceType-3|j-7 ; /* King moving sideways, */ 440D: 54A323 LD R89,R19 4410: 03B107 SB R89,7 4413: 54A643 LD R90,R22 4416: 03B203 SB R90,3 4419: 5CC023 LD R32,R89 441C: 0E4043 OR R32,R90 441F: ; if (! PieceMask) { 441F: 2BC000 TSB R32,0 4422: 74446E JMP NZ,RAYDECIDE 4425: ; RookSqr=FromSqr+3^StepVec>>1&7; /* virgin Rook in corner */ 4425: 54A703 LD R88,R23 4428: 02B003 AD R88,3 442B: 54A023 LD R89,R16 442E: ;LD R90,r16 442E: ;BIU R90 442E: F631 ROD R89 4430: 04B107 AN R89,7 4433: 5CA103 LD r17,R88 4436: 0F2123 XR R17,R89 4439: ; PieceMask=Board[RookSqr]-Side-6; /* virgin Rook in corner */ 4439: A0A103 LD R88,(IX+R17) 443C: 030003 SB R88,R0 443F: 03B006 SB R88,6 4442: 5CC003 LD R32,R88 4445: ; if (! PieceMask) 4445: 2BC000 TSB R32,0 4448: 74446E JMP NZ,RAYDECIDE 444B: ; PieceMask= Board[RookSqr^1]|Board[RookSqr^2]; /* 2 empty sqrs. next to R */ 444B: 54A103 LD R88,R17 444E: 07B001 XR R88,1 4451: 5CC103 LD R33,R88 4454: A0C123 LD R89,(IX+R33) 4457: 54A103 LD R88,R17 445A: 07B002 XR R88,2 445D: 5CC103 LD R33,R88 4460: A0C143 LD R90,(IX+R33) 4463: 5CC023 LD R32,R89 4466: 0E4043 OR R32,R90 4469: 70446E JMP RAYDECIDE 446C: ; } 446C: ; } 446C: ; else 446C: NOPCM: 446C: ; PieceMask=0; 446C: FBC0 BYD R32 446E: 446E: RAYDECIDE 446E: ; if(FromSqr+StepVec-ToSqr|Piece&32|PieceMask ) 446E: 54A503 LD R88,R21 4471: 04B020 AN R88,32 4474: 064003 OR R88,R32 4477: 54A723 LD R89,R23 447A: 022023 AD R89,R16 447D: 033023 SB R89,R24 4480: 5CC003 LD R32,R88 4483: 0E4023 OR R32,R89 4486: 7C4495 JMP Z,SETSKIP 4489: ; Victim+=PieceType<5; /* fake capt. for nonsliding pieces */ 4489: 2BA605 TSB R22,5 448C: 7F449B JMP NC,ENDSETSKIP 448F: 0AA401 AD R20,1 4492: 70449B JMP ENDSETSKIP 4495: ; else 4495: SETSKIP: 4495: ; SkipSqr=ToSqr; /* enable e.p. */ 4495: 54B003 LD R88,R24 4498: 5CA203 LD R18,R88 449B: ENDSETSKIP: 449B: ; }while(!Victim); /* if not capt. continue ray */ 449B: 2BA400 TSB R20,0 449E: 7C4143 JMP Z,DOCAPT 44A1: ENDDOCAPT: 44A1: ; 44A1: ; } 44A1: 704112 JMP DIRLOOP 44A4: ENDDIRLOOP: 44A4: ; } 44A4: ENDPCSIDE: 44A4: ; } while ((FromSqr = FromSqr + 9 & ~M) - StartSqr); /* next sqr. of board, wrap */ 44A4: 0AA709 AD R23,9 44A7: 0CA777 AN R23,&h77 44AA: 54A703 LD R88,R23 44AD: 033403 SB R88,R28 44B0: 7440EB JMP NZ,MAINDO 44B3: ; /* All moves have been searched; wrap up iteration by testing for check- or */ 44B3: ; /* stalemate, which leave Score at -INF. Call Search with Depth=1 after null */ 44B3: ; /* move to determine if we are in check. Finally store result in hash. */ 44B3: 44B3: ; CutOff: 44B3: CUTOFF: 44B3: ; if (BestScore > INF - M | BestScore < M - INF) 44B3: 2B931F TSB R11,&h1F 44B6: 7744C2 JMP C,VERLEGAL 44B9: 2B93E2 TSB R11,&hE2 44BC: 7F44C2 JMP NC,VERLEGAL 44BF: 44BF: FORCEITEREND: 44BF: ; IterDepth = 98; 44BF: 5EB562 LD R29,98 44C2: VERLEGAL 44C2: ; if (BestScore == -INF) { 44C2: 2B93E0 TSB R11,&hE0 44C5: 7444F4 JMP NZ,FINISHED 44C8: 44C8: ;// BestScore = -Search(24 - Side, -INF, INF, 0, S, S, 1); 44C8: 44C8: 44C8: ; SaveAll(); 44C8: 604510 CAL SAVEALL 44CB: ; Side=24-Side; 44CB: 0F8018 XR R0,24 44CE: ; Alpha=-INF; 44CE: FB81 BYD R1 44D0: 5E82E0 LD R2,&hE0 44D3: ; Beta=INF; 44D3: FB83 BYD R3 44D5: 5E8420 LD R4,&h20 44D8: ; Eval=0; 44D8: FB85 BYD R5 44DA: FB86 BYD R6 44DC: ; epSqr=S; 44DC: 5E8780 LD R7,128 44DF: ; LastTo=S; 44DF: 5E9080 LD R8,128 44E2: ; Depth=1; 44E2: 5E9101 LD R9,1 44E5: ; Search(); 44E5: 604050 CAL SEARCH 44E8: ; RestoreAll(); 44E8: 60451D CAL RESTALL 44EB: ; BestScore= -FunctionValue; 44EB: 5C9201 LD R10,R72 44EE: 5C9321 LD R11,R73 44F1: E91260 CMPM R10..R11 44F4: 44F4: ; } 44F4: FINISHED: 44F4: ; if (LastTo == 8) printf("%2d ply, %9d searched, %6d by (%2x,%2x)\n", 44F4: ; IterDepth - 1, N, BestScore, BestFrom, BestTo & 0x77); 44F4: ; } 44F4: 70406C JMP ITDLOOP 44F7: ENDITDLOOP: 44F7: ; BestScore += BestScore < Eval; /* faster-gain award */ 44F7: 5492A3 LD R93,R10 44FA: 5493C3 LD R94,R11 44FD: 1305C3 SBM R93..R94,R5..R6 4500: 24B680 TAN R94,128 4503: 7C4509 JMP Z,SETFVAL 4506: 4506: 1A9A61 ADM R10..R11,1 4509: ; FunctionValue=BestScore; 4509: SETFVAL: 4509: 549201 LD R72,R10 450C: 549321 LD R73,R11 450F: ENDSEARCH: 450F: ; return; 450F: 58 RTN 4510: 4510: ; THESE TWO SUBROUTINES SAVE AND RESTORE LOCAL VARIABLES 4510: 4510: 4510: SAVEALL: ; Save all registers representing local variables 4510: 9900E0 STM +(IY),R0..R7 4513: 9910E0 STM +(IY),R8..R15 4516: 9920E0 STM +(IY),R16..R23 4519: 9930E0 STM +(IY),R24..R31 451C: 58 RTN 451D: RESTALL: ; Restore all registers representing local variables 451D: BD3700 LDM R31..R24,(IY)- 4520: BD2700 LDM R23..R16,(IY)- 4523: BD1700 LDM R15..R8,(IY)- 4526: BD0700 LDM R7..R0,(IY)- 4529: 58 RTN 452A: 452A: ; USER INTERFACE, CHECK KEYBOARD AND DISPLAY BOARD 452A: 452A: ENTERMOVE 452A: 579EE9 LDM R78..R79,&h9 ; Initially no move selected 452D: 569544 LD R77,&h44 ; Cursor to center 4530: FB87 BYD R7 ; Flash flag for cursor 4532: DRAWBOARD: 4532: 049577 AN R77,&h77 ; Wrap cursor if out of board 4535: 60459A CAL DISP ; Display the board 4538: F807 INV R7 ; Flip the cursor flag 453A: 5EB302 LD R27,2 ; Small loop of 512 passes 453D: DELAY1: 453D: 1BBA61 SBM R26..R27,1 4540: 7C4532 JMP Z,DRAWBOARD 4543: 4543: 59C0 GST R32,KI ; READ KEYBOARD and shift bits to determine keys 4545: FE40 ROD R32 4547: 770000 JMP C,0 454A: FE40 ROD R32 454C: 774583 JMP C,COMPMOVE 454F: FE40 ROD R32 4551: 774587 JMP C,SETFROMTO 4554: FE40 ROD R32 4556: 774577 JMP C,LEFTKEY 4559: FE40 ROD R32 455B: 77457D JMP C,RIGHTKEY 455E: FE40 ROD R32 4560: 77456B JMP C,UPKEY 4563: FE40 ROD R32 4565: 774571 JMP C,DOWNKEY 4568: 70453D JMP DELAY1 456B: ; Update cursor for each case 456B: 456B: UPKEY: 456B: 039510 SB R77,16 456E: 704532 JMP DRAWBOARD 4571: DOWNKEY: 4571: 029510 AD R77,16 4574: 704532 JMP DRAWBOARD 4577: LEFTKEY: 4577: 039501 SB R77,1 457A: 704532 JMP DRAWBOARD 457D: RIGHTKEY: 457D: 029501 AD R77,1 4580: 704532 JMP DRAWBOARD 4583: COMPMOVE: ; Graph key, computer moves 4583: 5696FE LD R78,&hFE 4586: 58 RTN 4587: SETFROMTO: ; Disp key human moves 4587: 5CB1A1 LD R25,R77 458A: 239609 TSB R78,9 ; From field selected 458D: 744596 JMP NZ,SETTO 4590: 54B1C1 LD R78,R25 4593: 704532 JMP DRAWBOARD 4596: SETTO: 4596: 54B1E1 LD R79,R25 ; To field selected 4599: 58 RTN 459A: DISP: 459A: 977200 stm -(sp),r122..r120 ; Save index registers 459D: 9F7200 stm -(sp),r58..r56 45A0: 45A0: 45A0: 405A80 LDW IX,&h5A80 ; Start of video memory, clear screen routine 45A3: 415D80 LDW IY,&h5A80+768 45A6: 600F99 cal &h0F99 45A9: 40CC01 LDW IX,&hCC01 ; IX points to Board 45AC: 415A90 LDW IY,&h5A80+16 ; IY points to video memory, centered board 45AF: ; LD R5,&hEF 45AF: 5E8108 LD R1,8 ; Row loop counter 45B2: F394 BYD R76 45B4: FB86 BYD R6 ; tested position 45B6: BRDLP: 45B6: C900 ST +(IY),0 ; First vertical column 45B8: 5E8208 LD R2,8 ; Piece loop counter 45BB: BRDPIELP: 45BB: A803 LD R3,(IX)+ ; Take piece from board 45BD: 2B06A1 TSB R6,R77 ; Check if position is cursor 45C0: 7445CC JMP NZ,IGNOREFLAGS ; if not do not flash 45C3: 2B8700 TSB R7,0 ; Test flash phase on/off 45C6: 7445CC JMP NZ,IGNOREFLAGS ; if not do not flash 45C9: 45C9: 5E8308 LD R3,8 ; This field will be black square 45CC: IGNOREFLAGS: 45CC: 0C830F AN R3,&h0F ; We ignore upper nibble of piece 45CF: 7445D5 JMP NZ,FNDPSPRITE 45D2: 0A0381 AD R3,R76 ; Blank field will be interchanged as black/white 45D5: FNDPSPRITE: ; Piece value will be multiplied by 8 45D5: EC83 BIU R3 45D7: EC83 BIU R3 45D9: EC83 BIU R3 45DB: 42462B LDW IZ,EMPTYFIELD ; Set address of piece sprites 45DE: 079401 XR R76,1 ; Black/White field 45E1: ; Sprite loop 45E1: 5E8408 LD R4,8 45E4: PCLOOP: 45E4: A28361 LD R75,(IZ+R3) ; Take column of piece of field sprite 45E7: 2306C1 TSB R78,R6 ; If the field was previously selected, invert 45EA: 7445F5 JMP NZ,COPYPIECE 45ED: 239509 TSB R77,9 45F0: 7C45F5 JMP Z,COPYPIECE 45F3: 45F3: 45F3: F013 INV R75 ; Invert 45F5: COPYPIECE: 45F5: 8113 ST +(IY),R75 ; Put the sprite column 45F7: 4A01 ADW IZ,1 ; move pointer to sprites 45F9: 0B8401 SB R4,1 45FC: 7445E4 JMP NZ,PCLOOP ; repeat sprite loop 45FF: 0A8601 AD R6,1 ; increase current postiion 4602: ; XR R5,&hEF 4602: 0B8201 SB R2,1 4605: 7445BB JMP NZ,BRDPIELP ; End piece loop 4608: ; XR R5,&hEF 4608: 079401 XR R76,1 ; Next row starts with oposite field color 460B: 4808 ADW IX,8 ; Next row in board 460D: 491F ADW IY,31 ; Next row in video memory 460F: 0A8608 AD R6,8 ; increase current position to next row 4612: 0B8101 SB R1,1 4615: 7445B6 JMP NZ,BRDLP 4618: 0CD23F AN R42,&h3F ; PARAMETER DO REFRESH 461B: 461B: 970700 stm -(sp),r71..r64 ; Save global variables 461E: 600620 CAL &h0620 ; SYSTEM CALL REFRESH 4621: B300E0 ldm r64..r71,(sp)+ ; Restore global variables 4624: 4624: BB7040 ldm r56..r58,(sp)+ ; Restore index registers 4627: B37040 ldm r120..r122,(sp)+ 462A: 462A: 58 RTN 462B: 462B: ; Here are Piece screen definitions 462B: 462B: EFEFEFEFEFEFEF00 EMPTYFIELD: DB &hEF,&hEF,&hEF,&hEF,&hEF,&hEF,&hEF,&h00 4633: 0000000000000000 BLACKFIELD: DB &h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00 463B: EFAFAC28ACAFEF00 BLKPAWN: DB &hEF,&hAF,&hAC,&h28,&hAC,&hAF,&hEF,&h00 4643: EF2E2A202A2EEF00 BLKKING: DB &hEF,&h2E,&h2A,&h20,&h2A,&h2E,&hEF,&h00 464B: ECA8A1202028EF00 BLKKNIGHT: DB &hEC,&hA8,&hA1,&h20,&h20,&h28,&hEF,&h00 4653: EFAC2A2028ACEF00 BLKBISHOP: DB &hEF,&hAC,&h2A,&h20,&h28,&hAC,&hEF,&h00 465B: EFA92C282CA9EF00 BLKROOK: DB &hEF,&hA9,&h2C,&h28,&h2C,&hA9,&hEF,&h00 4663: EB282E282E28EB00 BLKQUEEN: DB &hEB,&h28,&h2E,&h28,&h2E,&h28,&hEB,&h00 466B: 1818181818181818 CURSOR: DB &h18,&h18,&h18,&h18,&h18,&h18,&h18,&h18 4673: EFAFAC2AACAFEF00 WHTPAWN: DB &hEF,&hAF,&hAC,&h2A,&hAC,&hAF,&hEF,&h00 467B: 00E72400E702E700 UNKNOWN3: DB &h00,&hE7,&h24,&h00,&hE7,&h02,&he7,&h00 4683: EF2EAAA0AA2EEF00 WHTKING: DB &hEF,&h2E,&hAA,&hA0,&hAA,&h2E,&hEF,&h00 468B: ECAAA524A728EF00 WHTKNIGHT: DB &hEC,&hAA,&hA5,&h24,&hA7,&h28,&hEF,&h00 4693: EFAC2B272BACEF00 WHTBISHOP: DB &hEF,&hAC,&h2B,&h27,&h2B,&hAC,&hEF,&h00 469B: EFA92CA92CA9EF00 WHTROOK: DB &hEF,&hA9,&h2C,&hA9,&h2C,&hA9,&hEF,&h00 46A3: EB28AEA8AE28EB00 WHTQUEEN: DB &hEB,&h28,&hAE,&hA8,&hAE,&h28,&hEB,&h00 46AB: ; BOARD left half is actual board, right half is field value. To check field legality binary AND the value with &h88 46AB: 16141517131514161C15100D0C0D1015 BOARD: DB 22 ,20,21,23,19,21,20,22, 28,21,16,13,12,13,16,21 46BB: 1212121212121212160F0A0908070A0F DB 18 ,18,18,18,18,18,18,18, 22,15,10, 9, 8, 7,10,15 46CB: 0000000000000000120B06030203060B DB 0, 0, 0, 0, 0, 0, 0, 0, 18,11, 6, 3, 2, 3, 6,11 46DB: 00000000000000001009040100010409 DB 0, 0, 0, 0, 0, 0, 0, 0, 16, 9, 4, 1, 0, 1, 4, 9 46EB: 00000000000000001009040100010409 DB 0, 0, 0, 0, 0, 0, 0, 0, 16, 9, 4, 1, 0, 1, 4, 9 46FB: 0000000000000000120B06030203060B DB 0, 0, 0, 0, 0, 0, 0, 0, 18,11, 6, 3, 2, 3, 6,11 470B: 0909090909090909160F0A0908070A0F DB 9, 9, 9, 9, 9, 9, 9, 9, 22,15,10, 9, 8, 7,10,15 471B: 0E0C0D0F0B0D0C0E1C15100D0C0D101500 DB 14,12,13,15,11,13,12,14, 28,21,16,13,12,13,16,21,0 472C: 472C: F0F1EF0001100001100F11000E121F2100 STEPVECS DB -16, -15, -17, 0, 1, 16, 0, 1, 16, 15, 17, 0, 14, 18, 31, 33, 0 ; /* step-vector lists */ 473D: 0800070C090407 DB 7+1, -1+1, 6+1, 11+1, 8+1, 3+1, 6+1 ; /* 1st dir. in StepVecs[] per piece*/ 4744: 006464FE2C2CF484 PIECEVAL DB 0, 100, 100, -2, 44, 44, 244, 132 ; Absolute piece values low bytw */ 474C: 000000FE01010103 PIECEVALHI DB 0, 0, 0, -2, 1, 1, 1, 3 ; High byte 4754: 4754: 4754: ORG &h4755 4755: 704001 JMP CHESSSTART 4758: 4755475547554755 db 'GUGUGUGU' ; This sequence is also 4755475547554755 4760: 47203A30EC3A5D3835335B5A0E5D303334875B5A01 DB 'G :0',&hEC,':]853[Z',&h0E,']034',&h87,'[Z',01 4775: 434D00 DB 'CM',00 ; PASSWORD 2 LETTERS 4778: 5353454843 DB 'SSEHC' ; Name 5 letters 477D: 477D: 477D: 477D:
5AE8: 423FFF LDW IZ,&H3FFF ; destination address-1 5AEB: 405AF7 LDW IX,&H5AF7 ; source address in video memory-1 5AEE: 415B37 LDW IY,&H5B37 ; end of source in video memory 5AF1: 600008 CAL 8 ; transfer block 5AF4: 700000 JMP 0 ; home screen 5AF7: 00 DB 0 ; address needs to be divisible by 4 5AF8: FF4046 db &hFF,&h40,&h46 ; chess program part ...
List of files in the archive: