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