; The classic John Conway game of Life
; Z80 Implementation (and not a very good one) by Phil Brown
; Overcrowded if cells>4
; Lonely if cells<2
; Birth if empty and cells=3
;
; Change random seed to get different initial generations

          org 1000
cellch    equ 'O'
blnkch    equ #32

random    ld hl,(seed)        ; places a "random" value in HL
          push de
          ld d,h
          ld e,h
          add hl,hl
          add hl,hl
          add hl,de
          add hl,hl
          add hl,hl
          add hl,hl
          add hl,de
          ld (seed),hl
          pop de
          ret

display   ld a,#27
          out (1),a           ; print ESC 0 to clear console
          ld a,#0
          out (1),a
          ld hl,cells
          ld c,#16
disp_1    ld b,#16
disp_2    ld a,(hl)
          out (1),a
          inc hl
          djnz disp_2
          ld a,#13
          out (1),a           ; print newline
          dec c
          ld a,c
          cp 0
          jr nz,disp_1
          ret

create    ld de,cells
          ld a,#27
          out (1),a           ; print ESC 0 to clear console
          ld a,0
          out (1),a
          ld c,#16
create_1  ld b,#16
create_2  call random         ; returns "random" value in HL
          ld a,l
          cp #80
          ld a,blnkch
          jr c,outcell        ; L<80
          ld a,cellch
outcell   ld (de),a
          inc de
          djnz create_2
          dec c
          ld a,c
          cp #0
          jr nz,create_1
          ret

copy      ld de,copys
          ld hl,cells
          ld bc,#256
          ldir
          ret

generate  ld de,copys
          ld c,#16
gen_1     ld b,#16
gen_3     push bc
          push de
          ld c,#0             ; count of number of adjacent cells
          ld hl,offsets       ; pointer to table of offsets
          ld b,#8             ; 8 adjacent cells
gen_2     ld a,e
          add a,(hl)
          inc hl
          ld e,a              ; de now contains address of adjacent cell
          ld a,(de)           ; get this adjacent cell
          cp blnkch           ; is it empty?
          jr z,blnk_adj
          inc c               ; increment counter of adjacent cells
blnk_adj  djnz gen_2
          pop de
          ld a,c
          cp #3
          ld a,cellch
          jr z,put_cell
          ld a,(de)
          cp blnkch
          ld a,blnkch
          jr z,put_cell
          ld a,c
          cp #2
          ld a,cellch
          jr z,put_cell
          ld a,blnkch
put_cell  dec d               ; point to cells not copys
          ld (de),a
          inc d               ; point back to copys
          inc de              ; next cell
          pop bc
          djnz gen_3
          dec c
          ld a,c              ; done all 16 rows?
          cp #0
          jr nz,gen_1         ; no, go back and do them then!
          ret
life      call create
next_gen  call display
          call copy
          call generate
          jr next_gen

          org #10*#256        ; needs to be page aligned
cells     defs #256           ; 16 * 16 array of cells
copys     defs #256           ; copy when calculating next generation
offsets   defb #239           ; table for eight relative offsets
          defb #1
          defb #1
          defb #14
          defb #2
          defb #14
          defb #1
          defb #1
seed      defw #56123
