;;; -*-MIDAS-*- ;;; ;;; Copyright (C) 2002 Donald Fisk ;;; ;;; This program is free software; you can redistribute it and/or modify ;;; it under the terms of the GNU General Public License as published by ;;; the Free Software Foundation; either version 2 of the License, or ;;; (at your option) any later version. ;;; ;;; This program is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program; if not, write to the Free Software ;;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ;;; USA ;;; ;;; Life was conceived by Conway and implemented at AI Labs by Gosper. ;;; in TECO. This version was written partly to prove that ITS isn't dead -- ;;; after all it can't be dead if it has life. ;;; ;;; After assembling, you need to run it with a random number seed on ;;; the command line, e.g. ;;; ;;; :life 123456123456 ;;; ;;; You will need KN:KSC;MACROS > ;;; If you don't have this, contact me and I'll mail you a copy. title life i=1 j=2 index=3 above=4 middle=5 below=6 after=7 count=10 x=11 y=12 z=13 ismid=14 bufptr=15 p=17 chttyo==1 nrows==36. ncols==36. pdllen==100. ;Length of push down list (stack). pdl: block pdllen ;Storage for stack. old: block nrows ;Old generation. new: block nrows ;New generation buffer: block 100. ;To hold single line of output. jclbuf: block 100. ;To hold job command line. srand: 0 bitlft: <" > <"[> bitrgt: <" > <"]> nbrs: <0> ;Number of neighbours. <1> <1> <2> <1> <2> <2> <3> .insrt ksc;macros start: move p,[-pdllen,,pdl-1] ;Initialize stack pointer. ;;Open output to TTY in display mode (%TJDIS bit set). syscal open,[[%TJDIS+.uao,,chttyo] ? [sixbit/tty/] ? 0 ? 0] .lose %lsfil .break 12,[..RJCL,,jclbuf] move bufptr,[440700,,jclbuf] ;Point buffer at job command line. movei x,0 ;Initialize random number seed. movei y,7 ;Mask to get bottom 3 bits of digits. jcllp: ildb z,bufptr cain z,^M ;Reached the end of JCL (CR)? jrst init ; Yes? -- initialize old world. ;; .iot chttyo,z rot x,3 ;Shift left by three bits (x8). and z,y ;Get significant part of digit. add x,z ;Add it. jrst jcllp ;; Start by initializing old. init: movem x,srand ;Save random number seed. movei index,0 initlp: cain index,nrows jrst prrows pushj p,random ;Value returned in y. movem y,old(index) addi index,1 jrst initlp prrows: .iot chttyo,[^P] .iot chttyo,["T] ;Move cursor to top left hand corner of TTY. ;; Print the rows. movei index,0 prrwlp: cain index,nrows jrst nxtgen move x,old(index) pushj p,prtrow addi index,1 jrst prrwlp ;; Calculate the next generation nxtgen: movei index,0 nxtrow: cail index,nrows ;if index >= nrows goto endrow jrst endrow ;; Retrieve above, middle and below from old array. move i,index cain i,0 movei i,nrows subi i,1 move above,old(i) ;above <- old((index - 1) % nrows) move i,index move middle,old(i) ;middle <- old(index) addi i,1 cain i,nrows movei i,0 move below,old(i) ;below <- old((index + 1) % nrows) ;; Iterate through the columns in a single row. move after,middle movei j,0 nxtcol: cail j,ncols ;if j >= ncols goto endcol jrst endcol ;; Count neighbours. movei count, 0 ;Store running total of neighbours in count. movei y,7 ;Mask for rightmost three bits. move x,above and x,y add count,nbrs(x) move x,below and x,y add count,nbrs(x) movei y,5 ;Mask, but this time zero the bit itself. move x,middle and x,y add count,nbrs(x) ;; Number of neighbours is now in count. ;; See if the point lives or dies. movei y,2 caie count,3 ;if count = 3 then jrst cntne2 ior after,y ; The point comes to life. jrst cnteq2 cntne2: caie count,2 ;else if count != 2 then andcm after,y ; The point dies. cnteq2: ;else (count = 2) ; The point stays as it is. ;fi addi j,1 ;Increment column rot above,-1 ;Rotate to next column in above, rot middle,-1 ; middle, below and after. rot below,-1 rot after,-1 jrst nxtcol endcol: movem after,new(index) ;Save back in new array. addi index,1 jrst nxtrow endrow: ;; Copy the new rows into old. movei i,0 cpynxt: cain i,nrows jrst prrows ;Life: The Next Generation. Print rows first. move x,new(i) movem x,old(i) addi i,1 jrst cpynxt random: hlr x,srand ;Put LHS of srand in RHS of x. imuli x,<352421> ;a=352421 addi x,<1> ;c=1 idiv x,[000001,,000000];Remainder in y. hrlm y,srand ;Put LHS of y (remainder) in RHS of srand. hrr x,srand imuli x,<352421> ;a=352421 addi x,<1> ;c=1 idiv x,[000001,,000000];Remainder in y. hrrm y,srand ;Put RHS of y (remainder) in RHS of srand. move y,srand ;Put value in y befure returning. popj p, prtrow: ;; Init loop counter move bufptr,[440700,,buffer] movei i,ncols ;; Find the bottommost bit in b. prtlp: move y,x movei z,<000000,,000001> and y,z move z,bitlft(y) idpb z,bufptr move z,bitrgt(y) idpb z,bufptr rot x,-1 ;Get next bit. subi i,1 jumpg i,prtlp movei z,^M ;CR idpb z,bufptr movei z,^J ;LF idpb z,bufptr move bufptr,[440700,,buffer] movei z,ncols*2+2 syscal siot,[movei chttyo ? bufptr ? z] .lose %lsfil popj p, end start