+; initialize xss
+mov ah, 0x00 ; get
+int 0x1a ; system time
+mov [xss], dx ; cx:dx = number of clock ticks since midnight
+
+; initialize currvgapg
+mov word [currvgapg], VGAPGSZ
+
+; start simulation from random state ------------------------------------------
+
+start:
+
+call init_grid
+
+; apply game of life's rules to determine the next state ----------------------
+
+next_state:
+
+call flip_vga_page ; display current state
+call delay ; sleep a little
+
+call write_next_vga_page ; write the next state to the hidden page
+
+jmp next_state
+
+; =============================================================================
+
+; functions -------------------------------------------------------------------
+
+; delay() - suspend program execution temporarily -----------------------------
+
+; clobbers ah, cx, dx
+
+delay:
+
+mov cx, WAIT_DELAY ; cx:dx = interval in microseconds
+mov dx, 0
+
+mov ah, 0x86
+int 0x15 ; wait
+
+ret
+
+; vsync_wait() - wait for display to enter the next VBlank cycle --------------
+
+; clobbers ax, dx
+
+vsync_wait:
+
+mov dx, 0x3da ; input status #1 register
+
+.wait_on:
+ in al, dx
+ test al, 0x08 ; vertical retrace bit
+ jnz .wait_on
+
+.wait_off:
+ in al, dx
+ test al, 0x08
+ jz .wait_off
+
+ret
+
+; xs() - xorshift pseudorandom number generator -------------------------------
+
+; output:
+; [xss] = updated state
+
+; clobbers bx, dx
+
+xs:
+
+mov bx, [xss]
+mov dx, bx
+
+shl dx, 1 ; dx = xss << 1
+xor bx, dx ; bx = xss ^ (xss << 1)
+mov dx, bx
+
+shr dx, 3 ; dx = xss' >> 3
+xor bx, dx ; bx = xss' ^ (xss' >> 3)
+mov dx, bx
+
+shl dx, 10 ; dx = xss'' << 10
+xor bx, dx ; bx = xss'' ^ (xss'' << 10)
+mov [xss], bx
+
+ret
+
+; init_grid() - initialize grid cells randomly --------------------------------
+
+; clobbers ax, bx, cx, dx, di