;LIFE.ASM - Source code for m100 game of LIFE ;Kenneth G. Jackson - 71316,1321 - 12/25/88 ; ;SAVECO & KILL routines from James Yi: HXFER.ASM ; ;SVIMG routine from G.W. Flander: QIKDMP.SRC ; ORG $EF40 SELECT EQU $4CBF RFLPTR EQU $2146 RESTORE FILE DEVICE EQU $F675 MENU EQU $5797 PRNT@1 EQU $5791 PRINT @ CLMN 1 LINPA EQU $463E LINE INPUT BEEP EQU $7662 ;SOUND BEEP GETLEN EQU $21FA COUNT LENGTH FMTFNM EQU $4C0B FORMAT FILENAME FINDCO EQU $2089 LOADBL EQU $6C9C LOAD BA LABEL ERRTRP EQU $04B7 MAXFIL EQU $7F2B SET MAXFIL RETERR EQU $047B SYSTEM ERROR PROCESSING CLOSE EQU $4E27 CLOSE FILES BELL EQU $4229 DELY2S EQU $5310 OMMSG EQU $60B1 BYTES EQU $7432 READS BYTES UNDER CURSOR AND LOADS THEM INTO ;SIX MEMORY LOCATIONS STARTING AT (HL) INTX EQU $765C DISABLE INTERRUPTS RTIME EQU $19A0 PSTR EQU $27B1 PRINT STR AT CUR POS GETTIM EQU $190F HL-> BUFFER KYREAD EQU $7242 Z SET NO CHR WAITING CHLDE EQU $0018 COMPAIR HL TO DE PLOT EQU $744C CLS EQU $4231 MAXX EQU 128 OUTPOS EQU $427C L COLUMN H ROW BINASC EQU $39D4 HL CONTAINS BINARY MAXY EQU 64 OUTCHR EQU $20 WAITSP EQU $5F2F WAIT FOR PRESS AND RT HIMEM EQU $F5F4 HIMEM STRORAGE PIXBUF EQU $D3E5 AFTER EQU PIXBUF+1921 TOP EQU $FACE LEN EQU $FAD0 EXE EQU $FAD2 SECOND EQU $F923 MINUTE EQU $F925 HOUR EQU $F927 BEGIN CALL CHKMEM ;CHECK HIMEM SETTING DB 12,25,88 PBEGIN JMP PRSCN PRINT SCREEN BEGIN0 CALL LOADBL LOAD LABEL LXI H,TRAPIT SET BA ERROR TRAP SHLD ERRTRP TO OURS LXI H,CREDIT CALL PSTR CALL DELY2S CALL DELY2S BEGINX CALL ZEROCT CALL RANDOM BEGIN7 XCHG PUT HL IN DE CALL LITTLE MAI0 CALL SCREEN CALL KYREAD CHECK KEYBOARD CNZ CONTRL NOTHING MAI01 CALL PRPBUF CALL KYREAD CNZ CONTRL CALL CNTGEN CALL NXTGEN CALL KYREAD CNZ CONTRL JMP MAI0 LOAD CALL OPENCO JC GETBY9 NO VALID NAME XCHG SHLD WTEMP TEMP PLACE LXI HL,MYBUF ; CALL MOVE XLOAD CALL CLEAR CLEAR WORLD XLOAD1 LHLD WTEMP XCHG LXI H,WORLD LOCATE WORLD SHLD WTEMP MVI A,8 8 PASSES STA LCOUNT GETBY0 MVI B,MAXX WANT ONLY MAXX COLUMN GETBYT LDAX D GET BYTE GETBY1 INX D BUMP OFFSET PUSH BC SAVE PASS COUNT PUSH DE LHLD WTEMP INDEX WORLD CALL BYTE PUT EACH BIT IN PLACE INX HL MOVE TO NEXT COLUMN SHLD WTEMP SAVE POINTER POP DE POP BC DCR B COLUMN DONE? JNZ GETBYT ..NO..DO ANOTHER LXI HL,240-MAXX SKIP LAST OF PIX DAD DE XCHG BACK IN DE PUSH DE LHLD WTEMP INDEX WORLD LXI DE,7*MAXX SKIP LINES DONE DAD DE SHLD WTEMP POP DE LDA LCOUNT GET PASS COUNT DCR A COUNT ONE JZ GETBY9 DO NEXT STA LCOUNT JMP GETBY0 GETBY9 CALL CLOSE RET LABEL LXI HL,$1B03 FOR TIME CALL OUTPOS LXI HL,$FD8B BUFR IN ALTLCD PUSH H SAVE PTR CALL GETTIM GET TIME MVI M,00 MARK END POP H GET PTR CALL PSTR LXI HL,$1A06 CALL OUTPOS LXI HL,LMSG CALL PSTR LXI HL,$1A05 CALL OUTPOS LXI HL,GMSG CALL PSTR LXI HL,$1708 CALL OUTPOS LXI HL,FNKMSG CALL PSTR PRINT STRING RET FNKMSG DB 'S Rnd Load Menu',0 LMSG DB 'Cells',0 GMSG DB 'Age',0 CONTRL CPI 7 MENU JNZ C2 CALL MENU C2 CPI 6 LOAD PALETTE JNZ C3 CALL LOAD CALL ZEROCT POP DE REMOVE RET ADDR JMP MAI0 PRINT LOAD C3 CPI 5 RESTART RANDOM JNZ C4 POP DE REMOVE RET ADDR JMP BEGINX C4 CPI 4 SAVE SCREEN JNZ C5 CALL SAVE LXI HL,MYBUF SHLD WTEMP CALL XLOAD ;CURRENT POP DE JMP MAI0 RESUME C5 CPI 9 ? PRINT JNZ C6 ..NO IN 187 CHECK PRINTER ANI 6 CPI 2 JNZ C5ER NOT READY CALL SVIMG GET SCREEN CALL PBEGIN 'JUMP TABLE' C51 POP DE JMP MAI0 RESTART C5ER LXI H,$1603 POSITION CURSOR CALL OUTPOS LXI H,PREROR CALL PSTR LXI H,$1604 CALL OUTPOS LXI H,SPSTR CALL PSTR CALL WAITSP JMP C51 PREROR DB 'Printer not ready!',0 SPSTR DB 'Space to continue!',0 C6 CPI 3 FN 4 JNZ C7 CALL ZEROCT LHLD LASTRN DO LAST RANDOM XCHG CALL LITTLE ADDR IN DE POP D RETURN OFF SP JMP MAI0 C7 LXI HL,$2506 POSITION CURSOR CALL OUTPOS CALL WAITSP RET BYTE PUSH HL MVI B,8 SET COUNTER BYTE0 RAR GET FIRST BIT JNC BYTE1 NOTHING..SKIP STA TEMP SAVE A MOV A,M SET CELL ALIVE ORI 1 MOV M,A PUT IT BACK LDA TEMP RETRIEVE A BYTE1 DCR B COUNT 1 JZ BYTE9 DONE WITH BYTE XCHG LXI H,MAXX LOCATE NEXT CELL DAD DE JMP BYTE0 LOOP BYTE9 POP HL RET CLEAR PUSH HL PUSH DE LXI HL,PREWORLD LXI DE,CHAOS CLEAR1 XRA A LOAD A WITH 0 MOV M,A INX HL CALL CHLDE JC CLEAR1 POP DE POP HL RET SCREEN CALL CLS CALL LABEL LXI HL,WORLD MVI E,0 LINE TO ZERO SCREE1 MVI D,0 COLUMN TO ZERO SCREE2 PUSH D PUSH H MOV A,M PLOT OR NOT? ANI 1 JZ SCREE4 CALL PLOT SCREE4 POP H POP D INX H INR D BUMP COLUMN MOV A,D CPI MAXX LAST COLUMN? JNZ SCREE2 NO, LOOP INR E YES, BUMP LINE. MOV A,E CPI MAXY LAST LINE? JNZ SCREE1 NO, LOOP RET NXTGEN LXI HL,WORLD INDEX WORLD NXTGE1 CALL SURVEY COUNT NEIGHBORS MOV A,M CHECK THIS CELL ANI 2 OCCUPIED? JZ BIRTH? ..NO.. LDA NEIGHB NEIGHBOR COUNT CPI 2 HAS 2 NEIGHBOR JZ SURVIV ..YES.. CPI 3 HAS 3 NEIGHBORS JZ SURVIV ..YES.. JMP END AUTO EXECUTION BIRTH? LDA NEIGHB NEIGHBOR COUNT CPI 3 A BIRTHING? JNZ END NOPE SURVIV MOV A,M GET CELL ORI 1 PLANT LIFE MOV M,A PUT BACK PUSH HL LHLD LIVECT INX HL SHLD LIVECT POP HL END INX HL LXI DE,AFTERLIFE CALL CHLDE JC NXTGE1 BLANK LXI HL,WORLD+MAXX BLANK LXI DE,MAXX THE 128 COLUM MVI B,64 SO THERE'S XRA A NO OVERLAP BLANK1 MOV M,A OF DISPLAY ENDS DAD DE DCR B JNZ BLANK1 RET ; ENTERS WITH HL POINTING TO CELL SURVEY PUSH HL POINTS TO CELL XRA A STA NEIGHB LXI DE,WORLD+MAXX WILL IT CALL CHLDE BE BEYOND EDGE? JC SURVE4 LXI DE,-MAXX-1 ROW ABOVE DAD DE CALL COUNT SURVE4 POP HL POINT TO CELL AGAIN PUSH HL LXI DE,AFTERLIFE-MAXX+1 CALL CHLDE BEYOND EDGE JNC SURVE5 ...YES LXI DE,MAXX-1 ROW BELOW DAD DE CALL COUNT SURVE5 POP HL POINT TO CELL AGAIN PUSH HL DCX HL NEIGHBOR BEHIND MOV A,M ANI 2 ALIVE? CNZ BUMPB YES! COUNT SURVE1 INX HL NEIGHBOR AHEAD INX HL MOV A,M ANI 2 ALIVE? CNZ BUMPB YES! COUNT POP HL X9 RET PRPBUF LXI DE,AFTERLIFE LXI HL,WORLD PRPBU1 MOV A,M PREP FOR NEXT GENERATION STC RLC ANI $2 MOV M,A ;SAVE INX HL CALL CHLDE JC PRPBU1 PRPBU9 RET ; HL POINTS TO BEGINING OF NEIGHBORHOOD COUNT MVI C,3 CHECK FOR 3 COUNT2 MOV A,M GET CELL ANI 2 ALIVE? CNZ BUMPB YES! COUNT COUNT1 INX H INDEX NEXT CELL DCR C COUNT COUNT JNZ COUNT2 NOT DONE LOOP RET BUMPB LDA NEIGHB INR A COUNT 1 STA NEIGHB RET CNTGEN LXI HL,$2205 CALL OUTPOS LHLD GCOUNT INX HL BUMP COUNT SHLD GCOUNT CALL BINASC PRINT IT LXI HL,$2206 CALL OUTPOS LHLD LIVECT CALL BINASC LXI HL,0 SHLD LIVECT RET ZEROCT LXI HL,0 SHLD GCOUNT SHLD LIVECT RET GETNAM LXI H,$1901 CALL OUTPOS LXI H,COMSG CALL PSTR LXI H,$1903 CALL OUTPOS LXI H,PALTSG PALLETE FILE CALL PSTR GUIDE LXI H,$1902 CALL OUTPOS CALL LINPA GET FILE NAME RST 2 ANYTHING ? JZ GETNA8 ...NO... CALL GETLEN GET LEN OF NAME CALL FMTFNM FORMAT STC CMC NOTE FIND RET GETNA8 STC NOTE NO NAME RET OPENCO CALL GETNAM CALL FINDCO JZ FFERR DIDN'T FIND INX D INX D AT FILE LENGTH INX D INX D AT EXEC ADDR INX D INX D FIRST OPENC9 RET TRAPIT MOV A,E CPI 52 JZ FFERR CPI 7 JZ OMERR CPI 55 JZ NMERR JMP RETERR OTHERS ER: RESUME PROCESSING FFERR LXI H,NOFILE JMP PRERR NMERR LXI H,BADNAM JMP PRERR OMERR LXI H,OMMSG OUT OF MEMORY PRERR PUSH H CALL CLOSE LXI H,$1908 CALL OUTPOS POP H CALL PSTR CALL BELL CALL DELY2S RET SAVE CALL SVIMG LXI HL,PIXBUF ;TO PTR LXI DE,MYBUF ;FROM CALL MOVE CALL GETNAM JC SAVEND LXI H,PIXBUF SHLD TOP LXI H,1920 SHLD LEN LXI H,$0 SHLD EXE CALL FINDCO DOES .CO EXIST? CNZ KILL ASK AND KILL CALL RFLPTR RESTORE PTR CALL SAVECO CREATE A NEW CO SAVEND CALL CLOSE RET SVIMG XRA A STA TOGL+1 STORE/PAINT FLAG LXI H,MYBUF THE 1920 BYTE BUFR XRA A NXR STA $FFF4 SET CURSOR ROW XRA A NXC STA $FFF5 SET CURSOR COLUMN PUSH H CALL INTX DISABLE INTERRUPS TOGL MVI D,00 OADS D REG WITH 0 OR 1 CALL BYTES READ 6 BYTES POP H LXI B,6 DAD B INCR 6 BYTES LDA $FFF5 CURSOR COLUMN INR A INCR BY 1 CPI $28 END OF ROW? JNZ NXC NO..DO ANOTHER LDA $FFF4 CHECK CURRENT ROW CPI 7 AT END? RZ IF SO EXIT INR A NO..INCR JMP NXR SAVECO CALL $2089 ;ROM routine, mod to give RET CNZ $1FD9 ;instead of JMP to Basic CALL $20E4 PUSH H LHLD $FBB0 PUSH H LHLD $FAD0 MOV A,H ORA L JZ $3F17 PUSH H LXI B,$6 DAD B MOV B,H MOV C,L LHLD $FBB2 SHLD $FB99 CNC $6B6D JC $3F17 XCHG LXI H,$FACE CALL $2540 LHLD $FACE POP B CALL $6BDB POP H SHLD $FBB0 POP H MVI A,$A0 XCHG LHLD $FB99 XCHG CALL $2239 CALL $2146 LHLD $FB8E RET ; KILL MOV A,M ;from M200 ROM code INX H ;no equiv M100 code found MOV E,M INX H MOV D,M DCX H DCX H CPI $C0 JZ $1FBF CPI $80 JZ $2017 JMP $1FD9 LITTLE CALL CLEAR PTRN IN DE LXI H,WORLD PUSH DE LXI D,2604 ;START DAD D ;HERE MVI C,3 ;3 LINES ;24 DOTS LITTL0 MVI B,20 ;20 DOTS WIDE LITTL1 POP DE LDAX D ;GET CHARACTER INX D ;POINT TO NEXT PUSH DE PUSH B CALL BYTE ;PUT ONE INX H POP B DCR B JNZ LITTL1 LXI D,(7*120)-92 ;NEXT DAD D DCR C JNZ LITTL0 POP DE RET MOVE PUSH B LXI B,1920 MOVE1 LDAX D ;GET CHAR INX D ;BUMP POINTER MOV M,A ;SAVE CHAR INX H ;BUMP DCX B ;COUNT MOV A,B ;?ZERO ORA C JNZ MOVE1 POP B RET BUFLOC DB 00,00 CHAR DB 0 RANDOM PUSH D PUSH B CALL RTIME READ TIME LHLD SECOND MOV B,H MOV C,L XCHG LHLD MINUTE DAD D XCHG LHLD HOUR LDAX D RANDO1 ADC M INX H DCR C JNZ RANDO1 MOV E,A DAD D LHLD LASTRN DAD D MOV A,H ANI $7F MOV H,A SHLD LASTRN POP D POP B RET LIVECT DB 0,0 TEMP DB 0 WTEMP DB 0,0 PTEMP DB 0,0 NEIGHB DB 0 GCOUNT DB 0,0 COMSG DB 'File Name',0 PALTSG DB ' _____] ',0 BUFLEN DB 0 BADNAM DB 'Bad File Name' 0 NOFILE DB 'File not found ' 0 ERRMSG DB 'Corrupt file' 0 LASTRN DB 00,00 RNM DB 0 LCOUNT DB 0 CREDIT DB $12,$D,$A,$A,' L I F E' DB $D,$A,$A,' by Ken Jackson' DB $D,$A,$A,' 71316,1321',0 CHKMEM POP HL ;RTRN ADDR LXI D,MYBUF-BEGIN-4 DAD D ;SHOULD BE HIMEM SHLD TEMP ;SAVE XCHG LHLD HIMEM ;CURRENT HIMEM CALL CHLDE JNC MEMMSG ;HIMEM NOT CORRECT JMP BEGIN0 ;OK MEMMSG CALL CLS CALL BEEP LXI H,$1003 CALL OUTPOS LXI H,HMSG CALL PSTR ;PRINT IT LHLD TEMP ;GET # CALL BINASC ;PRINT IT CALL WAITSP ;GET RESPONSE JMP MENU HMSG DB 'Check HIMEM!!',$A,$D DB 'Set to be lower than the following!...' DB $A,$D,'Press space key to continue. DB $A,$D,' ',0 PRSCN MVI A,1 STA DEVICE LPT CALL SVIMG CALL SETUP SCREEN->PRINTER CALL PRSET LXI H,GOFF SHUT OFF GRAPHICS CALL PSTR OFF GRAPHICS XRA A STA DEVICE LCD RET SETUP LXI H,PSTRNG INDEX SETUP SETUP1 PUSH H SAVE MOV A,M GET CHAR CPI $FF ?END OF STR JZ SETUP9 ..YES CALL OUTCHR PRINT IT POP H RETRIEVE PTR INX H NEXT JMP SETUP1 LOOP SETUP9 POP H ADJUST STACK RET SHIFT PUSH B PUSH D PUSH H XRA A STA CHAR MVI B,3 COUNT 3 SHIFTS SHIFT1 POP H PUSH H BYTE WANTED LXI D,(2*240) DAD D 3 LINE 'DOWN' LXI D,AFTER CALL CHLDE HL>AFTER? LXI D,-240 ROW LENGTH JC SHIFT2 ..NO JMP SHIFT3 ..WITH C CLEAR SHIFT2 MOV A,M GET BYTE STC CMC CLEAR C RAR MOV M,A PUT IT BACK SHIFT3 PUSH PSW SAVE FLAGS DAD D NEXT ROW POP PSW MOV A,M DO IT 3 TIMES RAR MOV M,A PUSH PSW DAD D POP PSW MOV A,M RAR MOV M,A LDA CHAR PREP FOR SHIFT RAR STA CHAR SAVE IT DCR B ? DONE JNZ SHIFT1 ..NO POP H POP D POP B RET PATTRN PUSH D GET PATTERN PUSH H LXI H,TABLE POINT TO TABLE RAR FROM 7-5 TO 2-0 RAR RAR RAR RAR MVI D,0 SET DO TO ZERO MOV E,A ADD IN A DAD D ADD TO TABLE MOV A,M GET PATTERN ORI 128 FIT FOR PRINTER STA CHAR POP H POP D RET TABLE DB 0,3,12,15 DB 48,51,60,63 PRSET LXI H,MYBUF-(3*240) SHLD BUFLOC PRSET0 LHLD BUFLOC LXI D,3*240 ;? AT END DAD D ;ADD IT IN LXI D,MYBUF+1920-1 END TASK? CALL CHLDE ;COMPAIR H & D JNC PRSET9 SHLD BUFLOC MVI C,8 ;SET COUNTER PRSET1 LHLD BUFLOC 1 TIME THRU MVI E,240 ;1 SCRN WIDTH PRSET2 CALL SHIFT NEXT 3 BITS CALL ONEBYT INX H DCR E JNZ PRSET2 ;NOT LINE END CALL ENDLIN DCR C ;COUNT 1 PASS JNZ PRSET1 DO 8 TIMES JMP PRSET0 PRSET9 RET ENDLIN LXI H,TWIXT JMP SETUP1 ONEBYT LDA CHAR CALL PATTRN PRINT PATTERN PUSH PSW SAVE CHAR CALL OUTCHR PRINT ONCE POP PSW PUSH PSW CALL OUTCHR POP PSW CALL OUTCHR PRSCNE RET TWIXT DB 30 ;GRAPHICS OFF DB 27,28,$D ;LINEFEED DB 18 ;GRAPHICS MODE DB 27,16 ;POSITION DB 0,20 ;AT COL 20 DB $FF ;DONE DB 00,00,00 PSTRNG DB 27,20 ;CONDENSED DB 18 ;GRAPHICS MODE DB 27,16 ;POSITION DB 0,20 ;AT COL 20 DB $FF ;DONE DB 00,00,00 DB 00 GOFF DB 30,$ff,$ff AFTERLIFE EQU BEGIN-2 PREWORLD EQU AFTERLIFE-(MAXX*MAXY)-1 WORLD EQU PREWORLD CHAOS EQU AFTERLIFE+1 MYBUF EQU WORLD-1920 ;1920 END