bits 16
org 0x7c00
-%define ORG 0x7c00 ; where we are loaded initially
+%define ORG 0x7c00
+%define VGA 0xb8000
-%define VGA_SEG 0xb800 ; video memory starts at 0xb8000
-%define VGA_COL 80
-%define VGA_ROW 25
-%define VGA_LENW VGA_COL * VGA_ROW
+%define COLS 80
+%define ROWS 25
-%define FILL_CHAR 0xfa ; middle dot
-%define FILL_COLOR 0x04 ; red on black
-%define PRINT_COLOR 0x07 ; grey on black
+%define DEAD ' ' ; char to represent a dead cell
+%define ALIVE '#' ; char to represent an alive cell
+%define PRINT_COLOR 0x07 ; grey on black
+
+%define GRID ORG + 512 ; current cell grid (80 * 25 bytes)
+%define NEXT_GRID GRID + COLS * ROWS ; next cell grid (80 * 25 bytes)
+%define XSS NEXT_GRID + COLS * ROWS ; xs() state
; entry point -----------------------------------------------------------------
int 0x10
; clear video memory
-mov cx, VGA_LENW
-mov ax, VGA_SEG
+mov cx, COLS * ROWS
+mov ax, VGA >> 4
mov es, ax
xor di, di
-mov ax, (FILL_COLOR << 8) | FILL_CHAR
+mov ax, (PRINT_COLOR << 8) | DEAD
rep stosw ; fill cx words at es:di with ax
+; setup -----------------------------------------------------------------------
+
+setup:
+
+; initialize xss
+mov ah, 0x00 ; get
+int 0x1a ; system time
+mov [XSS], dx ; cx:dx = number of clock ticks since midnight
+
+; initialize grid
+mov di, GRID
+mov cx, COLS * ROWS
+
+.initgrid: ; do {
+ call xs ; ax = rand
+ mov dl, DEAD ; dl = DEAD (likely)
+
+ test ax, 0b11
+
+ jnz .initgrid_nz ; if (ax % 4 == 0)
+ mov dl, ALIVE ; dl = ALIVE
+
+.initgrid_nz:
+ mov [di + cx], dl ; grid[cx] = dl
+
+ loop .initgrid ; } while (--cx)
+
+jmp halt
+
+; functions -------------------------------------------------------------------
+
+; xs() - xorshift pseudorandom number generator -------------------------------
+
+; output:
+; ax = updated state ([XSS])
+
+; clobbers ax, dx
+
+xs:
+
+mov ax, [XSS]
+mov dx, ax
+
+shl dx, 1 ; dx = xss << 1
+xor ax, dx ; ax = xss ^ (xss << 1)
+mov dx, ax
+
+shr dx, 3 ; dx = xss' >> 3
+xor ax, dx ; ax = xss' ^ (xss' >> 3)
+mov dx, ax
+
+shl dx, 10 ; dx = xss'' << 10
+xor ax, dx ; ax = xss'' ^ (xss'' << 10)
+mov [XSS], ax
+
+ret
+
; errors ----------------------------------------------------------------------
hello: