home *** CD-ROM | disk | FTP | other *** search
- ; ***** 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
- ê Ç ² ╛ √ ■ ■ √ ■ @ Ç