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