1 /* Project 16 Source Code~
\r
2 * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
\r
4 * This file is part of Project 16.
\r
6 * Project 16 is free software; you can redistribute it and/or modify
\r
7 * it under the terms of the GNU General Public License as published by
\r
8 * the Free Software Foundation; either version 3 of the License, or
\r
9 * (at your option) any later version.
\r
11 * Project 16 is distributed in the hope that it will be useful,
\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 * GNU General Public License for more details.
\r
16 * You should have received a copy of the GNU General Public License
\r
17 * along with this program. If not, see <http://www.gnu.org/licenses/>, or
\r
18 * write to the Free Software Foundation, Inc., 51 Franklin Street,
\r
19 * Fifth Floor, Boston, MA 02110-1301 USA.
\r
23 #include "src/lib/16_snd.h"
\r
25 void opl2out(word reg, word data)
\r
30 mov dx,word ptr [ADLIB_FM_ADDRESS]
\r
48 void opl3out(word reg, word data)
\r
53 mov dx,word ptr [ADLIB_FM_ADDRESS]
\r
68 void opl3exp(word data)
\r
73 mov dx,word ptr [ADLIB_FM_ADDRESS]
\r
88 /* Function: FMResest *******************************************************
\r
90 * Description: quick and dirty sound card reset (zeros all
\r
94 void FMReset(void/*int percusiveMode*/)
\r
98 /* zero all registers */
\r
99 for(i = MIN_REGISTER; i < MAX_REGISTER+1; i++) opl2out(i, 0);
\r
101 /* allow FM chips to control the waveform of each operator */
\r
102 opl2out(0x01, 0x20);
\r
104 /* set rhythm enabled (6 melodic voices, 5 percussive) */
\r
105 opl2out(0xBD, 0x20);
\r
107 //FMSetPercusiveMode(percusiveMode);
\r
108 } /* End of FMReset */
\r
110 /* Function: FMKeyOff *******************************************************
\r
112 * Parameters: voice - which voice to turn off.
\r
114 * Description: turns off the specified voice.
\r
117 void FMKeyOff(int voice)
\r
121 /* turn voice off */
\r
122 regNum = 0xB0 + voice % 11;//NUMVOICE;
\r
123 opl2out(regNum, 0x0E);
\r
124 } /* End of FMKeyOff */
\r
126 /* Function: FMKeyOn *******************************************************
\r
128 * Parameters: voice - which voice to turn on.
\r
129 * freq - its frequency (note).
\r
130 * octave - its octave.
\r
132 * Description: turns on a voice of specfied frequency and
\r
136 void FMKeyOn(int voice, int freq, int octave)
\r
140 regNum = 0xA0 + voice % 11;//NUMVOICE;
\r
141 opl2out(regNum, freq & 0xff);
\r
142 regNum = 0xB0 + voice % 11;//NUMVOICE;
\r
143 tmp = (freq >> 8) | (octave << 2) | 0x20;
\r
144 opl2out(regNum, tmp);
\r
145 } /* End of FMKeyOn */
\r
147 /* Function: FMSetVoice *****************************************************
\r
149 * Parameters: voiceNum - which voice to set.
\r
150 * ins - instrument to set voice.
\r
152 * Description: sets the instrument of a voice.
\r
155 void FMSetVoice(int voiceNum, FMInstrument *ins){
\r
156 int opCellNum, cellOffset;
\r
158 voiceNum %= 11;//NUMVOICE;
\r
159 cellOffset = voiceNum % 3 + ((voiceNum / 3) << 3);
\r
161 /* set sound characteristic */
\r
162 opCellNum = 0x20 + (char)cellOffset;
\r
163 opl2out(opCellNum, ins->SoundCharacteristic[0]);
\r
165 opl2out(opCellNum, ins->SoundCharacteristic[1]);
\r
167 /* set level/output */
\r
168 opCellNum = 0x40 + (char)cellOffset;
\r
169 opl2out(opCellNum, ins->Level[0]);
\r
171 opl2out(opCellNum, ins->Level[1]);
\r
173 /* set Attack/Decay */
\r
174 opCellNum = 0x60 + (char)cellOffset;
\r
175 opl2out(opCellNum, ins->AttackDecay[0]);
\r
177 opl2out(opCellNum, ins->AttackDecay[1]);
\r
179 /* set Sustain/Release */
\r
180 opCellNum = 0x80 + (char)cellOffset;
\r
181 opl2out(opCellNum, ins->SustainRelease[0]);
\r
183 opl2out(opCellNum, ins->SustainRelease[1]);
\r
185 /* set Wave Select */
\r
186 opCellNum = 0xE0 + (char)cellOffset;
\r
187 opl2out(opCellNum, ins->WaveSelect[0]);
\r
189 opl2out(opCellNum, ins->WaveSelect[1]);
\r
191 /* set Feedback/Selectivity */
\r
192 opCellNum = (byte)0xC0 + (byte)voiceNum;
\r
193 opl2out(opCellNum, ins->Feedback);
\r
194 } /* End of FMSetVoice */
\r