Home | History | Annotate | Line # | Download | only in dev
opm.c revision 1.2.12.1
      1  1.2.12.1  thorpej /*	$NetBSD: opm.c,v 1.2.12.1 1997/10/14 10:20:30 thorpej Exp $	*/
      2       1.1      oki 
      3       1.1      oki /*
      4       1.1      oki  * Copyright (c) 1995 Masanobu Saitoh, 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 Masanobu Saitoh.
     18       1.1      oki  * 4. Neither the name of the University nor of the Laboratory may be used
     19       1.1      oki  *    to endorse or promote products derived from this software without
     20       1.1      oki  *    specific prior written permission.
     21       1.1      oki  *
     22       1.1      oki  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23       1.1      oki  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24       1.1      oki  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25       1.1      oki  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26       1.1      oki  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27       1.1      oki  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28       1.1      oki  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29       1.1      oki  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30       1.1      oki  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31       1.1      oki  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32       1.1      oki  * SUCH DAMAGE.
     33       1.1      oki  */
     34       1.1      oki 
     35       1.1      oki #include "fd.h"
     36       1.1      oki /*#include "bsdaudio.h"*/
     37       1.1      oki #include "bell.h"
     38       1.1      oki 
     39       1.1      oki #if ((NBSDAUDIO > 0) || (NFD > 0) || (NBELL > 0))
     40       1.1      oki 
     41       1.1      oki #include <sys/param.h>
     42       1.1      oki #include <sys/systm.h>
     43       1.1      oki #include <x68k/dev/opmreg.h>
     44       1.1      oki #include <x68k/dev/bsd_audioreg.h>
     45       1.1      oki #include <x68k/x68k/iodevice.h>
     46       1.1      oki 
     47       1.1      oki static u_char opmreg[0x100];
     48       1.1      oki static struct opm_voice vdata[8];
     49       1.1      oki 
     50  1.2.12.1  thorpej void opm_set_volume __P((int, int));
     51  1.2.12.1  thorpej void opm_set_key __P((int, int));
     52  1.2.12.1  thorpej void opm_set_voice __P((int, struct opm_voice *));
     53  1.2.12.1  thorpej void opm_set_voice_sub __P((int, struct opm_operator *));
     54  1.2.12.1  thorpej __inline static void writeopm __P((int, int));
     55  1.2.12.1  thorpej __inline static int readopm __P((int));
     56  1.2.12.1  thorpej void opm_key_on __P((u_char));
     57  1.2.12.1  thorpej void opm_key_off __P((u_char));
     58  1.2.12.1  thorpej int opmopen __P((dev_t, int, int));
     59  1.2.12.1  thorpej int opmclose __P((dev_t));
     60       1.1      oki 
     61  1.2.12.1  thorpej __inline static void
     62       1.1      oki writeopm(reg, dat)
     63       1.1      oki 	int reg, dat;
     64       1.1      oki {
     65       1.1      oki 	while (OPM.data & 0x80);
     66       1.1      oki 	OPM.reg = reg;
     67       1.1      oki 	while (OPM.data & 0x80);
     68       1.1      oki 	OPM.data = opmreg[reg] = dat;
     69       1.1      oki }
     70       1.1      oki 
     71  1.2.12.1  thorpej __inline static int
     72       1.1      oki readopm(reg)
     73       1.1      oki 	int reg;
     74       1.1      oki {
     75       1.1      oki 	return opmreg[reg];
     76       1.1      oki }
     77       1.1      oki 
     78       1.1      oki void
     79       1.1      oki adpcm_chgclk(clk)
     80       1.1      oki 	u_char	clk;
     81       1.1      oki {
     82       1.1      oki 	writeopm(0x1b, readopm(0x1b) & ~OPM1B_CT1MSK | clk);
     83       1.1      oki }
     84       1.1      oki 
     85       1.1      oki void
     86       1.1      oki fdc_force_ready(rdy)
     87       1.1      oki 	u_char	rdy;
     88       1.1      oki {
     89       1.1      oki 	writeopm(0x1b, readopm(0x1b) & ~OPM1B_CT2MSK | rdy);
     90       1.1      oki }
     91       1.1      oki 
     92       1.1      oki void
     93       1.1      oki opm_key_on(channel)
     94  1.2.12.1  thorpej 	u_char channel;
     95       1.1      oki {
     96       1.1      oki     writeopm(0x08, vdata[channel].sm << 3 | channel);
     97       1.1      oki }
     98       1.1      oki 
     99       1.1      oki void
    100       1.1      oki opm_key_off(channel)
    101       1.1      oki 	u_char	channel;
    102       1.1      oki {
    103       1.1      oki     writeopm(0x08, channel);
    104       1.1      oki }
    105       1.1      oki 
    106       1.1      oki void
    107       1.1      oki opm_set_voice(channel, voice)
    108       1.1      oki 	int channel;
    109       1.1      oki 	struct opm_voice *voice;
    110       1.1      oki {
    111       1.1      oki 	bcopy(voice, &vdata[channel], sizeof(struct opm_voice));
    112       1.1      oki 
    113       1.1      oki 	opm_set_voice_sub(0x40 + channel, &voice->m1);
    114       1.1      oki 	opm_set_voice_sub(0x48 + channel, &voice->m2);
    115       1.1      oki 	opm_set_voice_sub(0x50 + channel, &voice->c1);
    116       1.1      oki 	opm_set_voice_sub(0x58 + channel, &voice->c2);
    117       1.1      oki 	writeopm(0x20 + channel, 0xc0 | (voice->fb & 0x7) << 3 | (voice->con & 0x7));
    118       1.1      oki }
    119       1.1      oki 
    120       1.1      oki void
    121       1.1      oki opm_set_voice_sub(reg, op)
    122       1.1      oki 	register int reg;
    123       1.1      oki 	struct opm_operator *op;
    124       1.1      oki {
    125       1.1      oki     /* DT1/MUL */
    126       1.1      oki     writeopm(reg, (op->dt1 & 0x7) << 3 | (op->mul & 0x7));
    127       1.1      oki 
    128       1.1      oki     /* TL */
    129       1.1      oki     writeopm(reg + 0x20, op->tl & 0x7f);
    130       1.1      oki 
    131       1.1      oki     /* KS/AR */
    132       1.1      oki     writeopm(reg + 0x40, (op->ks & 0x3) << 6 | (op->ar & 0x1f));
    133       1.1      oki 
    134       1.1      oki     /* AMS/D1R */
    135       1.1      oki     writeopm(reg + 0x60, (op->ame & 0x1) << 7 | (op->d1r & 0x1f));
    136       1.1      oki 
    137       1.1      oki     /* DT2/D2R */
    138       1.1      oki     writeopm(reg + 0x80, (op->dt2 & 0x3) << 6 | (op->d2r & 0x1f));
    139       1.1      oki 
    140       1.1      oki     /* D1L/RR */
    141       1.1      oki     writeopm(reg + 0xa0, (op->d1l & 0xf) << 4 | (op->rr & 0xf));
    142       1.1      oki }
    143       1.1      oki 
    144       1.1      oki void
    145       1.1      oki opm_set_volume(channel, volume)
    146       1.1      oki 	int channel;
    147       1.1      oki 	int volume;
    148       1.1      oki {
    149       1.1      oki     int value;
    150       1.1      oki 
    151       1.1      oki     switch (vdata[channel].con) {
    152       1.1      oki     case 7:
    153       1.1      oki 	value = vdata[channel].m1.tl + volume;
    154       1.1      oki 	writeopm(0x60 + channel, ((value > 0x7f) ? 0x7f : value));
    155       1.1      oki     case 6:
    156       1.1      oki     case 5:
    157       1.1      oki 	value = vdata[channel].m2.tl + volume;
    158       1.1      oki 	writeopm(0x68 + channel, ((value > 0x7f) ? 0x7f : value));
    159       1.1      oki     case 4:
    160       1.1      oki 	value = vdata[channel].c1.tl + volume;
    161       1.1      oki 	writeopm(0x70 + channel, ((value > 0x7f) ? 0x7f : value));
    162       1.1      oki     case 3:
    163       1.1      oki     case 2:
    164       1.1      oki     case 1:
    165       1.1      oki     case 0:
    166       1.1      oki 	value = vdata[channel].c2.tl + volume;
    167       1.1      oki 	writeopm(0x78 + channel, ((value > 0x7f) ? 0x7f : value));
    168       1.1      oki     }
    169       1.1      oki }
    170       1.1      oki 
    171       1.1      oki void
    172       1.1      oki opm_set_key(channel, tone)
    173       1.1      oki 	int channel;
    174       1.1      oki 	int tone;
    175       1.1      oki {
    176       1.1      oki 	writeopm(0x28 + channel, tone >> 8);
    177       1.1      oki 	writeopm(0x30 + channel, tone & 0xff);
    178       1.1      oki }
    179       1.1      oki 
    180       1.1      oki /*ARGSUSED*/
    181       1.1      oki int
    182       1.1      oki opmopen(dev, flag, mode)
    183       1.1      oki 	dev_t dev;
    184  1.2.12.1  thorpej 	int flag, mode;
    185       1.1      oki {
    186       1.2      oki 	return 0;
    187       1.1      oki }
    188       1.1      oki 
    189       1.1      oki /*ARGSUSED*/
    190       1.1      oki int
    191       1.1      oki opmclose(dev)
    192       1.1      oki 	dev_t dev;
    193       1.1      oki {
    194       1.2      oki 	return 0;
    195       1.1      oki }
    196       1.1      oki 
    197       1.1      oki #endif
    198