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