fixed
[bootcard] / bootcard.asm
1 ; ---- boot me! ----
2 ; nasm -f bin -o bootcard.img bootcard.asm
3 ; cat bootcard.img >/dev/<usbstick>
4
5 %define MIDI
6
7         bits 16
8 %ifdef DOS
9         org 100h
10         jmp start
11 %else
12         org 7c00h
13 %endif
14
15 barh    equ 4
16 nbars   equ 11
17 barstart equ 200 - (nbars+1) * barh
18
19 %ifdef DOS
20 nticks  dd 0
21 tmoffs  dd 0
22 musptr  dd 0
23 frame   dd 0
24 fval    dd 0
25 cmap    dd 0
26
27 saved_tintr_offs dw 0
28 saved_tintr_seg dw 0
29 %else
30 nticks  equ 7e00h
31 tmoffs  equ 7e04h
32 musptr  equ 7e08h
33 frame   equ 7e0ch
34 fval    equ 7e10h
35 cmap    equ 7e14h
36 %endif
37
38 %macro setcur 2
39         mov dx, %1 | (%2 << 8)
40         xor bx, bx
41         mov ah, 2
42         int 10h
43 %endmacro
44 %macro spkon 0
45         in al, 61h
46         or al, 3
47         out 61h, al
48 %endmacro
49 %macro spkoff 0
50         in al, 61h
51         and al, 0fch
52         out 61h, al
53 %endmacro
54 %macro stimer 2
55         mov al, (%1 << 6) | 36h
56         out 43h, al
57         mov ax, %2
58         out 40h + %1, al
59         mov al, ah
60         out 40h + %1, al
61 %endmacro
62
63 start:
64 %ifndef DOS
65         xor ax, ax
66         mov ds, ax
67         mov es, ax
68         mov ss, ax
69         mov sp, 7c00h
70
71         cli
72         mov word [32], tintr
73         mov [34], ax
74 %else
75         ; for DOS save the previous interrupt handler to restore at the end
76         xor ax, ax
77         mov es, ax
78         mov ax, [es:32]
79         mov [saved_tintr_offs], ax
80         mov ax, [es:34]
81         mov [saved_tintr_seg], ax
82
83         cli
84         mov ax, ds
85         mov word [es:32], tintr
86         mov [es:34], ax
87 %endif
88
89         mov di, nticks
90         mov cx, 16
91         rep stosw
92
93         stimer 0, 5966
94 %ifdef MIDI
95         call resetmidi
96         mov ax, 0c0h    ; change program on chan 0
97         call sendmidi
98         mov ax, 19      ; church organ
99         call sendmidi
100 %endif
101         mov ax, 13h
102         int 10h
103         push 0a000h
104         pop es
105
106         
107         mov al, 16
108         mov di, barstart * 320
109         mov bx, nbars
110 .drawbars:
111         mov cx, barh * 320
112         rep stosb
113         inc al
114         dec bx
115         jnz .drawbars
116
117         setcur 12, 16
118         mov si, str1
119         call textout
120
121         sti
122
123 mainloop:
124         mov dx, 3dah
125 .invb:  in al, dx
126         and al, 8
127         jnz .invb
128 .novb:  in al, dx
129         and al, 8
130         jz .novb
131
132 drawbg:
133         mov bx, 200
134         xor di, di
135 .fillgrad:
136         mov ax, bx
137         mov ah, al
138         mov cx, 2400 ; 15 lines
139         rep stosw
140         inc bx
141         cmp bx, 208
142         jnz .fillgrad
143
144         ; mountains
145         mov cx, 320
146         mov bp, sp
147 .mnt:   mov [bp - 2], cx
148         fild word [bp - 2]
149         fidiv word [w30]
150         fsincos
151         fiadd word [w5]
152         fimul word [w5]
153         fistp word [bp - 2]
154         fstp st0
155         mov bx, [bp - 2]
156         add bx, 84
157         imul bx, bx, 320
158         add bx, cx
159 .mntcol:
160         mov byte [es:bx], 0
161         add bx, 320
162         cmp bx, 128 * 320
163         jb .mntcol
164
165         dec cx
166         jnz .mnt
167
168         ; upd colormap
169         mov dx, 3c8h
170         mov al, 16
171         out dx, al
172         inc dx
173         mov si, cmap
174         mov cx, 16 * 3
175         rep outsb
176
177 %ifdef DOS
178         in al, 60h
179         dec al
180         jnz mainloop
181
182         mov ax, 3
183         int 10h
184
185         cli
186         xor ax, ax
187         mov es, ax
188         mov ax, [saved_tintr_offs]
189         mov word [es:32], ax
190         mov ax, [saved_tintr_seg]
191         mov [es:34], ax
192         stimer 0, 0xffff
193         sti
194         ret
195 %else
196         jmp mainloop
197 %endif
198
199 textout:
200         mov al, [si]
201         and al, al
202         jz textout_done
203         mov ah, 0eh
204         mov bx, 82
205         int 10h
206         inc si
207         jmp textout
208 textout_done:
209         ret
210
211 %ifdef MIDI
212 note_on:
213         push ax
214         mov ax, 90h     ; note-on command for channel 0
215         call sendmidi
216         pop ax
217         call sendmidi
218         mov ax, 127
219         jmp sendmidi
220
221 all_notes_off:
222         mov ax, 0b0h    ; channel mode message for channel 0...
223         call sendmidi
224         mov ax, 7bh     ; all notes off
225         call sendmidi
226         xor ax, ax
227         jmp sendmidi
228
229 waitmidi:
230         mov dx, 331h
231 .wait:  in al, dx       ; read status port
232         test al, 40h    ; test output-ready bit (0: ready)
233         jnz .wait
234         ret
235
236 sendmidi:
237         push dx
238         push ax
239         call waitmidi
240         pop ax
241         dec dx
242         out dx, al
243         pop dx
244         ret
245
246 resetmidi:
247         call waitmidi
248         mov ax, 0ffh    ; reset command
249         out dx, al
250         call waitmidi
251         mov ax, 3fh     ; enter UART mode
252         out dx, al
253         ret
254 %endif  ; MIDI
255
256 tintr:
257         pusha
258         mov ax, [nticks]
259         inc ax
260         mov [nticks], ax
261
262         mov bx, [musptr]
263 %ifdef MIDI
264         cmp bx, 22*2
265 %else
266         cmp bx, 22*3
267 %endif
268         jnz .skiploop
269         xor bx, bx
270         mov [tmoffs], ax
271 .skiploop:
272         xor cx, cx
273         mov cl, [music + bx]
274         shl cx, 4
275         sub ax, [tmoffs]
276         cmp ax, cx
277         jb .end
278
279 %ifdef MIDI
280         mov al, [music + 1 + bx]
281         xor ah, ah
282         add bx, 2
283 %else
284         mov ax, [music + 1 + bx]
285         add bx, 3
286 %endif
287         mov [musptr], bx
288         test ax, ax
289         jz .off
290
291         mov bx, ax
292 %ifdef MIDI
293         sub bx, 43
294 %else
295         shr bx, 9
296         sub bx, 13
297 %endif
298         imul bx, bx, 3
299         mov byte [cmap + bx], 3fh
300         mov word [cmap + bx + 1], 2f2fh
301
302 %ifdef MIDI
303         push ax
304         call all_notes_off
305         pop ax
306         call note_on
307 %else
308         mov bx, ax
309         stimer 2, bx
310         spkon
311 %endif
312         jmp .end
313
314 .off:
315 %ifdef MIDI
316         call all_notes_off
317 %else
318         spkoff
319 %endif
320
321 .end:   test word [nticks], 1
322         jnz .eoi
323         mov cx, 16 * 3
324         mov si, cmap
325 .fadecol:
326         lodsb
327         test al, al
328         jz .skipdec
329         dec al
330         mov [si-1], al
331 .skipdec:
332         dec cx
333         jnz .fadecol
334         
335 .eoi:   mov al, 20h
336         out 20h, al
337         popa
338         iret
339
340 str1:   db 'Michael ',3,' Athena',0
341
342 %ifdef MIDI
343 G2      equ 43
344 C3      equ 48
345 D3      equ 50
346 B2      equ 47
347 F3      equ 53
348 E3      equ 52
349 %else
350 G2      equ 12175
351 C3      equ 9121
352 D3      equ 8126
353 B2      equ 9664
354 F3      equ 6833
355 E3      equ 7239
356 %endif
357
358
359 %ifdef MIDI
360 %macro EV 2
361         db %1 >> 4
362         db %2
363 %endmacro
364 %else
365 %macro EV 2
366         db %1 >> 4
367         dw %2
368 %endmacro
369 %endif
370
371 music:  EV     0,  G2
372         EV   160,  C3
373         EV   272,  C3
374         EV   320,  C3
375         EV   560,  0
376         EV   640,  G2
377         EV   800,  D3
378         EV   912,  B2
379         EV   960,  C3
380         EV  1200,  0
381         EV  1280,  G2
382         EV  1440,  C3
383         EV  1552,  F3
384         EV  1600,  F3
385         EV  1760,  E3
386         EV  1872,  D3
387         EV  1920,  C3
388         EV  2080,  B2
389         EV  2192,  C3
390         EV  2240,  D3
391         EV  2560,  0
392         EV  2720,  0
393
394 w5:     dw 5
395 w30:    dw 30
396
397 %ifndef DOS
398 %ifndef MIDI
399         times 446-($-$$) db 0
400         dd 00212080h
401         dd 0820280ch
402         dd 00000800h
403         dd 0001f800h
404 %endif
405
406         times 510-($-$$) db 0
407         dw 0aa55h
408 %endif
409 ; vi:ft=nasm ts=8 sts=8 sw=8: