]> wirehaze git hosting - lifeboot.git/blob - lifeboot.asm

wirehaze git hosting

07d9c5a56e900f5b895e521b4e3a763bb6b782ae
[lifeboot.git] / lifeboot.asm
1 bits 16
2 org 0x7c00
3
4 %define ORG 0x7c00
5 %define VGA 0xb8000
6
7 %define COLS 80
8 %define ROWS 25
9
10 %define DEAD ' ' ; char to represent a dead cell
11 %define ALIVE '#' ; char to represent an alive cell
12 %define PRINT_COLOR 0x07 ; grey on black
13
14 %define GRID ORG + 512 ; current cell grid (80 * 25 bytes)
15 %define NEXT_GRID GRID + COLS * ROWS ; next cell grid (80 * 25 bytes)
16 %define XSS NEXT_GRID + COLS * ROWS ; xs() state
17
18 ; entry point -----------------------------------------------------------------
19
20 ; initialize segment registers
21 xor ax, ax
22 mov ds, ax
23 mov es, ax
24 mov ss, ax
25
26 ; set stack pointers
27 mov sp, ORG
28 mov bp, ORG
29
30 ; clear direction flag
31 cld
32
33 ; disable cursor
34 mov ch, 0x3f
35 mov ah, 0x01
36 int 0x10
37
38 ; setup -----------------------------------------------------------------------
39
40 setup:
41
42 ; initialize xss
43 mov ah, 0x00 ; get
44 int 0x1a ; system time
45 mov [XSS], dx ; cx:dx = number of clock ticks since midnight
46
47 ; initialize grid
48 mov di, GRID ; es:di -> GRID
49 mov cx, COLS * ROWS ; for each cell
50
51 .initgrid: ; do {
52 call xs ; [XSS] = rand
53 mov al, DEAD ; al = DEAD (likely)
54
55 test [XSS], 0b11
56
57 jnz .initgrid_nz ; if ([XSS] % 4 == 0)
58 mov al, ALIVE ; al = ALIVE
59
60 .initgrid_nz:
61 stosb ; [es:(di++)] = al
62
63 loop .initgrid ; } while (--cx)
64
65 call print_grid
66
67 jmp halt
68
69 ; functions -------------------------------------------------------------------
70
71 ; xs() - xorshift pseudorandom number generator -------------------------------
72
73 ; output:
74 ; [XSS] = updated state
75
76 ; clobbers bx, dx
77
78 xs:
79
80 mov bx, [XSS]
81 mov dx, bx
82
83 shl dx, 1 ; dx = xss << 1
84 xor bx, dx ; bx = xss ^ (xss << 1)
85 mov dx, bx
86
87 shr dx, 3 ; dx = xss' >> 3
88 xor bx, dx ; bx = xss' ^ (xss' >> 3)
89 mov dx, bx
90
91 shl dx, 10 ; dx = xss'' << 10
92 xor bx, dx ; bx = xss'' ^ (xss'' << 10)
93 mov [XSS], bx
94
95 ret
96
97 ; print_grid() - print GRID cells to screen -----------------------------------
98
99 ; (*) this function expects ds = 0 when called and sets es = 0 before
100 ; returning. this is simpler because in the rest of the program we want the
101 ; segment registers to be zeroed anyway.
102
103 ; clobbers ax, cx, di, si
104
105 print_grid:
106
107 mov ax, VGA >> 4
108 xor di, di
109
110 mov es, ax ; es:di -> VGA
111 mov si, GRID ; ds:si -> GRID
112
113 mov ah, PRINT_COLOR ; ah = color attribute
114
115 mov cx, COLS * ROWS ; for each cell
116
117 .print_cell: ; do {
118
119 lodsb ; al = [ds:(si++)]
120 stosw ; [es:di] = ax ; di += 2
121
122 loop .print_cell ; } while (--cx)
123
124 mov es, cx ; es = 0
125 ret
126
127 ; halt() - stop program execution ---------------------------------------------
128
129 halt:
130
131 cli ; disable interrupts
132 hlt
133 jmp halt
134
135 ; -----------------------------------------------------------------------------
136
137 times 510 - ($ - $$) db 0 ; fill remaining bytes with zeroes
138 dw 0xaa55 ; mbr magic byte