opmbell.c revision 1.5 1 1.5 oki /* $NetBSD: opmbell.c,v 1.5 1997/10/12 14:44:14 oki Exp $ */
2 1.1 oki
3 1.1 oki /*
4 1.1 oki * Copyright (c) 1995 MINOURA Makoto, Takuya Harakawa.
5 1.1 oki * All rights reserved.
6 1.1 oki *
7 1.1 oki * Redistribution and use in source and binary forms, with or without
8 1.1 oki * modification, are permitted provided that the following conditions
9 1.1 oki * are met:
10 1.1 oki * 1. Redistributions of source code must retain the above copyright
11 1.1 oki * notice, this list of conditions and the following disclaimer.
12 1.1 oki * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 oki * notice, this list of conditions and the following disclaimer in the
14 1.1 oki * documentation and/or other materials provided with the distribution.
15 1.1 oki * 3. All advertising materials mentioning features or use of this software
16 1.1 oki * must display the following acknowledgement:
17 1.1 oki * This product includes software developed by MINOURA Makoto,
18 1.1 oki * Takuya Harakawa.
19 1.1 oki * 4. Neither the name of the authors may be used to endorse or promote
20 1.1 oki * products derived from this software without specific prior written
21 1.1 oki * permission.
22 1.1 oki *
23 1.1 oki * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 1.1 oki * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 1.1 oki * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 1.1 oki * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 1.1 oki * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 1.1 oki * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 1.1 oki * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 1.1 oki * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 1.1 oki * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 1.1 oki * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 1.1 oki * SUCH DAMAGE.
34 1.1 oki *
35 1.1 oki */
36 1.1 oki
37 1.1 oki /*
38 1.1 oki * bell device driver
39 1.1 oki */
40 1.1 oki
41 1.1 oki #include "bell.h"
42 1.1 oki #if NBELL > 0
43 1.1 oki
44 1.1 oki #if NBELL > 1
45 1.1 oki #undef NBELL
46 1.1 oki #define NBELL 1
47 1.1 oki #endif
48 1.1 oki
49 1.1 oki #include <sys/param.h>
50 1.1 oki #include <sys/errno.h>
51 1.1 oki #include <sys/uio.h>
52 1.1 oki #include <sys/device.h>
53 1.1 oki #include <sys/malloc.h>
54 1.1 oki #include <sys/file.h>
55 1.1 oki #include <sys/systm.h>
56 1.5 oki #include <sys/conf.h>
57 1.1 oki
58 1.1 oki #include <x68k/x68k/iodevice.h>
59 1.1 oki #include <machine/opmbellio.h>
60 1.1 oki #include <x68k/dev/opmreg.h>
61 1.1 oki #include <x68k/dev/opmbellvar.h>
62 1.1 oki
63 1.1 oki static u_int bell_pitchtokey __P((u_int));
64 1.5 oki static void bell_timeout __P((void *));
65 1.1 oki
66 1.1 oki struct bell_softc {
67 1.1 oki int sc_flags;
68 1.1 oki u_char ch;
69 1.1 oki u_char volume;
70 1.1 oki u_int pitch;
71 1.1 oki u_int msec;
72 1.1 oki u_int key;
73 1.1 oki };
74 1.1 oki
75 1.1 oki struct bell_softc *bell_softc;
76 1.1 oki
77 1.1 oki static struct opm_voice vtab[NBELL];
78 1.1 oki
79 1.1 oki /* sc_flags values */
80 1.1 oki #define BELLF_READ 0x01
81 1.1 oki #define BELLF_WRITE 0x02
82 1.1 oki #define BELLF_ALIVE 0x04
83 1.1 oki #define BELLF_OPEN 0x08
84 1.1 oki #define BELLF_OUT 0x10
85 1.1 oki #define BELLF_ON 0x20
86 1.1 oki
87 1.1 oki #define UNIT(x) minor(x)
88 1.1 oki
89 1.5 oki cdev_decl(bell);
90 1.5 oki void bell_on __P((struct bell_softc *sc));
91 1.5 oki void bell_off __P((struct bell_softc *sc));
92 1.5 oki void opm_bell __P((void));
93 1.5 oki void opm_bell_on __P((void));
94 1.5 oki void opm_bell_off __P((void));
95 1.5 oki int opm_bell_setup __P((struct bell_info *));
96 1.5 oki int bellmstohz __P((int));
97 1.5 oki
98 1.5 oki void bellattach __P((int));
99 1.5 oki
100 1.2 oki void
101 1.1 oki bellattach(num)
102 1.1 oki int num;
103 1.1 oki {
104 1.1 oki char *mem;
105 1.1 oki register u_long size;
106 1.1 oki register struct bell_softc *sc;
107 1.1 oki int unit;
108 1.1 oki
109 1.1 oki if (num <= 0)
110 1.1 oki return;
111 1.1 oki size = num * sizeof(struct bell_softc);
112 1.1 oki mem = malloc(size, M_DEVBUF, M_NOWAIT);
113 1.1 oki if (mem == NULL) {
114 1.4 christos printf("WARNING: no memory for opm bell\n");
115 1.1 oki return;
116 1.1 oki }
117 1.1 oki bzero(mem, size);
118 1.1 oki bell_softc = (struct bell_softc *)mem;
119 1.1 oki
120 1.1 oki for (unit = 0; unit < num; unit++) {
121 1.1 oki sc = &bell_softc[unit];
122 1.1 oki sc->sc_flags = BELLF_ALIVE;
123 1.1 oki sc->ch = BELL_CHANNEL;
124 1.1 oki sc->volume = BELL_VOLUME;
125 1.1 oki sc->pitch = BELL_PITCH;
126 1.1 oki sc->msec = BELL_DURATION;
127 1.1 oki sc->key = bell_pitchtokey(sc->pitch);
128 1.1 oki
129 1.1 oki /* setup initial voice parameter */
130 1.1 oki bcopy(&bell_voice, &vtab[unit], sizeof(bell_voice));
131 1.1 oki opm_set_voice(sc->ch, &vtab[unit]);
132 1.1 oki
133 1.4 christos printf("bell%d: YM2151 OPM bell emulation.\n", unit);
134 1.1 oki }
135 1.1 oki }
136 1.1 oki
137 1.1 oki int
138 1.5 oki bellopen(dev, flags, mode, p)
139 1.1 oki dev_t dev;
140 1.5 oki int flags, mode;
141 1.5 oki struct proc *p;
142 1.1 oki {
143 1.1 oki register int unit = UNIT(dev);
144 1.1 oki register struct bell_softc *sc = &bell_softc[unit];
145 1.1 oki
146 1.1 oki if (unit >= NBELL || !(sc->sc_flags & BELLF_ALIVE))
147 1.1 oki return ENXIO;
148 1.1 oki
149 1.1 oki if (sc->sc_flags & BELLF_OPEN)
150 1.1 oki return EBUSY;
151 1.1 oki
152 1.1 oki sc->sc_flags |= BELLF_OPEN;
153 1.1 oki sc->sc_flags |= (flags & (FREAD | FWRITE));
154 1.1 oki
155 1.1 oki return 0;
156 1.1 oki }
157 1.1 oki
158 1.5 oki int
159 1.5 oki bellclose(dev, flags, mode, p)
160 1.1 oki dev_t dev;
161 1.5 oki int flags, mode;
162 1.5 oki struct proc *p;
163 1.1 oki {
164 1.1 oki int unit = UNIT(dev);
165 1.1 oki struct bell_softc *sc = &bell_softc[unit];
166 1.1 oki
167 1.1 oki sc->sc_flags &= ~BELLF_OPEN;
168 1.5 oki return 0;
169 1.1 oki }
170 1.1 oki
171 1.1 oki int
172 1.1 oki bellioctl(dev, cmd, addr, flag, p)
173 1.1 oki dev_t dev;
174 1.1 oki u_long cmd;
175 1.1 oki caddr_t addr;
176 1.1 oki int flag;
177 1.1 oki struct proc *p;
178 1.1 oki {
179 1.1 oki int unit = UNIT(dev);
180 1.1 oki struct bell_softc *sc = &bell_softc[unit];
181 1.1 oki
182 1.1 oki switch (cmd) {
183 1.1 oki case BELLIOCGPARAM:
184 1.1 oki {
185 1.1 oki struct bell_info *bp = (struct bell_info *)addr;
186 1.1 oki if (!(sc->sc_flags & FREAD))
187 1.1 oki return EBADF;
188 1.1 oki
189 1.1 oki bp->volume = sc->volume;
190 1.1 oki bp->pitch = sc->pitch;
191 1.1 oki bp->msec = sc->msec;
192 1.1 oki break;
193 1.1 oki }
194 1.1 oki
195 1.1 oki case BELLIOCSPARAM:
196 1.1 oki {
197 1.1 oki struct bell_info *bp = (struct bell_info *)addr;
198 1.1 oki
199 1.1 oki if (!(sc->sc_flags & FWRITE))
200 1.1 oki return EBADF;
201 1.1 oki
202 1.1 oki return opm_bell_setup(bp);
203 1.1 oki }
204 1.1 oki
205 1.1 oki case BELLIOCGVOICE:
206 1.1 oki if (!(sc->sc_flags & FREAD))
207 1.1 oki return EBADF;
208 1.1 oki
209 1.1 oki if (addr == NULL)
210 1.1 oki return EFAULT;
211 1.1 oki
212 1.1 oki bcopy(&vtab[unit], addr, sizeof(struct opm_voice));
213 1.1 oki break;
214 1.1 oki
215 1.1 oki case BELLIOCSVOICE:
216 1.1 oki if (!(sc->sc_flags & FWRITE))
217 1.1 oki return EBADF;
218 1.1 oki
219 1.1 oki if (addr == NULL)
220 1.1 oki return EFAULT;
221 1.1 oki
222 1.1 oki bcopy(addr, &vtab[unit], sizeof(struct opm_voice));
223 1.1 oki opm_set_voice(sc->ch, &vtab[unit]);
224 1.1 oki break;
225 1.1 oki
226 1.1 oki default:
227 1.1 oki return EINVAL;
228 1.1 oki }
229 1.1 oki return 0;
230 1.1 oki }
231 1.1 oki
232 1.1 oki /*
233 1.1 oki * The next table is used for calculating KeyCode/KeyFraction pair
234 1.1 oki * from frequency.
235 1.1 oki */
236 1.1 oki
237 1.1 oki static u_int note[] = {
238 1.1 oki 0x0800, 0x0808, 0x0810, 0x081c,
239 1.1 oki 0x0824, 0x0830, 0x0838, 0x0844,
240 1.1 oki 0x084c, 0x0858, 0x0860, 0x086c,
241 1.1 oki 0x0874, 0x0880, 0x0888, 0x0890,
242 1.1 oki 0x089c, 0x08a4, 0x08b0, 0x08b8,
243 1.1 oki 0x08c4, 0x08cc, 0x08d8, 0x08e0,
244 1.1 oki 0x08ec, 0x08f4, 0x0900, 0x0908,
245 1.1 oki 0x0910, 0x091c, 0x0924, 0x092c,
246 1.1 oki 0x0938, 0x0940, 0x0948, 0x0954,
247 1.1 oki 0x095c, 0x0968, 0x0970, 0x0978,
248 1.1 oki 0x0984, 0x098c, 0x0994, 0x09a0,
249 1.1 oki 0x09a8, 0x09b4, 0x09bc, 0x09c4,
250 1.1 oki 0x09d0, 0x09d8, 0x09e0, 0x09ec,
251 1.1 oki 0x09f4, 0x0a00, 0x0a08, 0x0a10,
252 1.1 oki 0x0a18, 0x0a20, 0x0a28, 0x0a30,
253 1.1 oki 0x0a38, 0x0a44, 0x0a4c, 0x0a54,
254 1.1 oki 0x0a5c, 0x0a64, 0x0a6c, 0x0a74,
255 1.1 oki 0x0a80, 0x0a88, 0x0a90, 0x0a98,
256 1.1 oki 0x0aa0, 0x0aa8, 0x0ab0, 0x0ab8,
257 1.1 oki 0x0ac4, 0x0acc, 0x0ad4, 0x0adc,
258 1.1 oki 0x0ae4, 0x0aec, 0x0af4, 0x0c00,
259 1.1 oki 0x0c08, 0x0c10, 0x0c18, 0x0c20,
260 1.1 oki 0x0c28, 0x0c30, 0x0c38, 0x0c40,
261 1.1 oki 0x0c48, 0x0c50, 0x0c58, 0x0c60,
262 1.1 oki 0x0c68, 0x0c70, 0x0c78, 0x0c84,
263 1.1 oki 0x0c8c, 0x0c94, 0x0c9c, 0x0ca4,
264 1.1 oki 0x0cac, 0x0cb4, 0x0cbc, 0x0cc4,
265 1.1 oki 0x0ccc, 0x0cd4, 0x0cdc, 0x0ce4,
266 1.1 oki 0x0cec, 0x0cf4, 0x0d00, 0x0d04,
267 1.1 oki 0x0d0c, 0x0d14, 0x0d1c, 0x0d24,
268 1.1 oki 0x0d2c, 0x0d34, 0x0d3c, 0x0d44,
269 1.1 oki 0x0d4c, 0x0d54, 0x0d5c, 0x0d64,
270 1.1 oki 0x0d6c, 0x0d74, 0x0d7c, 0x0d80,
271 1.1 oki 0x0d88, 0x0d90, 0x0d98, 0x0da0,
272 1.1 oki 0x0da8, 0x0db0, 0x0db8, 0x0dc0,
273 1.1 oki 0x0dc8, 0x0dd0, 0x0dd8, 0x0de0,
274 1.1 oki 0x0de8, 0x0df0, 0x0df8, 0x0e00,
275 1.1 oki 0x0e04, 0x0e0c, 0x0e14, 0x0e1c,
276 1.1 oki 0x0e24, 0x0e28, 0x0e30, 0x0e38,
277 1.1 oki 0x0e40, 0x0e48, 0x0e50, 0x0e54,
278 1.1 oki 0x0e5c, 0x0e64, 0x0e6c, 0x0e74,
279 1.1 oki 0x0e7c, 0x0e80, 0x0e88, 0x0e90,
280 1.1 oki 0x0e98, 0x0ea0, 0x0ea8, 0x0eac,
281 1.1 oki 0x0eb4, 0x0ebc, 0x0ec4, 0x0ecc,
282 1.1 oki 0x0ed4, 0x0ed8, 0x0ee0, 0x0ee8,
283 1.1 oki 0x0ef0, 0x0ef8, 0x1000, 0x1004,
284 1.1 oki 0x100c, 0x1014, 0x1018, 0x1020,
285 1.1 oki 0x1028, 0x1030, 0x1034, 0x103c,
286 1.1 oki 0x1044, 0x104c, 0x1050, 0x1058,
287 1.1 oki 0x1060, 0x1064, 0x106c, 0x1074,
288 1.1 oki 0x107c, 0x1080, 0x1088, 0x1090,
289 1.1 oki 0x1098, 0x109c, 0x10a4, 0x10ac,
290 1.1 oki 0x10b0, 0x10b8, 0x10c0, 0x10c8,
291 1.1 oki 0x10cc, 0x10d4, 0x10dc, 0x10e4,
292 1.1 oki 0x10e8, 0x10f0, 0x10f8, 0x1100,
293 1.1 oki 0x1104, 0x110c, 0x1110, 0x1118,
294 1.1 oki 0x1120, 0x1124, 0x112c, 0x1134,
295 1.1 oki 0x1138, 0x1140, 0x1148, 0x114c,
296 1.1 oki 0x1154, 0x1158, 0x1160, 0x1168,
297 1.1 oki 0x116c, 0x1174, 0x117c, 0x1180,
298 1.1 oki 0x1188, 0x1190, 0x1194, 0x119c,
299 1.1 oki 0x11a4, 0x11a8, 0x11b0, 0x11b4,
300 1.1 oki 0x11bc, 0x11c4, 0x11c8, 0x11d0,
301 1.1 oki 0x11d8, 0x11dc, 0x11e4, 0x11ec,
302 1.1 oki 0x11f0, 0x11f8, 0x1200, 0x1204,
303 1.1 oki 0x120c, 0x1210, 0x1218, 0x121c,
304 1.1 oki 0x1224, 0x1228, 0x1230, 0x1238,
305 1.1 oki 0x123c, 0x1244, 0x1248, 0x1250,
306 1.1 oki 0x1254, 0x125c, 0x1260, 0x1268,
307 1.1 oki 0x1270, 0x1274, 0x127c, 0x1280,
308 1.1 oki 0x1288, 0x128c, 0x1294, 0x129c,
309 1.1 oki 0x12a0, 0x12a8, 0x12ac, 0x12b4,
310 1.1 oki 0x12b8, 0x12c0, 0x12c4, 0x12cc,
311 1.1 oki 0x12d4, 0x12d8, 0x12e0, 0x12e4,
312 1.1 oki 0x12ec, 0x12f0, 0x12f8, 0x1400,
313 1.1 oki 0x1404, 0x1408, 0x1410, 0x1414,
314 1.1 oki 0x141c, 0x1420, 0x1428, 0x142c,
315 1.1 oki 0x1434, 0x1438, 0x1440, 0x1444,
316 1.1 oki 0x1448, 0x1450, 0x1454, 0x145c,
317 1.1 oki 0x1460, 0x1468, 0x146c, 0x1474,
318 1.1 oki 0x1478, 0x1480, 0x1484, 0x1488,
319 1.1 oki 0x1490, 0x1494, 0x149c, 0x14a0,
320 1.1 oki 0x14a8, 0x14ac, 0x14b4, 0x14b8,
321 1.1 oki 0x14c0, 0x14c4, 0x14c8, 0x14d0,
322 1.1 oki 0x14d4, 0x14dc, 0x14e0, 0x14e8,
323 1.1 oki 0x14ec, 0x14f4, 0x14f8, 0x1500,
324 1.1 oki 0x1504, 0x1508, 0x1510, 0x1514,
325 1.1 oki 0x1518, 0x1520, 0x1524, 0x1528,
326 1.1 oki 0x1530, 0x1534, 0x1538, 0x1540,
327 1.1 oki 0x1544, 0x154c, 0x1550, 0x1554,
328 1.1 oki 0x155c, 0x1560, 0x1564, 0x156c,
329 1.1 oki 0x1570, 0x1574, 0x157c, 0x1580,
330 1.1 oki 0x1588, 0x158c, 0x1590, 0x1598,
331 1.1 oki 0x159c, 0x15a0, 0x15a8, 0x15ac,
332 1.1 oki 0x15b0, 0x15b8, 0x15bc, 0x15c4,
333 1.1 oki 0x15c8, 0x15cc, 0x15d4, 0x15d8,
334 1.1 oki 0x15dc, 0x15e4, 0x15e8, 0x15ec,
335 1.1 oki 0x15f4, 0x15f8, 0x1600, 0x1604,
336 1.1 oki 0x1608, 0x160c, 0x1614, 0x1618,
337 1.1 oki 0x161c, 0x1620, 0x1628, 0x162c,
338 1.1 oki 0x1630, 0x1638, 0x163c, 0x1640,
339 1.1 oki 0x1644, 0x164c, 0x1650, 0x1654,
340 1.1 oki 0x165c, 0x1660, 0x1664, 0x1668,
341 1.1 oki 0x1670, 0x1674, 0x1678, 0x1680,
342 1.1 oki 0x1684, 0x1688, 0x168c, 0x1694,
343 1.1 oki 0x1698, 0x169c, 0x16a0, 0x16a8,
344 1.1 oki 0x16ac, 0x16b0, 0x16b8, 0x16bc,
345 1.1 oki 0x16c0, 0x16c4, 0x16cc, 0x16d0,
346 1.1 oki 0x16d4, 0x16dc, 0x16e0, 0x16e4,
347 1.1 oki 0x16e8, 0x16f0, 0x16f4, 0x16f8,
348 1.1 oki };
349 1.1 oki
350 1.1 oki static u_int
351 1.1 oki bell_pitchtokey(pitch)
352 1.1 oki u_int pitch;
353 1.1 oki {
354 1.1 oki int i, oct;
355 1.1 oki u_int key;
356 1.1 oki
357 1.1 oki i = 16 * pitch / 440;
358 1.1 oki for (oct = -1; i > 0; i >>= 1, oct++)
359 1.1 oki ;
360 1.1 oki
361 1.1 oki i = (pitch * 16 - (440 * (1 << oct))) / (1 << oct);
362 1.1 oki key = (oct << 12) + note[i];
363 1.1 oki
364 1.1 oki return key;
365 1.1 oki }
366 1.1 oki
367 1.1 oki /*
368 1.1 oki * The next table is a little trikcy table of volume factors.
369 1.1 oki * Its values have been calculated as table[i] = -15 * log10(i/100)
370 1.1 oki * with an obvious exception for i = 0; This log-table converts a linear
371 1.1 oki * volume-scaling (0...100) to a logarithmic scaling as present in the
372 1.1 oki * OPM chips. so: Volume 50% = 6 db.
373 1.1 oki */
374 1.1 oki
375 1.1 oki static u_char vol_table[] = {
376 1.1 oki 0x7f, 0x35, 0x2d, 0x28, 0x25, 0x22, 0x20, 0x1e,
377 1.1 oki 0x1d, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, 0x15,
378 1.1 oki 0x15, 0x14, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11,
379 1.1 oki 0x10, 0x10, 0x0f, 0x0f, 0x0e, 0x0e, 0x0d, 0x0d,
380 1.1 oki 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0a,
381 1.1 oki 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x08, 0x08,
382 1.1 oki 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
383 1.1 oki 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05,
384 1.1 oki 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
385 1.1 oki 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02,
386 1.1 oki 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
387 1.1 oki 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
388 1.1 oki 0x00, 0x00, 0x00, 0x00, 0x00,
389 1.1 oki };
390 1.1 oki
391 1.1 oki void
392 1.1 oki bell_on(sc)
393 1.1 oki register struct bell_softc *sc;
394 1.1 oki {
395 1.1 oki int sps;
396 1.1 oki
397 1.1 oki sps = spltty();
398 1.1 oki opm_set_volume(sc->ch, vol_table[sc->volume]);
399 1.1 oki opm_set_key(sc->ch, sc->key);
400 1.1 oki splx(sps);
401 1.1 oki
402 1.1 oki opm_key_on(sc->ch);
403 1.1 oki sc->sc_flags |= BELLF_ON;
404 1.1 oki }
405 1.1 oki
406 1.1 oki void
407 1.1 oki bell_off(sc)
408 1.1 oki register struct bell_softc *sc;
409 1.1 oki {
410 1.1 oki if (sc->sc_flags & BELLF_ON) {
411 1.1 oki opm_key_off(sc->ch);
412 1.1 oki sc->sc_flags &= ~BELLF_ON;
413 1.1 oki }
414 1.1 oki }
415 1.1 oki
416 1.1 oki void
417 1.1 oki opm_bell()
418 1.1 oki {
419 1.1 oki register struct bell_softc *sc = &bell_softc[0];
420 1.1 oki register int ticks;
421 1.1 oki int sps;
422 1.1 oki
423 1.1 oki if (sc->msec != 0) {
424 1.1 oki if (sc->sc_flags & BELLF_OUT) {
425 1.5 oki bell_timeout(0);
426 1.1 oki } else if (sc->sc_flags & BELLF_ON)
427 1.1 oki return;
428 1.1 oki
429 1.1 oki ticks = bellmstohz(sc->msec);
430 1.1 oki
431 1.1 oki bell_on(sc);
432 1.1 oki sc->sc_flags |= BELLF_OUT;
433 1.1 oki
434 1.1 oki timeout(bell_timeout, (caddr_t)NULL, ticks);
435 1.1 oki }
436 1.1 oki }
437 1.1 oki
438 1.1 oki static void
439 1.5 oki bell_timeout(arg)
440 1.5 oki void *arg;
441 1.1 oki {
442 1.1 oki struct bell_softc *sc = &bell_softc[0];
443 1.1 oki
444 1.1 oki sc->sc_flags &= ~BELLF_OUT;
445 1.1 oki bell_off(sc);
446 1.1 oki untimeout(bell_timeout, (caddr_t)NULL);
447 1.1 oki }
448 1.1 oki
449 1.1 oki void
450 1.1 oki opm_bell_on()
451 1.1 oki {
452 1.1 oki register struct bell_softc *sc = &bell_softc[0];
453 1.1 oki
454 1.1 oki if (sc->sc_flags & BELLF_OUT)
455 1.5 oki bell_timeout(0);
456 1.1 oki if (sc->sc_flags & BELLF_ON)
457 1.1 oki return;
458 1.1 oki
459 1.1 oki bell_on(sc);
460 1.1 oki }
461 1.1 oki
462 1.1 oki void
463 1.1 oki opm_bell_off()
464 1.1 oki {
465 1.1 oki register struct bell_softc *sc = &bell_softc[0];
466 1.1 oki
467 1.1 oki if (sc->sc_flags & BELLF_ON)
468 1.1 oki bell_off(sc);
469 1.1 oki }
470 1.1 oki
471 1.1 oki int
472 1.1 oki opm_bell_setup(data)
473 1.1 oki struct bell_info *data;
474 1.1 oki {
475 1.1 oki register struct bell_softc *sc = &bell_softc[0];
476 1.1 oki
477 1.1 oki /* bounds check */
478 1.1 oki if (data->pitch > MAXBPITCH || data->pitch < MINBPITCH ||
479 1.1 oki data->volume > MAXBVOLUME || data->msec > MAXBTIME) {
480 1.1 oki return EINVAL;
481 1.1 oki } else {
482 1.1 oki sc->volume = data->volume;
483 1.1 oki sc->pitch = data->pitch;
484 1.1 oki sc->msec = data->msec;
485 1.1 oki
486 1.1 oki sc->key = bell_pitchtokey(data->pitch);
487 1.1 oki }
488 1.1 oki return 0;
489 1.1 oki }
490 1.1 oki
491 1.1 oki int
492 1.1 oki bellmstohz(m)
493 1.1 oki int m;
494 1.1 oki {
495 1.1 oki extern int hz;
496 1.1 oki register int h = m;
497 1.1 oki
498 1.1 oki if (h > 0) {
499 1.1 oki h = h * hz / 1000;
500 1.1 oki if (h == 0)
501 1.1 oki h = 1000 / hz;
502 1.1 oki }
503 1.1 oki return h;
504 1.1 oki }
505 1.1 oki
506 1.1 oki #endif
507