music
[bootcard] / bootcard.asm
1 ; ---- boot me! ----
2 ; nasm -f bin -o bootcard.img bootcard.asm
3 ; cat bootcard.img >/dev/<usbstick>
4 ; reboot
5
6         org 7c00h
7         bits 16
8
9 data_start      equ 7e00h
10 nticks          equ data_start
11 tmoffs          equ nticks + 4
12 muscur          equ tmoffs + 4
13 spkstat         equ muscur + 4
14 vol             equ spkstat + 4
15 data_end        equ vol + 4
16
17 OSC_FREQ        equ 1193182
18 PIT_DATA0       equ 40h
19 PIT_CMD         equ 43h
20 PIT_CMD_CHAN0   equ 00h
21 PIT_CMD_HILO    equ 30h
22 PIT_CMD_SQWAVE  equ 06h
23 KB_CTRL         equ 61h
24
25 %define DIV_ROUND(a, b) ((a) / (b) + ((a) % (b)) / ((b) / 2))
26
27 %macro setcursor 2
28         mov dl, %1
29         mov dh, %2
30         xor bx, bx
31         mov ah, 2
32         int 10h
33 %endmacro
34 %macro spkon 0
35         in al, KB_CTRL
36         or al, 3
37         out KB_CTRL, al
38 %endmacro
39 %macro spkoff 0
40         in al, KB_CTRL
41         and al, 0fch
42         out KB_CTRL, al
43 %endmacro
44 %macro settimer 2
45         mov al, (PIT_CMD_CHAN0 + (%1 << 6)) | PIT_CMD_HILO | PIT_CMD_SQWAVE
46         out PIT_CMD, al
47         mov ax, %2
48         out PIT_DATA0 + %1, al
49         mov al, ah
50         out PIT_DATA0 + %1, al
51 %endmacro
52
53         xor eax, eax
54         mov ds, ax
55         mov es, ax
56         mov ss, ax
57         mov sp, 7c00h
58
59         mov di, data_start
60         mov cx, (data_end - data_start) / 2
61         rep stosw
62
63         ;mov word [vol], 04h
64         mov word [32], timer_intr
65         mov word [34], 0
66
67         settimer 0, DIV_ROUND(OSC_FREQ, 100)
68
69         mov ax, 13h
70         int 10h
71         mov ax, 0a000h
72         mov es, ax
73
74         mov ax, 0303h
75         mov cx, 32000
76         xor di, di
77         rep stosw
78
79         setcursor 10, 12
80         mov si, str1
81         call textout
82         setcursor 12, 13
83         mov si, str2
84         call textout
85
86         sti
87
88 infloop:
89         hlt
90         jmp infloop
91
92 textout:
93         mov al, [si]
94         and al, al
95         jz .done
96         mov ah, 0eh
97         mov bx, 0fh
98         int 10h
99         inc si
100         jmp textout
101 .done:  ret
102
103 timer_intr:
104         pusha
105         mov ax, [nticks]
106         inc ax
107         mov [nticks], ax
108
109         sub ax, [tmoffs]
110 .pmus:  mov bx, [muscur]
111         shl bx, 2
112         mov cx, [music + bx]    ; event time
113         cmp cx, 0ffffh
114         jz .loop
115         cmp ax, cx
116         jb .dopwm
117
118         inc dword [muscur]
119         mov ax, [music + 2 + bx] ; event counter reload
120         test ax, ax
121         jz .off
122         mov bx, ax
123         settimer 2, bx
124         spkon
125         mov word [spkstat], 1
126         jmp .dopwm
127
128 .off:   spkoff
129         mov word [spkstat], 0
130         jmp .eoi
131
132         ; PWM for volume control
133 .dopwm: jmp .eoi
134         spkoff
135         mov ax, [spkstat]
136         test ax, ax
137         jz .eoi
138         mov ax, [nticks]
139         and ax, 0fh
140         cmp ax, [vol]
141         jae .pwmoff
142         spkon
143         jmp .eoi
144 .pwmoff:
145         spkoff
146
147 .eoi:   mov al, 20h
148         out 20h, al     ; EOI
149         popa
150         iret
151
152 .loop:  neg cx
153         mov [muscur], cx
154         mov ax, [nticks]
155         mov [tmoffs], ax
156         jmp .pmus
157         
158
159 str1:   db 'message message blah',0
160 str2:   db 'Michael & Athina',0
161
162 G1      equ 24351
163 C2      equ 18243
164 D2      equ 16252
165 B1      equ 19328
166 F2      equ 13666
167 E2      equ 14479
168
169 %define TM(x)   (40 + (x) * 2)
170
171 music:  dw 0, 0
172         dw TM(0),       G1
173         dw TM(40),      C2
174         dw TM(70),      C2
175
176         dw TM(80),      C2
177         dw TM(140),     0
178
179         dw TM(160),     G1
180         dw TM(200),     D2
181         dw TM(230),     B1
182
183         dw TM(240),     C2
184         dw TM(300),     0
185
186         dw TM(320),     G1
187         dw TM(360),     C2
188         dw TM(390),     F2
189
190         dw TM(400),     F2
191         dw TM(440),     E2
192         dw TM(470),     D2
193
194         dw TM(480),     C2
195         dw TM(520),     B1
196         dw TM(550),     C2
197
198         dw TM(560),     D2
199         dw TM(640),     0
200
201         dw TM(680),     0
202         dw 0ffffh, 0
203
204         times 446-($-$$) db 0
205         dd 00212080h
206         dd 0820280ch
207         dd 00000800h
208         dd 0001f800h
209         times 510-($-$$) db 0
210         dw 0aa55h
211
212 ; vi:ft=nasm ts=8 sts=8 sw=8: