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

wirehaze git hosting

0e114d0a7a93aebfb29ace065599d1129d3fd84e
[lifeboot.git] / lifeboot.asm
1 bits 16
2 org 0x7c00
3
4 ; =============================================================================
5
6 ; settings --------------------------------------------------------------------
7
8 %define DEAD ' ' ; char to represent a dead cell
9 %define ALIVE '#' ; char to represent an alive cell
10 %define PRINT_COLOR 0x07 ; grey on black
11 %define WAIT_DELAY 0x02 ; 0.131072 seconds
12
13 ; constants -------------------------------------------------------------------
14
15 %define COLS 80
16 %define ROWS 25
17 %define VGAPGSZ (COLS * ROWS * 2)
18
19 ; memory layout ---------------------------------------------------------------
20
21 %define ORG 0x7c00
22 %define VGA 0xb8000
23 %define DAT ORG + 512
24
25 ; static variables ------------------------------------------------------------
26
27 %define xss DAT ; xs() state (word)
28 %define currvgapg DAT + 2 ; current vga page near pointer (word)
29
30 ; =============================================================================
31
32 ; entry point -----------------------------------------------------------------
33
34 ; initialize segment registers
35 mov ax, VGA >> 4
36 mov ds, ax
37 mov es, ax
38
39 xor ax, ax
40 mov ss, ax
41
42 ; set stack pointers
43 mov bp, ORG
44 mov sp, bp
45
46 ; clear direction flag
47 cld
48
49 ; disable cursor
50 mov ch, 0x3f ; cursor start and options
51 mov ah, 0x01 ; set text-mode cursor shape
52 int 0x10 ; video services
53
54 ; initialize xss
55 mov ah, 0x00 ; get
56 int 0x1a ; system time
57 mov [xss], dx ; cx:dx = number of clock ticks since midnight
58
59 ; initialize currvgapg
60 mov word [currvgapg], VGAPGSZ
61
62 ; setup -----------------------------------------------------------------------
63
64 setup:
65
66 call init_grid
67 call flip_vga_page
68 call delay
69
70 jmp setup
71
72 ; =============================================================================
73
74 ; functions -------------------------------------------------------------------
75
76 ; delay() - suspend program execution temporarily -----------------------------
77
78 ; clobbers ah, cx, dx
79
80 delay:
81
82 mov cx, WAIT_DELAY ; cx:dx = interval in microseconds
83 mov dx, 0
84
85 mov ah, 0x86
86 int 0x15 ; wait
87
88 ret
89
90 ; vsync_wait() - wait for display to enter the next VBlank cycle --------------
91
92 ; clobbers ax, dx
93
94 vsync_wait:
95
96 mov dx, 0x3da ; input status #1 register
97
98 .wait_on:
99 in al, dx
100 test al, 0x08 ; vertical retrace bit
101 jnz .wait_on
102
103 .wait_off:
104 in al, dx
105 test al, 0x08
106 jz .wait_off
107
108 ret
109
110 ; xs() - xorshift pseudorandom number generator -------------------------------
111
112 ; output:
113 ; [xss] = updated state
114
115 ; clobbers bx, dx
116
117 xs:
118
119 mov bx, [xss]
120 mov dx, bx
121
122 shl dx, 1 ; dx = xss << 1
123 xor bx, dx ; bx = xss ^ (xss << 1)
124 mov dx, bx
125
126 shr dx, 3 ; dx = xss' >> 3
127 xor bx, dx ; bx = xss' ^ (xss' >> 3)
128 mov dx, bx
129
130 shl dx, 10 ; dx = xss'' << 10
131 xor bx, dx ; bx = xss'' ^ (xss'' << 10)
132 mov [xss], bx
133
134 ret
135
136 ; init_grid() - initialize grid cells randomly --------------------------------
137
138 ; clobbers ax, bx, cx, dx, di
139
140 init_grid:
141
142 mov ah, PRINT_COLOR ; ah = color attribute
143 mov di, [currvgapg] ; es:di -> grid start
144 mov cx, COLS * ROWS ; for each cell
145
146 .write_cell: ; do {
147 call xs ; [xss] = rand
148 mov al, DEAD ; al = DEAD (likely)
149
150 test word [xss], 0b11
151
152 jnz .nz ; if ([xss] % 4 == 0)
153 mov al, ALIVE ; al = ALIVE
154
155 .nz:
156 stosw ; [es:di] = ax ; di += 2
157
158 loop .write_cell ; } while (--cx)
159
160 ret
161
162 ; flip_vga_page() - flip active display page ----------------------------------
163
164 ; clobbers ax, dx
165
166 flip_vga_page:
167
168 call vsync_wait
169
170 xor word [currvgapg], VGAPGSZ ; flip currvgapg
171 setnz al ; al = !(currvgapg == 0)
172
173 mov ah, 0x05 ; select active display page
174 int 0x10 ; video services
175
176 ret
177
178 ; halt() - stop program execution ---------------------------------------------
179
180 halt:
181
182 cli ; disable interrupts
183 hlt
184 jmp halt
185
186 ; =============================================================================
187
188 times 510 - ($ - $$) db 0 ; fill remaining bytes with zeroes
189 dw 0xaa55 ; mbr magic byte