home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol075
/
oznaki1.asm
< prev
next >
Wrap
Assembly Source File
|
1985-02-09
|
6KB
|
287 lines
; ***** 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
ê Ç ² ╛ √ ■■√ ■ @ Ç