.nlist .enabl lc,crf .mcall .exit .macro arggen a,b,c,d,e,f,g,h,i,j,k,l,m,n .if nb a .word a arggen b,c,d,e,f,g,h,i,j,k,l,m,n .iff .mexit .endc .endm arggen .macro print arg .if df arg .globl writec jsr r5, writec arg .iff .list .ERROR Undefined argument (arg) in PRINT .nlist .endc .endm print .macro accept no,arg .if df arg .if gt no .globl readc jsr r5, readc .word no,arg .iff .list .ERROR Illegal argument (no) in ACCEPT .nlist .endc .iff .list .ERROR Undefined argument (arg) in ACCEPT .nlist .endc .endm accept .macro readln a,b,c,d,e,f,g,h,i,j,k,l,m,n .narg $no$ .if gt $no$ .globl readd jsr r5, readd .word $no$ arggen a,b,c,d,e,f,g,h,i,j,k,l.m,n .iff .list .ERROR READLN must have an argument .nlist .endc .endm readln .macro writeln a,b,c,d,e,f,g,h,i,j,k,l,m,n .narg $no$ .if gt $no$ .globl writed jsr %5, writed .word $no$ arggen a,b,c,d,e,f,g,h,i,j,k,l,m,n .iff .list .ERROR Writeln Must have an argument .nlist .endc .endm writeln .list .TITLE LIFE DEMO IN SUPERMAC ;## 1 # 0 ## .TITLE LIFE DEMO IN SUPERMAC ;author T. Weslowski 24-oct-81 ; This program demonstrates the game of life ; while running on an intertube. DEAD = 0 ;## 8 # 0 ## DEAD = 0 ALIVE = 1 ;## 9 # 0 ## ALIVE = 1 ROWMAX = 25. ;## 11 # 0 ## ROWMAX = 25. COLMAX = 25. ;## 12 # 0 ## COLMAX = 25. LIFE: .BLKW ROWMAX*COLMAX ;## 14 # 0 ## .BLKW ROWMAX*COLMAX NEXT: .BLKW ROWMAX*COLMAX ;## 15 # 0 ## .BLKW ROWMAX*COLMAX ; array vector ADDR = LIFE ;## 19 # 0 ## ADDR = LIFE AV: .REPT ROWMAX ;## 21 # 0 ## .REPT ROWMAX ADDR ;## 22 # 0 ## ADDR ADDR = ADDR + <2 * COLMAX> ;## 23 # 0 ## ADDR = ADDR + <2 * COLMAX> .ENDR ;## 24 # 0 ## .ENDR ROW: .BLKW 1 ;## 26 # 0 ## .BLKW 1 COL: .BLKW 1 ;## 27 # 0 ## .BLKW 1 ; with r5 (row,col) SUBSCRIPT: ;## 29 # 0 ## PROCEDURE SUBSCRIPT ; leaves address pointer in r5 mov R0,-(sp) ;## 33 # 0 ## PUSH R0,R1 mov R1,-(sp) mov @(R5)+,R0 ;## 34 # 0 ## LET R0 := @(R5)+;fetch row dec R0 ;## 35 # 0 ## LET R0 := R0 - #1 L.SHIFT 1 + #AV; make into address .rept 1 asl R0 .endr add #AV,R0 mov @(R5)+,R1 ;## 36 # 0 ## LET R1 := @(R5)+;fetch column dec R1 ;## 37 # 0 ## LET R1 := R1 - #1 L.SHIFT 1 + (R0) .rept 1 asl R1 .endr add (R0),R1 mov R1,4(SP) ;## 38 # 0 ## LET 4(SP) := R1;save on stack mov (sp)+,R1 ;## 39 # 0 ## POP R1,R0 mov (sp)+,R0 rts R5 ;## 40 # 0 ## RETURN WITH R5 ;<#array> sets array to zero SETTOZERO: ;## 42 # 0 ## PROCEDURE SETTOZERO mov R1,-(sp) ;## 44 # 0 ## PUSH R1 mov #ROWMAX*COLMAX,R1 ;## 45 # 0 ## LET R1 := #ROWMAX*COLMAX ll$1: ;## 46 # 0 ## THRU R1 DO clr (R0)+ ;## 47 # 1 ## LET (R0)+ := #0 sob R1,ll$1 ;## 48 # 0 ## END ll$2: mov (sp)+,R1 ;## 49 # 0 ## POP R1 rts pc ;## 50 # 0 ## RETURN MSG1:.ASCII/ ENTER ROW COL COORDINATES/ <15><12> .ASCIZ/ I WILL STOP WHN YOU ENTER 0 0/ <7><7><15><12> MSG2:.ASCIZ/ ILLEGAL ROW OR COLUMN / .EVEN ;## 55 # 0 ## .EVEN ; initializes life INIT: ;## 56 # 0 ## PROCEDURE INIT mov #LIFE ,r0 ;## 57 # 0 ## CALL SETTOZERO < #LIFE > jsr pc,SETTOZERO mov #NEXT ,r0 ;## 58 # 0 ## CALL SETTOZERO < #NEXT > jsr pc,SETTOZERO PRINT MSG1 ;## 59 # 0 ## PRINT MSG1 READLN ROW,COL ;## 60 # 0 ## READLN ROW,COL ll$3: ;## 61 # 0 ## WHILE ROW <> #0 AND COL <> #0 DO cmp ROW,#0 bNE ll$6 jmp ll$5 ll$6: cmp COL,#0 bNE ll$7 jmp ll$5 ll$5: jmp ll$4 ll$7: cmp ROW,#0 ;## 62 # 1 ## IF ROW > #0 AND ROW <= #ROWMAX AND COL > #0 AND COL <= #CO bGT ll$9 jmp ll$8 ll$9: cmp ROW,#ROWMAX bLE ll$10 jmp ll$8 ll$10: cmp COL,#0 bGT ll$11 jmp ll$8 ll$11: cmp COL,#COLMAX bLE ll$12 jmp ll$8 ll$12: jsr R5,SUBSCRIPT ;## 63 # 2 ## CALL SUBSCRIPT WITH R5 (ROW,COL) .word ROW,COL mov #ALIVE,(R5) ;## 64 # 2 ## LET (R5) := #ALIVE jmp ll$13 ;## 65 # 1 ## ELSE ll$8: PRINT MSG2 ;## 66 # 1 ## PRINT MSG2 ll$13: ;## 67 # 1 ## FI READLN ROW,COL ;## 68 # 0 ## READLN ROW,COL jmp ll$3 ;## 69 # 0 ## END; while ll$4: rts pc ;## 70 # 0 ## RETURN NUL=0 ;## 72 # 0 ## NUL=0 ESC=27.+128. ;## 73 # 0 ## ESC=27.+128. ORAY: .BYTE ESC,'Y,0,0 ;## 75 # 0 ## .BYTE ESC,'Y,0,0 .BLKB 10. ;## 76 # 0 ## .BLKB 10. ; PRINTAT: ;## 77 # 0 ## PROCEDURE PRINTAT ;let r0 := (r0) ;let r1 := (r1) cmp R0,#80. ;## 80 # 0 ## IF R0 > #80. THEN bGT ll$15 jmp ll$14 ll$15: mov #80.,R0 ;## 81 # 1 ## LET R0 := #80. jmp ll$16 ;## 82 # 0 ## ELSE ll$14: cmp R0,#0 ;## 83 # 1 ## IF R0 < #0 THEN bLT ll$18 jmp ll$17 ll$18: clr R0 ;## 84 # 2 ## LET R0 := #0 ll$17: ;## 85 # 1 ## FI ll$16: ;## 86 # 0 ## FI cmp R1,#24. ;## 87 # 0 ## IF R1 > #24. THEN bGT ll$20 jmp ll$19 ll$20: mov #24.,R1 ;## 88 # 1 ## LET R1 := #24. jmp ll$21 ;## 89 # 0 ## ELSE ll$19: cmp R1,#0 ;## 90 # 1 ## IF R1 < #0 THEN bLT ll$23 jmp ll$22 ll$23: clr R1 ;## 91 # 2 ## LET R1 := #0 ll$22: ;## 92 # 1 ## FI ll$21: ;## 93 # 0 ## FI add #32.,R0 ;## 94 # 0 ## LET R0 := R0 + #32. add #32.,R1 ;## 95 # 0 ## LET R1 := R1 + #32. movb R0,ORAY+2 ;## 96 # 0 ## LETB ORAY+2 := R0 movb R1,ORAY+3 ;## 97 # 0 ## LETB ORAY+3 := R1 mov #ORAY+4,R0 ;## 98 # 0 ## LET R0 := #ORAY+4 ll$24: ;## 99 # 0 ## REPEAT movb (R2)+,(R0)+ ;## 100 # 1 ## LETB (R0)+ := (R2)+ cmpb (R2),# ;## 101 # 0 ## UNTILB (R2) IS # beq ll$27 jmp ll$26 ll$27: br ll$25 ll$26: jmp ll$24 ll$25: PRINT ORAY ;## 102 # 0 ## PRINT ORAY rts pc ;## 103 # 0 ## RETURN ;****** the mainline ****** MSG3:.ASCIZ/HOW MANY GENERATIONS?/ MSG4:.ASCIZ/GENERATION/ .EVEN ;## 109 # 0 ## .EVEN SUM: .BLKW 1 ;## 110 # 0 ## .BLKW 1 J: .BLKW 1 ;## 111 # 0 ## .BLKW 1 K: .BLKW 1 ;## 112 # 0 ## .BLKW 1 RM1: .BLKW 1 ;## 113 # 0 ## .BLKW 1 RP1: .BLKW 1 ;## 114 # 0 ## .BLKW 1 CM1: .BLKW 1 ;## 115 # 0 ## .BLKW 1 CP1: .BLKW 1 ;## 116 # 0 ## .BLKW 1 N: .BLKW 1 ;## 117 # 0 ## .BLKW 1 MAXNOGEN: .BLKW 1 ;## 118 # 0 ## .BLKW 1 BEGIN: jsr pc,INIT ;## 121 # 0 ## CALL INIT PRINT MSG3 ;## 122 # 0 ## PRINT MSG3 READLN MAXNOGEN ;## 123 # 0 ## READLN MAXNOGEN mov #1,N ;## 124 # 0 ## LET N := #1 ll$28: ;## 125 # 0 ## WHILE N < MAXNOGEN DO cmp N,MAXNOGEN bLT ll$31 jmp ll$30 ll$30: jmp ll$29 ll$31: mov #0,r0 ;## 126 # 1 ## CALL PRINTAT < #0, #0,MSG1 > mov #0,r1 mov MSG1 ,r2 jsr pc,PRINTAT WRITELN N ;## 127 # 1 ## WRITELN N mov #2,ROW ;## 128 # 1 ## FOR ROW := #2 TO #ROWMAX-1 ll$32: mov #2,COL ;## 129 # 2 ## FOR COL := #2 TO #COLMAX-1 ll$34: clr SUM ;## 130 # 3 ## LET SUM := #0 mov ROW,RM1 ;## 131 # 3 ## LET RM1 := ROW - #1 dec RM1 mov ROW,RP1 ;## 132 # 3 ## LET RP1 := ROW + #1 inc RP1 mov COL,CM1 ;## 133 # 3 ## LET CM1 := COL - #1 dec CM1 mov COL,CP1 ;## 134 # 3 ## LET CP1 := COL + #1 inc CP1 mov RM1,J ;## 136 # 3 ## FOR J := RM1 TO RP1 ll$36: mov CM1,K ;## 137 # 4 ## FOR K := CM1 TO CP1 ll$38: jsr R5,SUBSCRIPT ;## 139 # 5 ## CALL SUBSCRIPT WITH R5 ( J,K ) .word J,K cmp (R5),#ALIVE ;## 140 # 5 ## IF (R5) IS #ALIVE THEN beq ll$41 jmp ll$40 ll$41: inc SUM ;## 141 # 6 ## LET SUM := SUM + #1 ll$40: ;## 142 # 5 ## FI inc K ;## 143 # 4 ## END; for k cmp K,CP1 ble .+4 br .+6 jmp ll$38 ll$39: inc J ;## 144 # 3 ## END; for j cmp J,RP1 ble .+4 br .+6 jmp ll$36 ll$37: jsr R5,SUBSCRIPT ;## 146 # 3 ## CALL SUBSCRIPT WITH R5 (ROW,COL) .word ROW,COL cmp (R5),#DEAD ;## 147 # 3 ## IF (R5) IS #DEAD THEN beq ll$43 jmp ll$42 ll$43: mov #ll$44,-(SP) ;## 148 # 4 ## CASE SUM OF mov SUM,ll$45 asl ll$45 asl ll$45 add #ll$46,ll$45 137 ;jmp @# ll$45:0 ll$46: jmp MD ;## 149 # 5 ## MD,MD,MD jmp MD jmp MD jmp MA ;## 150 # 4 ## MA jmp MD ;## 151 # 4 ## MD,MD,MD,MD,MD jmp MD jmp MD jmp MD jmp MD ll$44: ;## 152 # 4 ## END; case jmp ll$47 ;## 153 # 3 ## ELSE ll$42: dec SUM ;## 154 # 4 ## LET SUM := SUM - #1 mov #ll$48,-(SP) ;## 155 # 4 ## CASE SUM OF mov SUM,ll$49 asl ll$49 asl ll$49 add #ll$50,ll$49 137 ;jmp @# ll$49:0 ll$50: jmp MD1 ;## 156 # 5 ## MD1,MD1,MA1,MA1 jmp MD1 jmp MA1 jmp MA1 jmp MD1 ;## 157 # 4 ## MD1,MD1,MD1,MD1,MD1 jmp MD1 jmp MD1 jmp MD1 jmp MD1 ll$48: ;## 158 # 4 ## END; case of sum-1 ll$47: ;## 159 # 3 ## FI inc COL ;## 160 # 2 ## END; for row cmp COL,#COLMAX-1 ble .+4 br .+6 jmp ll$34 ll$35: inc ROW ;## 161 # 1 ## END; for col cmp ROW,#ROWMAX-1 ble .+4 br .+6 jmp ll$32 ll$33: jsr pc,COPYMATRIX ;## 162 # 1 ## CALL COPYMATRIX inc N ;## 163 # 1 ## LET N := N + #1 jmp ll$28 ;## 164 # 0 ## END; while n < maxnogen ll$29: .EXIT ;## 165 # 0 ## .EXIT COPYMATRIX: ;## 166 # 0 ## PROCEDURE COPYMATRIX clr R0 ;## 167 # 0 ## LET R0 := #0 mov #ROWMAX*COLMAX,R1 ;## 168 # 0 ## LET R1 := #ROWMAX*COLMAX ll$51: ;## 169 # 0 ## THRU R1 DO mov NEXT(R0),LIFE(R0) ;## 170 # 1 ## LET LIFE(R0) := NEXT(R0) add #2,R0 ;## 171 # 1 ## LET R0 := R0 + #2 sob R1,ll$51 ;## 172 # 0 ## END ll$52: rts pc ;## 173 # 0 ## RETURN LINE: .BYTE ESC,'0,'P,'*,ESC,'0,'@,0 ;## 174 # 0 ## .BYTE ESC,'0,'P,'*,ESC,'0,'@,0 MD: ;## 175 # 0 ## PROCEDURE MD sub #LIFE,R5 ;## 176 # 0 ## LET R5 := R5 - #LIFE + #NEXT add #NEXT,R5 mov #DEAD,(R5) ;## 177 # 0 ## LET (R5) := #DEAD rts pc ;## 178 # 0 ## RETURN MA: ;## 179 # 0 ## PROCEDURE MA sub #LIFE,R5 ;## 180 # 0 ## LET R5 := R5 - #LIFE + #NEXT add #NEXT,R5 mov #ALIVE,(R5) ;## 181 # 0 ## LET (R5) := #ALIVE mov ROW,TP ;## 182 # 0 ## LET TP := ROW L.SHIFT 1 .rept 1 asl TP .endr mov TP,r0 ;## 183 # 0 ## CALL PRINTAT mov COL,r1 mov LINE,r2 jsr pc,PRINTAT rts pc ;## 184 # 0 ## RETURN SPACE:.ASCIZ / / CRITTER:.ASCIZ /*/ .EVEN ;## 187 # 0 ## .EVEN TP: .BLKW 1 ;## 188 # 0 ## .BLKW 1 MD1: ;## 189 # 0 ## PROCEDURE MD1 sub #LIFE,R5 ;## 190 # 0 ## LET R5 := R5 - #LIFE + #NEXT add #NEXT,R5 mov #DEAD,(R5) ;## 191 # 0 ## LET (R5) := #DEAD mov ROW,TP ;## 192 # 0 ## LET TP := ROW L.SHIFT 1 .rept 1 asl TP .endr mov TP,r0 ;## 193 # 0 ## CALL PRINTAT mov COL,r1 mov SPACE,r2 jsr pc,PRINTAT rts pc ;## 194 # 0 ## RETURN MA1: ;## 195 # 0 ## PROCEDURE MA1 sub #LIFE,R5 ;## 196 # 0 ## LET R5 := R5 - #LIFE + #NEXT add #NEXT,R5 mov #ALIVE,(R5) ;## 197 # 0 ## LET (R5) := #ALIVE mov ROW,TP ;## 198 # 0 ## LET TP := ROW L.SHIFT 1 .rept 1 asl TP .endr mov TP,r0 ;## 199 # 0 ## CALL PRINTAT mov COL,r1 mov CRITTER,r2 jsr pc,PRINTAT rts pc ;## 200 # 0 ## RETURN ;## 201 # 0 ## .END BEGIN ;SUPERMAC error(s) detected: 0 ; 1 0 11 2 53 4 10 0 0 7 ; 278 0 7 170 22 1 1 26 162 52 ; 0 42 0 4 0 170 0 0 485 5 ; 2 0 9 2 41 20 1 9 178 170 ; 28 8 2 1 14 2 10 0 0 0 ; 0 0 0 0 0 0 0 0 0 0 ; 0 0 0 0 0 0 0 0 0 0 ; 0 0 0 0 0 0 .END BEGIN