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