;       ***** LIFE *****
;
; A GAME OF LIFE FOR A VDM DISPLAY.
;
;Adapted from the 'Oznaki' life program (Dr Dobbs, No. 24)
;by R. Daniells of the S.A.M.G. Inc.
;
;This version of life uses the screen memory of the Processor
;Technology VDM-1 display to store the current status of the
;cells.  It should work OK with similar memory mapped VDU's
;such as the DG-640 with perhaps a few modifications.
;
;Caution: Program contains some machine dependant I/O due to
;the lack of a non-echoing input routine in CP/M.
;
VDM     EQU     0CC00H  ;START OF VDM MEMORY.
VDMU    EQU     VDM SHR 8  ;HIGH BYTE OF VDM MEMORY.
VDMPT   EQU     0C8H    ;VDM CONTROL PORT (TO INHIBIT SCROLL).
ALIVEC  EQU     0AAH    ;ALIVE CHARACTER.
DEADC   EQU     7FH     ;DEAD CHARACTER.
CR      EQU     0DH     ;CARRIAGE RETURN CHARACTER.
LF      EQU     0AH     ;LINEFEED CHARACTER.
KSTAT   EQU     0       ;KEYBOARD STATUS PORT.
KDATA   EQU     2       ;KEYBOARD DATA PORT.
RDR     EQU     10H     ;KEYBOARD DATA READY MASK.
ENTRY   EQU     5       ;ENTRY TO CP/M.
;
       ORG     100H
START:  LXI     H,0  ;SAVE CPM'S STACK.
       DAD     SP
       SHLD    OLDSTK
MLOOP:  LXI     SP,NEWSTK ;SET UP NEW LOCAL STACK.
       MVI     A,0
       OUT     0C8H    ;INIT VDM (NO SCROLLING).
CLEAR:  LXI     H,VDM+400H  ;GENERATE DEAD SCREEN.
       MVI     A,VDMU-1
BLANK:  MVI     M,DEADC
       DCX     H
       CMP     H
       JNZ     BLANK
READY:  PUSH    H
       MVI     A,0     ;CLEAR ONE-GENERATION FLAG.
       STA     ONEFLAG
       LXI     B,0FFC0H  ;NORTH ADDRESS INCREMENT.
                         ;B IS ALSO CURSOR CHAR.
       LXI     D,40H   ;SOUTH ADDRESS INCREMENT.
READIN: MOV     C,M     ;REAL CHAR IN C.
       MOV     M,B
INPUT:  CALL    GETCH   ;WAIT FOR INPUT CHARACTER.
       JZ      INPUT
       MOV     M,C
       MVI     C,0C0H  ;RESTORE C.
       CPI     'C'-40H ;CONTROL - C?
       JZ      EXIT
       CPI     30H     ;NUMBER?
       JC      NOTNUM
       CPI     3AH     ;NUMBER LESS THAN 9?
       JC      SETSPD
NOTNUM  CPI     'H'     ;REQUEST FOR HELP?
       JZ      HELP
       CPI     'N'     ;MOVEMENT COMMAND?
       CZ      NORTH
       CPI     'S'
       CZ      SOUTH
       CPI     'E'
       CZ      EAST
       CPI     'W'
       CZ      WEST
       CPI     'M'
       CZ      MIDDLE
       CPI     'K'     ;KILL CELL?
       CZ      KILL
       CPI     'L'     ;GRANT LIFE?
       CZ      LIVE
       CPI     'C'     ;CLEAR SCREEN?
       CZ      CLEAR
       CPI     'O'     ;ONE GENERATION ONLY?
       CZ      ONEGEN
       CPI     'G'     ;GO?
       JNZ     READIN
       POP     H       ;SET VDM-1 IN CURRENT GENERATION POINTER.
LIFE    XRA     A       ;INIT CELL COUNTER.
       ADD     M
       DAD     B       ;TO GO NORTH.
       ADD     M
       INX     H       ;TO GO EAST.
       ADD     M
       INX     H       ;TO GO EAST.
       ADD     M
       DAD     D       ;TO GO SOUTH.
       ADD     M
       DAD     D       ;TO GO SOUTH.
       ADD     M
       DCX     H       ;TO GO WEST.
       ADD     M
       DCX     H       ;TO GO WEST.
       ADD     M
       INX     H       ;TO GO EAST.
       DAD     B       ;TO GO NORTH.
       ANI     7       ;WHAT'S IN BOTTOM 3 BITS.
       CPI     6       ;WERE THERE 2 LIVE?
       CNZ     MARK    ;DO NOTHING IF 2 NEIGHBORS.
       MOV     A,H     ;HAVE WE CHECKED ALL OF SCREEN?
       CPI     0D0H
       JNZ     LIFE    ;CONTINUE IF NOT DONE.
       CALL    DELAY   ;DELAY BETWEEN GENERATIONS.
;BIRTH/DEATH AGONY SEQUENCE.
C1      DCX     H
       MOV     A,M
       ORA     A
       CPE     LIVE
       CPO     KILL
       MOV     A,H
       CPI     VDMU-1
       JNZ     C1
; DELAY FOR VIEWING MARKED LOCATIONS.
       CALL    DELAY
; SEE IF ONLY ONE GENERATION REQUESTED.
       LDA     ONEFLAG
       ORA     A
       JNZ     READY   ;STOP IF SO.
; DISPLAY CAN BE STOPPED AND ALTERED.
       CALL    GETCH   ;SEE IF KEY PRESSED.
       JZ      LIFE    ;CONTINUE IF NOT.
       JMP     READY   ;ELSE, GET NEW COMMAND.
;
; ROUTINES THAT MARK CELLS FOR POSSIBLE ALTERATION.
MARK    CPI     1       ;ARE THERE EXACTLY 3 LIVE NEIGHBOURS?
       JZ      LMARK
