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

wirehaze git hosting

f1545209a35feff333e53ab7ab1eadf0af8b45bf
[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 %define WAIT_DELAY 0x02 ; 0.131072 seconds
14
15 %define GRID ORG + 512 ; current cell grid (80 * 25 bytes)
16 %define NEXT_GRID GRID + COLS * ROWS ; next cell grid (80 * 25 bytes)
17 %define XSS NEXT_GRID + COLS * ROWS ; xs() state
18
19 ; entry point -----------------------------------------------------------------
20
21 ; initialize segment registers
22 lds ax, [farptr.zero]
23 les ax, [farptr.zero]
24 lss ax, [farptr.zero]
25
26 ; set stack pointers
27 mov bp, ORG
28 mov sp, bp
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 call delay
50
51 jmp setup
52
53 ; functions -------------------------------------------------------------------
54
55 ; delay() - suspend program execution temporarily -----------------------------
56
57 ; clobbers ah, cx, dx
58
59 delay:
60
61 mov cx, WAIT_DELAY ; cx:dx = interval in microseconds
62 mov dx, 0
63
64 mov ah, 0x86
65 int 0x15 ; wait
66
67 ret
68
69 ; xs() - xorshift pseudorandom number generator -------------------------------
70
71 ; output:
72 ; [XSS] = updated state
73
74 ; clobbers bx, dx
75
76 xs:
77
78 mov bx, [XSS]
79 mov dx, bx
80
81 shl dx, 1 ; dx = xss << 1
82 xor bx, dx ; bx = xss ^ (xss << 1)
83 mov dx, bx
84
85 shr dx, 3 ; dx = xss' >> 3
86 xor bx, dx ; bx = xss' ^ (xss' >> 3)
87 mov dx, bx
88
89 shl dx, 10 ; dx = xss'' << 10
90 xor bx, dx ; bx = xss'' ^ (xss'' << 10)
91 mov [XSS], bx
92
93 ret
94
95 ; init_grid() - initialize GRID cells with random values ----------------------
96
97 ; (*) expects es = 0.
98
99 ; clobbers al, bx, cx, dx, di
100
101 init_grid:
102
103 mov di, GRID ; es:di -> GRID
104 mov cx, COLS * ROWS ; for each cell
105
106 .write_cell: ; do {
107 call xs ; [XSS] = rand
108 mov al, DEAD ; al = DEAD (likely)
109
110 test word [XSS], 0b11
111
112 jnz .nz ; if ([XSS] % 4 == 0)
113 mov al, ALIVE ; al = ALIVE
114
115 .nz:
116 stosb ; [es:(di++)] = al
117
118 loop .write_cell ; } while (--cx)
119
120 ret
121
122 ; print_grid() - print GRID cells to screen -----------------------------------
123
124 ; (*) this function expects ds = 0 when called and sets es = 0 before
125 ; returning. this is simpler because in the rest of the program we want the
126 ; segment registers to be zeroed anyway.
127
128 ; clobbers ax, cx, di, si
129
130 print_grid:
131
132 les di, [farptr.vga_start] ; es:di -> VGA
133 mov si, GRID ; ds:si -> GRID
134
135 mov ah, PRINT_COLOR ; ah = color attribute
136
137 mov cx, COLS * ROWS ; for each cell
138
139 .print_cell: ; do {
140
141 lodsb ; al = [ds:(si++)]
142 stosw ; [es:di] = ax ; di += 2
143
144 loop .print_cell ; } while (--cx)
145
146 mov es, cx ; es = 0
147 ret
148
149 ; halt() - stop program execution ---------------------------------------------
150
151 halt:
152
153 cli ; disable interrupts
154 hlt
155 jmp halt
156
157 ; data ------------------------------------------------------------------------
158
159 farptr: ; offset, segment
160 .zero:
161 dw 0 ; take advantage of next dw 0
162
163 .vga_start:
164 dw 0, VGA >> 4
165
166 times 510 - ($ - $$) db 0 ; fill remaining bytes with zeroes
167 dw 0xaa55 ; mbr magic byte