; ; ; THREE DIMENSIONAL TIC - TAC - TOE ; ; VER 1.0 11/20/75 ; ; THOMAS A. ROLANDER ; ORG 100H ; CO EQU 3809H CI EQU 3803H CSTS EQU 3812H ; CR EQU 0DH LF EQU 0AH ESC EQU 1BH BSPACE EQU 08H TAB EQU 09H ; WIDTH EQU 14 SPACING EQU 3 ; BEGIN: LXI SP,2000H ; SET STACK POINTER MVI B,65 ; CLEAR THE BOARD LXI H,MOVEARY XRA A CLOOP: MOV M,A INX H DCR B ; CLEAR ALL 64 SQUARES JNZ CLOOP LXI H,MSG0 ; CLEAR SCREEN AND PRINT BOARD CALL MESAG CALL BDHOME ; MOVE CURSOR TO LOWER LEFT CORNER GETMOVE: LXI H,MSG1 ; PRINT "ENTER YOUR MOVE" GETX: CALL PRINTMESAG GETNEXT: CALL COPYPOSITION ; START BY DEFAULTING TO CURRENT POSITION CALL CI ; THEN GET PLAYERS KEYBOARD INPUT ANI 7FH ; BAG PARITY BIT MOV B,A ; RESPONSE WILL BE SAVED IN B LXI D,CHARLIST-2 ; SCAN LIST OF OK CHARS & JUMP GLOOP: INX D ; PRE-INCREMENT INX D LDAX D ; GET CHAR FROM TABLE ORA A ; TEST FOR END OF LIST GETERROR: LXI H,MSG2 ; JUST IN CASE BAD CHAR JZ GETX ; BAD CHAR -> GO PRINT "TRY AGAIN" INX D ; NOW POINT TO JUMP ADDRESS CMP B ; COMPARE CHAR TO THAT KEY'D IN JNZ GLOOP ; NO LUCK ?! LDAX D ; EL-KLUGE-O INDIRECT JUMP MOV L,A INX D LDAX D MOV H,A LXI D,GETNEXT ; SET-UP FAKE 'CALL' RETURN PUSH D PCHL ; WHITHER WANDEREST THOU ..... ; CHARLIST: DB 1FH DW UP DB 0AH DW DOWN DB 8 DW LEFT DB 1CH DW RIGHT DB 'X' DW GOTMV DB CR DW BEGIN DB 'C' AND NOT 40H DW 7200H DB 'O' DW YOUMOVE DB 0 ; ; ; ++++++++++++++++++++++++++++++++++++++++++++++++ ; ; JUMP TABLE HANDLERS ; ; ++++++++++++++++++++++++++++++++++++++++++++++++ ; ; UP: LXI H,NRP ; INCREMENT NEW ROW POINTER MOV A,M INR A MOV M,A CPI 5 ; DO WE HAVE TO BUMP TO NEXT BOARD ?! JC MOVE ; NOPE -> SIMPLY GO MOVE MVI M,1 ; GOING TO ROW 1 OF NEXT BOARD JMP BDINC ; INCREMENT BD, TESTING FOR WRAPAROUND ; ; DOWN: LXI H,NRP ; DECREMENT NEW ROW POINTER DCR M JNZ MOVE ; OK -> STILL ON SAME BOARD MVI M,4 ; TOP ROW OF NEXT BOARD JMP BDDEC ; GO DECREMENT BD PTR, TESTING FRO WRAPAROUND ; ; RIGHT: LXI H,NCP ; INCREMENT NEW COLUMN POINTER MOV A,M INR A MOV M,A CPI 5 ; OFF BOARD ?! JC MOVE ; NOPE -> SIMPLY GO MOVE MVI M,1 ; END UP IN COLUMN ONE ; BDINC: LXI H,NBP ; INCREMENT NEW BOARD POINTER MOV A,M INR A MOV M,A CPI 5 ; GOING BEYOUND BOARD #4 ?! JC MOVE ; NOPE SIMPLY GO MOVE MVI M,1 ; ELSE WRAPAROUND TO BD # 1 JMP MOVE ; ; LEFT: LXI H,NCP ; DECREMENT NEW COLUMN POINTER DCR M JNZ MOVE ; OK -> NOT GOING TO BD #0 MVI M,4 ; ELSE WRAPAROUND ; BDDEC: LXI H,NBP ; DECREMENT NEW BOARD POINTER DCR M JNZ MOVE ; OK NO WRAPPING MVI M,4 JMP MOVE ; GO AND WRAP IT ; ; YOUMOVE: POP D ; POP PHONNEY RETURN ADDR JMP STRCALL ; GO CALL STRAT SUBR. ; ; GOTMV: POP D ; POP PHONNEY RETURN ADDR LXI H,BP ; CONVERT BOARD POSITION INTO INDEX MOV A,M DCR A ; 16*(BP-1) ADD A ADD A ADD A ADD A MOV B,A INX H MOV A,M DCR A ; + 4*(CRP-1) ADD A ADD A INX H ADD M ; + CCP ADD B LXI H,MOVEARY ADD L MOV L,A MOV A,M SUI 1 SBB A JZ GETERROR ; SQUARE ALREADY OCCUPIED ! MVI M,1 ; ELSE LET'M HAVE IT MVI C,'X' CALL CO MVI C,BSPACE ; PRINT HIS "X" CALL CO ; AND BACK SPACE CURSOR OVER POSITION STRCALL: LXI H,MSG3 ; PRINT CALL PRINTMESAG ; "I'M THINKING !" CALL STRAT ; CALL THE STRATEGY ROUTINE LDA M3 CPI 3 JP L18 CPI 1 MVI A,'O' LXI H,MSG5 JNZ L15 ; JUMP IF WE'VE WON MVI A,'X' LXI H,MSG6 ; HE'S WON !? L15: STA K8 CALL PRINTMESAG L15E: LDA M1 DCR A MOV L,A MVI H,0 DAD H DAD H INX H LXI D,ROW DAD D MVI D,4 L16: MOV A,M CALL PLACEIT PUSH H PUSH D CALL MOVE POP D POP H LDA K8 MOV C,A CALL CO MVI C,BSPACE CALL CO DCR D INX H JNZ L16 LDA K8 CPI ' ' JZ L17A STA J8 MVI A,' ' JMP L17B L17A: LDA J8 L17B: STA K8 CALL CSTS JZ L15E CALL CI JMP BEGIN L18: LDA M1 ORA A JNZ L13A LDA CBP MOV E,A MVI D,0 L14: LXI H,WAIT DAD D MOV C,M MVI B,0 LXI H,MOVEARY ; WE'RE GETTING A WAITING MOVE DAD B MOV A,M ORA A JZ L13 INX D MVI A,21 CMP E JNZ L14 LXI H,MSG4 ; NO WAITING MOVES LEFT ! CALL PRINTMESAG ; PRINT "TIE GAME !!!" CALL CI ; WAIT FOR INPUT JMP BEGIN L13A: MOV C,A LXI H,MOVEARY ADD L MOV L,A L13: MVI M,5 ; CLAIM SQUARE FOR US MOV A,C CALL PLACEIT CALL MOVE MVI C,'O' ; SHOW OUR "O" CALL CO MVI C,BSPACE CALL CO JMP GETMOVE ; GET OPPONENTS RESPONSE ; ; ; ++++++++++++++++++++++++++++++++++++++++++++++++ ; ; SUPPORTING SUBROUTINES ; ; ++++++++++++++++++++++++++++++++++++++++++++++++ ; ; MESAG: MOV A,M ORA A RZ INX H MOV C,A CALL CO JMP MESAG PRINTMESAG: PUSH H ; SAVE ADDR OF MESAG CALL REMEMBERPOSITION ;WE WANT TO COME BACK HERE CALL BDHOME ; HOME CURSOR TO LOWER LEFT BD POSITION MVI B,24 CALL CURSRT ; MOVE CURSOR TO MESSAGE POSITION POP H CALL MESAG CALL BDHOME ; HOME CURSOR AGAIN JMP MOVE ; & RETURN TO WHERE WE WERE ; ; MOVE: LXI H,BP ; START BY GOING TO CORRECT BD LXI D,NBP ; DE=NEW POSITION, HL=CURRENT POSITION MBP: LDAX D ; GET NEW BD # CMP M ; COMPARE TO CURRENP B@ # JZ MBPD ; -> ON MATCH JM MBPL ; WE'RE GOING LEFT INR M ; FIRST UPDATE CURRENT BD # MVI B,WIDTH CALL CURSRT ; MOVE CURSOR RIGHT INTO POSTION MVI B,2 CALL CURSUP ; MOVE CURSOR UP INTO POSITION JMP MBP ; LOOP TILL NEW BD # = CURRENT BD # MBPL: DCR M ; FIRST UPDATE CURRENT BD # MVI B,WIDTH CALL CURSLT ; MOVE CURSOR LEFT INTO POSITION MVI B,2 CALL CURSDN ; MOVE CURSOR DOWN INTO POSITION JMP MBP ; LOOP TIL NEW BD # = CURRENT BD # ; MBPD: INX H INX D ; MEM ORGANIZED AS BP,RP,CP MRP: MVI B,1 LDAX D ; GET NEW ROW POINTER CMP M ; COMPARE TO CURRENT ROW POINTER JZ MRPD ; -> ON MATCH JM MRPL ; GO MOVE DOWN INR M ; FIRST INCREMENT CURRENT ROW POINTER CALL CURSUP ; MOVE UP ONE ROW JMP MRP ; LOOP UNTIL NEW ROW PTR = CURRENT ROW PTR MRPL: DCR M ; FIRST DECREMENT CURRENT ROW POINTER CALL CURSDN ; MOVE DOWN ONE ROW JMP MRP ; LOOP UNTIL NEW ROW PTR = CURRENT ROW PTR ; MRPD: INX H INX D MCP: MVI B,SPACING LDAX D ; GET NEW COLUMN POINTER CMP M ; COMPARE WITH CURRENT COLUMN POINTER RZ ; DONE MOVING WITH A MATCH JM MCPL ; GO MOVE CURSOR LEFT INR M ; FIRST INCREMENT CURRENT COLUMN POINTER CALL CURSRT ; MOVE CURSOR RIGHT ONE COLUMN JMP MCP ; LOOP UNTIL NEW COLUMN PTR = CURRENT COLUMN P MCPL: DCR M ; FIRST DECREMNT CURRENT COLUMN POINTER CALL CURSLT ; MOVE CURSOR LEFT ONE COLUMN JMP MCP ; LOOP UNTIL NEW COLUMN PTR = CURRENT COLUM PT ; ; BDHOME: CALL CURSHOME ; POSITION THE CURSOR AT TRUE "HOME" MVI B,9 CALL CURSDN ; MOVE DOWN TO ROW 1, COL 1 BD 1 LXI H,BP MVI A,1 MOV M,A ; BP = 1 INX H MOV M,A ; RP = 1 INX H MOV M,A ; CP = 1 RET ; ; REMEMBERPOSITION: COPYPOSITION: LXI D,BP LXI H,NBP ; COP] BP(ETC) -> NBP(ETC) MVI B,3 COPYLOOP: LDAX D ; GET BP(I) MOV M,A ; PUT NBP(I) INX D INX H DCR B ; LOOP FOR THREE BYTES JNZ COPYLOOP RET ; ; STRAT: MVI B,1 L15A: MOV A,B LXI H,SUM ADD L MOV L,A MVI M,0 PUSH H MOV L,B MVI H,0 DAD H DAD H DCX H DCX H DCX H XCHG MVI C,4 L15B: LXI H,ROW DAD D MOV A,M LXI H,MOVEARY ADD L MOV L,A MOV A,M POP H PUSH H ADD M MOV M,A INX D DCR C JNZ L15B POP H INR B MVI A,77 CMP B JNZ L15A ; MVI B,1 ; B = J1 ; DO21: MOV A,B STA M3 LXI H,TSTA1 ADD L MOV L,A MOV A,M STA TST1 ORA A JM END21 MOV A,B LXI H,TSTA2 ADD L MOV L,A MOV A,M STA TST2 MOV A,B LXI H,TSTA3 ADD L MOV L,A MOV A,M STA TST3 ; MVI C,1 ; C = J2 ; DO22: MOV A,C LXI H,SUM ADD L MOV L,A LDA TST1 CMP M JNZ END22 MOV A,B SUI 3 JC S18 MOV L,C MVI H,0 DAD H DAD H DCX H DCX H DCX H SHLD J3 MVI A,4 STA K3 ; DO23: LHLD J3 LXI D,ROW DAD D MOV A,M STA M1 LXI H,MOVEARY ADD L MOV L,A MOV A,M ORA A JNZ END23 LDA TST2 ORA A JM S17 ; MVI A,1 STA J4 DO24: LDA J4 LXI H,SUM ADD L MOV L,A LDA TST2 CMP M JNZ END24 LDA J4 CMP C JZ END24 ; MOV L,A MVI H,0 DAD H DAD H DCX H DCX H DCX H SHLD J5 SHLD L5 MVI A,4 STA K5 ; DO25: LHLD J5 LXI D,ROW DAD D LDA M1 CMP M JNZ END25 LDA TST3 ORA A JM S17 LHLD L5 SHLD J6 MVI A,4 STA K6 ; DO26: LHLD J6 LXI D,ROW DAD D MOV A,M STA M2 LXI H,MOVEARY ADD L MOV L,A MOV A,M ORA A JNZ END26 ; MVI A,1 STA J7 ; DO27: LDA J7 MOV D,A LXI H,SUM ADD L MOV L,A LDA TST3 CMP M JNZ END27 MOV A,D CMP C JZ END27 LDA J4 CMP D JZ END27 MOV L,D MVI H,0 DAD H DAD H DCX H DCX H DCX H SHLD J8 MVI A,4 STA K8 ; DO28: LHLD J8 LXI D,ROW DAD D LDA M2 CMP M JZ S16 ; END28: LHLD J8 INX H SHLD J8 LXI H,K8 DCR M JNZ DO28 ; END27: LXI H,J7 INR M MVI A,77 CMP M JNZ DO27 ; END26: LHLD J6 INX H SHLD J6 LXI H,K6 DCR M JNZ DO26 ; END25: LHLD J5 INX H SHLD J5 LXI H,K5 DCR M JNZ DO25 ; END24: LXI H,J4 INR M MVI A,77 CMP M JNZ DO24 ; END23: LHLD J3 INX H SHLD J3 LXI H,K3 DCR M JNZ DO23 ; END22: INR C MVI A,77 CMP C JNZ DO22 ; END21: INR B MVI A,16 CMP B JNZ DO21 ; ; XRA A STA M1 JMP S17 ; S18: MOV A,C STA M1 ; S17: XRA A STA M2 ; S16: RET ; ; ; PLACEIT: MOV B,A DCR A RRC RRC RRC RRC ANI 0FH INR A STA NBP DCR A ADD A ADD A ADD A ADD A MOV C,A MOV A,B SUB C MOV B,A DCR A RRC RRC ANI 3FH INR A STA NRP DCR A ADD A ADD A MOV C,A MOV A,B SUB C STA NCP RET ; ; ; ++++++++++++++++++++++++++++++++++++++++++++++++ ; ; CURSOR CONTROL SUBROUTINES ; ; ++++++++++++++++++++++++++++++++++++++++/+++++++ ; ; CURSUP: MVI C,1FH CALL CO DCR B ; B CONTAINS CNTR FOR ALL CRSR SUB'S JNZ CURSUP RET ; ; CURSDN: MVI C,LF CALL CO DCR B JNZ CURSDN RET ; ; CURSLT: MVI C,BSPACE CALL CO DCR B JNZ CURSLT RET ; ; CURSRT: MVI C,1CH CALL CO DCR B JNZ CURSRT RET ; ; CURSHOME: MVI C,19H JMP CO ; ; ; MSG0: DB 19H,0CH DB 'THREE DIMENSIONAL' DB ' + + + +',CR,LF DB ' TIC - TAC - TOE ' DB ' + + + +',CR,LF DB ' + + + + ' DB ' + + + +',CR,LF DB ' + + + + ' DB ' + + + +',CR,LF DB ' + + + + ' DB ' + + + +',CR,LF DB ' + + + + ' DB ' + + + +',CR,LF DB '+ + + + ' DB ' + + + +',CR,LF DB '+ + + + ' DB ' + + + +',CR,LF DB '+ + + +',CR,LF DB '+ + + +' DB 0 ; MSG1: DB 'ENTER YOUR MOVE',0 MSG2: DB 'TRY AGAIN ',0 MSG3: DB 'I AM THINKING !',0 MSG4: DB 'TIE GAME !!!!!!',0 MSG5: DB 'YOU HAVE LOST !',0 MSG6: DB 'CONGRATULATIONS',0 ; ; ; ++++++++++++++++++++++++++++++++++++++++++++++++ ; ; RAM BUFFER SPACE ; ; ++++++++++++++++++++++++++++++++++++++++++++++++ ; ; ORG 1000H ; BP: CBP: DS 1 ; CURRENT BOARD POINTER CRP: DS 1 ; CURRENT ROW POINTER CCP: DS 1 ; CURRENT COLUMN POINTER ; NBP: DS 1 ; NEW BOARD POINTER NRP: DS 1 ; NEW ROW POINTER NCP: DS 1 ; NEW COLUMN POINTER ; MOVEARY: DS 65 SUM: DS 77 TST1: DS 1 TST2: DS 1 TST3: DS 1 M1: DS 1 M2: DS 1 M3: DS 1 J3: DS 2 K3: DS 1 J4: DS 1 J5: DS 2 K5: DS 1 L5: DS 2 J6: DS 2 K6: DS 1 J7: DS 1 J8: DS 2 K8: DS 1 ; WAIT: DB 0,22,43,23,42,26,39,27,38,1,64,13,52,4 DB 61,16,49,22,43,23,42 ; TSTA1: DB 0, 4,15, 3,10,10, 2, 2, 2, 2, 1, 5, 5, 5, 5,-1 TSTA2: DB 0,-1,-1,-1,10, 5, 2, 1, 1, 0, 1, 5, 5, 0, 0,-1 TSTA3: DB 0,-1,-1,-1,-1,10,-1, 2, 1, 2, 1,10, 5,10, 5,-1 ; ROW: DB 0 DB 22,43,64, 1,23,42,61, 4 DB 26,39,52,13,27,38,49,16 DB 22,42,62, 2,23,43,63, 3 DB 23,38,53, 8,27,42,57,12 DB 26,38,50,14,27,39,51,15 DB 22,39,56, 5,26,43,60, 9 DB 22,38,54, 6,23,39,55, 7 DB 26,42,58,10,27,43,59,11 DB 22,23,24,21,26,27,28,25 DB 22,26,30,18,23,27,31,19 DB 22,27,32,17,23,26,29,20 DB 38,39,40,37,42,43,44,41 DB 38,42,46,34,39,43,47,35 DB 38,43,48,33,39,42,45,36 DB 61, 1,21,41,64, 4,24,44 DB 49, 4,19,34,61,16,31,46 DB 49,13,25,37,52,16,28,40 DB 52, 1,18,35,64,13,30,47 DB 49, 1,17,33,52, 4,20,36 DB 61,13,29,45,64,16,32,48 DB 4, 1, 2, 3,16,13,14,15 DB 13, 1, 5, 9,16, 4, 8,12 DB 16, 1, 6,11,13, 4, 7,10 DB 52,49,50,51,64,61,62,63 DB 61,49,53,57,64,52,56,60 DB 64,49,54,59,61,52,55,58 DB 18,34,50, 2,19,35,51, 3 DB 21,37,53, 5,24,40,56, 8 DB 25,41,57, 9,28,44,60,12 DB 30,46,62,14,31,47,63,15 DB 6, 7, 8, 5,10,11,12, 9 DB 6,10,14, 2, 7,11,15, 3 DB 18,19,20,17,30,31,32,29 DB 21,25,29,17,24,28,32,20 DB 34,35,36,33,46,47,48,45 DB 37,41,45,33,40,44,48,36 DB 54,55,56,53,58,59,60,57 DB 54,58,62,50,55,59,63,51 ; END  DB