DMARK   MVI     A,DEADC
       ANA     M
       MOV     M,A     ;CELL NOW MARKED FOR DEATH.
       RET
LIVEMARK        EQU     80H
LMARK   MVI     A,LIVEMARK
       ORA     M
       MOV     M,A     ;CELL NOW MARKED FOR LIFE.
       RET
; ROUTINES FOR SEEDING THE SCREEN.
NORTH   DAD     B
       RET
SOUTH   DAD     D
       RET
EAST    INX     H
       RET
WEST    DCX     H
       RET
MIDDLE  LXI     H,VDM+220H
       RET
KILL    MVI     M,DEADC
       RET
LIVE    MVI     M,ALIVEC
       RET
;NON-ECHOING CHARACTER INPUT ROUTINE.
GETCH:  IN      KSTAT   ;GET STATUS
       ANI     RDR     ;SEE IF KEY PRESSED.
       RZ              ;RETURN IF NOT.
       IN      KDATA   ;ELSE, GET CHARACTER.
       ANI     7FH     ;STRIP PARITY.
       RET
;
; DELAY ROUTINE.
DELAY   PUSH    D       ;SAVE REGISTERS.
       PUSH    B
       LDA     DMULT   ;GET DELAY MULTIPLIER.
       MOV     B,A     ;PUT IN REG. B.
       ORA     A       ;WANT MAXIMUM SPEED?
       JZ      NODEL   ;SKIP DELAY IF SO.
DELA1   LXI     D,16665 ;LOAD LOOP COUNT.
DELA2   DCX     D       ;DECREMENT COUNT.
       MOV     A,D
       ORA     E       ;ZERO YET?
       JNZ     DELA2   ;CONTINUE IF NOT.
       DCR     B       ;DECREMENT DELAY MULTIPLIER.
       JNZ     DELA1
NODEL   POP     B       ;RESTORE REGISTERS.
       POP     D
       RET
;
SETSPD  SUI     30H     ;REMOVE ASCII BIAS.
       STA     DMULT   ;UPDATE DELAY MULTIPLIER.
       JMP     READY
;
ONEGEN  MVI     A,1     ;SET ONEFLAG.
       STA     ONEFLAG
       MVI     A,'G'   ;PUT G IN ACC.
       RET
;
HELP    CALL    CLS     ;CLEAR SCREEN, INIT CURSOR.
       LXI     D,HMESS ;POINT TO MESSAGE.
       MVI     C,9     ;PRINT BUFFER FUNCTION FOR CP/M.
       CALL    ENTRY   ;PRINT THE MESSAGE.
WAIT    CALL    GETCH   ;WAIT FOR KEY DEPRESSION.
       JZ      WAIT
       JMP     MLOOP   ;THEN RESTART.
;
HMESS   DB      'AVAILABLE '
       DB      'COMMANDS '
       DB      'ARE:'
       DB      CR
       DB      LF
       DB      'H =    HELP.'
       DB      CR
       DB      LF
       DB      'C =    CLEAR '
       DB      'SCREEN.'
       DB      CR
       DB      LF
       DB      'M =    GO TO '
       DB      'MIDDLE OF '
       DB      'SCREEN.'
       DB      CR
       DB      LF
       DB      'N =    GO '
       DB      'NORTH.'
       DB      CR
       DB      LF
       DB      'S =    GO SOUTH.'
       DB      CR
       DB      LF
       DB      'E =    GO EAST.'
       DB      CR
       DB      LF
       DB      'W =    GO WEST.'
       DB      CR
       DB      LF
       DB      'G =    GRANT '
       DB      'LIFE.'
       DB      CR
       DB      LF
       DB      'O =    DO ONE '
       DB      'GENERATION '
       DB      'THEN HALT.'
       DB      CR
       DB      LF
       DB      'L =    MAKE '
       DB      'LIVE CELL.'
       DB      CR
       DB      LF
       DB      'K =    KILL CELL.'
       DB      CR
       DB      LF
       DB      'NUMBER '
       DB      '0 - 9 = '
       DB      'SET DELAY '
       DB      '(0 = FASTEST '
       DB      'SPEED).'
       DB      CR
       DB      LF
       DB      'ANY KEY = '
       DB      'HALT, AND '
       DB      'WAIT FOR '
       DB      'NEW COMMAND.'
       DB      CR
       DB      LF
       DB      CR
       DB      LF
       DB      'PRESS '
       DB      'ANY KEY '
       DB      'TO RESTART.'
       DB      '$'     ;DELIMITER.
;
EXIT    LHLD    OLDSTK  ;RESTORE CP/M'S STACK.
       SPHL
       RET             ;BACK TO CPM.
;
;ROUTINE TO CLEAR SCREEN AND INITIALIZE CURSOR.
CLS     LXI     H,VDM   ;POINT TO SCREEN MEMORY.
       MVI     M,80H+' ' ;THIS IS THE CURSOR.
       INX     H       ;BUMP POINTER.
CLS1    MVI     M,' '   ;STORE BLANK.
       INX     H       ;NEXT....
       MOV     A,H     ;SEE IF END OF SCREEN YET.
       CPI     VDMU+10H
       JC      CLS1    ;CONTINUE IF NOT.
       RET
;
ONEFLAG DB      0       ;FLAG FOR ONE GENERATION MODE.
DMULT   DB      0       ;DELAY MULTIPLER.
;
       DS      12      ;SPACE FOR LOCAL STACK.
NEWSTK  EQU     $       ;LOCAL STACK TOP.
OLDSTK  DS      2       ;SAVE CPM'S STACK HERE.
;
       END
���������s������ �� ���������l��� �������v���������� �� ���� ����H�      ���� ��w�������������_L��
�����������������������������������@��������������