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

wirehaze git hosting

f438c6069c9c25b110a8f2dc2f4b660c15dec224
[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 ; initialize xss
39 mov ah, 0x00 ; get
40 int 0x1a ; system time
41 mov [XSS], dx ; cx:dx = number of clock ticks since midnight
42
43 ; setup -----------------------------------------------------------------------
44
45 setup:
46
47 call init_grid
48 call print_grid
49
50 jmp halt
51
52 ; functions -------------------------------------------------------------------
53
54 ; xs() - xorshift pseudorandom number generator -------------------------------
55
56 ; output:
57 ; [XSS] = updated state
58
59 ; clobbers bx, dx
60
61 xs:
62
63 mov bx, [XSS]
64 mov dx, bx
65
66 shl dx, 1 ; dx = xss << 1
67 xor bx, dx ; bx = xss ^ (xss << 1)
68 mov dx, bx
69
70 shr dx, 3 ; dx = xss' >> 3
71 xor bx, dx ; bx = xss' ^ (xss' >> 3)
72 mov dx, bx
73
74 shl dx, 10 ; dx = xss'' << 10
75 xor bx, dx ; bx = xss'' ^ (xss'' << 10)
76 mov [XSS], bx
77
78 ret
79
80 ; init_grid() - initialize GRID cells with random values ----------------------
81
82 ; (*) expects es = 0.
83
84 ; clobbers ax, bx, cx, dx, di
85
86 init_grid:
87
88 mov di, GRID ; es:di -> GRID
89 mov cx, COLS * ROWS ; for each cell
90
91 .write_cell: ; do {
92 call xs ; [XSS] = rand
93 mov al, DEAD ; al = DEAD (likely)
94
95 test word [XSS], 0b11
96
97 jnz .nz ; if ([XSS] % 4 == 0)
98 mov al, ALIVE ; al = ALIVE
99
100 .nz:
101 stosb ; [es:(di++)] = al
102
103 loop .write_cell ; } while (--cx)
104
105 ret
106
107 ; print_grid() - print GRID cells to screen -----------------------------------
108
109 ; (*) this function expects ds = 0 when called and sets es = 0 before
110 ; returning. this is simpler because in the rest of the program we want the
111 ; segment registers to be zeroed anyway.
112
113 ; clobbers ax, cx, di, si
114
115 print_grid:
116
117 mov ax, VGA >> 4
118 xor di, di
119
120 mov es, ax ; es:di -> VGA
121 mov si, GRID ; ds:si -> GRID
122
123 mov ah, PRINT_COLOR ; ah = color attribute
124
125 mov cx, COLS * ROWS ; for each cell
126
127 .print_cell: ; do {
128
129 lodsb ; al = [ds:(si++)]
130 stosw ; [es:di] = ax ; di += 2
131
132 loop .print_cell ; } while (--cx)
133
134 mov es, cx ; es = 0
135 ret
136
137 ; halt() - stop program execution ---------------------------------------------
138
139 halt:
140
141 cli ; disable interrupts
142 hlt
143 jmp halt
144
145 ; -----------------------------------------------------------------------------
146
147 times 510 - ($ - $$) db 0 ; fill remaining bytes with zeroes
148 dw 0xaa55 ; mbr magic byte