| Indeks | English version |
Program oraz poniższy tekst napisał dr Samir Ribić, Sarajewo, Bośnia i Hercegowina, 25 sierpnia 2014.
W 1990 roku napisałen mój pierwszy program szachowy dla Casio fx-8000G, chociaż zdawałem sobie sprawę z ograniczeń tego komputerka. Język programowania (nazywajmy go za Wikipedią FGL, skrót od First Generation Language czyli Język Pierwszej Generacji) był bardzo powolny, przez co nie pozwalał na głęboką analizę. Algorytm był następujący: przejrzyj wszystkie możliwe posunięcia (oprócz roszady i bicia w przelocie), wybierz najkorzystniejsze bicie lub przejście na pole znajdujące się najbliżej środka szachownicy, a następnie (tylko na poziomie 2) sprawdź możliwe odpowiedzi przeciwnika i jeżeli stracisz więcej niż zyskasz, to spróbuj innego ruchu. Obmyślenie ruchu zajmowało około 5 minut a narysowanie planszy około minuty (z powodu braku komendy Unplot). Nazwałem ten program "Stupido chess", ale obiecałem sobie, że kiedyś napiszę lepszy. Wiedziałem, że to możliwe, ponieważ na komputer ZX-81 istniały szachy mieszczące się w 1KB pamięci, ale były napisane w języku maszynowym, wówczas niedostępnym dla Casio fx-8000G.
Ten dzień właśnie nadszedł. H.G.Muller napisał najmniejszy program szachowy w języku C (ok. 1800 bajtów), nazwany Micro-Max, który mimo to zna wszystkie reguły (włącznie z roszadą, biciem w przelocie i promocją), używa algorytmu przeszukującego alfa-beta z heurystyką porządkowania ruchów, oblicza przewagę materialną i pozycyjną oraz strukturę pionów. Piotr Piatek odkrył język maszynowy Casio fx-8000G. Przetłumaczyłem ręcznie szachy Micro-Max na język asemblera procesora upd1007, dodałem prezentację graficzną, zmodyfikowałem pewne parametry żeby się zmieścić w małej pamięci i ograniczonej mocy obliczeniowej kalkulatora Casio, usunąłem tablice transpozycji oraz starałem się przechowywać jak najwięcej danych w rejestrach procesora. Wykonanie ruchu zajmuje programowi typowo 3-100 sekund, w tym czasie analizuje 100-5000 pozycji i zależnie od sytuacji może rozpatrywać do 8 półruchów w głąb.
Jak grać? Wybierz bierkę klawiszami ze strzałkami a następnie wciśnij klawisz Range. Następnie przesuń kursor na pole docelowe i ponownie wciśnij Range. Jeżeli chcesz, żeby kalkulator wykonał ruch, wciśnij klawisz Graph. Klawiszem AC kończy się grę. Ten prosty sposób umożliwia grę człowieka z komputerem, komputera z człowiekiem, człowieka z człowiekiem, komputera z komputerem. Komputer może też chwilowo zastąpić żywego gracza.
Program zajmuje ok. 1870 bajtów. Razem z kodem startowym zapełnia całą pamięć edytora plików oraz używa graficznego bufora drukarki do rekurencji, pozostawiając obszar programów nienaruszony.

Przepis na wpisanie gry w szachy:
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 ; znacznik końca pliku EOF
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: ; nie można wykonać roszady jeżeli król jest szachowany lub musi przejść przez atakowane pola
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' ; odpowiada liczbie 4755475547554755
4760: 47203A30EC3A5D3835335B5A0E5D303334875B5A01
DB 'G :0',&hEC,':]853[Z',&h0E,']034',&h87,'[Z',01
4775: 434D00 DB 'CM',00 ; hasło, 2 znaki
4778: 5353454843
DB 'SSEHC' ; nazwa pliku, 5 znaków
5AE8: 423FFF LDW IZ,&H3FFF ; adres docelowy - 1 5AEB: 405AF7 LDW IX,&H5AF7 ; adres źródłowy w pamięci video - 1 5AEE: 415B37 LDW IY,&H5B37 ; koniec źródła w pamięci wideo 5AF1: 600008 CAL 8 ; kopiowanie bloku pamięci 5AF4: 700000 JMP 0 ; ekran główny 5AF7: 00 DB 0 ; adres musi być podzielny przez 4 5AF8: FF4046 db &hFF,&h40,&h46 ; początek części gry ...
Zawartość archiwum: