1 /*
2 * Copyright (C) 2002-2013 The DOSBox Team
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include "dosbox.h"
20 #include "inout.h"
21 #include "mixer.h"
22 #include "mem.h"
23 #include "hardware.h"
24 #include "setup.h"
25 #include "support.h"
26 #include "pic.h"
27 #include <cstring>
28 #include <math.h>
29
30
31 #define LEFT 0x00
32 #define RIGHT 0x01
33 #define CMS_BUFFER_SIZE 128
34 #define CMS_RATE 22050
35
36
37 typedef Bit8u UINT8;
38 typedef Bit16s INT16;
39
40 /* this structure defines a channel */
41 struct saa1099_channel
42 {
43 int frequency; /* frequency (0x00..0xff) */
44 int freq_enable; /* frequency enable */
45 int noise_enable; /* noise enable */
46 int octave; /* octave (0x00..0x07) */
47 int amplitude[2]; /* amplitude (0x00..0x0f) */
48 int envelope[2]; /* envelope (0x00..0x0f or 0x10 == off) */
49
50 /* vars to simulate the square wave */
51 double counter;
52 double freq;
53 int level;
54 };
55
56 /* this structure defines a noise channel */
57 struct saa1099_noise
58 {
59 /* vars to simulate the noise generator output */
60 double counter;
61 double freq;
62 int level; /* noise polynomal shifter */
63 };
64
65 /* this structure defines a SAA1099 chip */
66 struct SAA1099
67 {
68 int stream; /* our stream */
69 int noise_params[2]; /* noise generators parameters */
70 int env_enable[2]; /* envelope generators enable */
71 int env_reverse_right[2]; /* envelope reversed for right channel */
72 int env_mode[2]; /* envelope generators mode */
73 int env_bits[2]; /* non zero = 3 bits resolution */
74 int env_clock[2]; /* envelope clock mode (non-zero external) */
75 int env_step[2]; /* current envelope step */
76 int all_ch_enable; /* all channels enable */
77 int sync_state; /* sync all channels */
78 int selected_reg; /* selected register */
79 struct saa1099_channel channels[6]; /* channels */
80 struct saa1099_noise noise[2]; /* noise generators */
81 };
82
83 static const UINT8 envelope[8][64] = {
84 /* zero amplitude */
85 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
86 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
87 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
88 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
89 /* maximum amplitude */
90 {15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
91 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
92 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
93 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, },
94 /* single decay */
95 {15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
96 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
97 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
98 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
99 /* repetitive decay */
100 {15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
101 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
102 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
103 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 },
104 /* single triangular */
105 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
106 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
109 /* repetitive triangular */
110 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
111 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
112 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
113 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 },
114 /* single attack */
115 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
117 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
118 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
119 /* repetitive attack */
120 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
121 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
122 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
123 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 }
124 };
125
126
127 static const int amplitude_lookup[16] = {
128 0*32767/16, 1*32767/16, 2*32767/16, 3*32767/16,
129 4*32767/16, 5*32767/16, 6*32767/16, 7*32767/16,
130 8*32767/16, 9*32767/16, 10*32767/16, 11*32767/16,
131 12*32767/16, 13*32767/16, 14*32767/16, 15*32767/16
132 };
133
134 /* global parameters */
135 static double sample_rate;
136 static SAA1099 saa1099[2];
137 static MixerChannel * cms_chan;
138 static Bit16s cms_buffer[2][2][CMS_BUFFER_SIZE];
139 static Bit16s * cms_buf_point[4] = {
140 cms_buffer[0][0],cms_buffer[0][1],cms_buffer[1][0],cms_buffer[1][1] };
141
142 static Bitu last_command;
143 static Bitu base_port;
144
145
saa1099_envelope(int chip,int ch)146 static void saa1099_envelope(int chip, int ch)
147 {
148 struct SAA1099 *saa = &saa1099[chip];
149 if (saa->env_enable[ch])
150 {
151 int step, mode, mask;
152 mode = saa->env_mode[ch];
153 /* step from 0..63 and then loop in steps 32..63 */
154 step = saa->env_step[ch] =
155 ((saa->env_step[ch] + 1) & 0x3f) | (saa->env_step[ch] & 0x20);
156
157 mask = 15;
158 if (saa->env_bits[ch])
159 mask &= ~1; /* 3 bit resolution, mask LSB */
160
161 saa->channels[ch*3+0].envelope[ LEFT] =
162 saa->channels[ch*3+1].envelope[ LEFT] =
163 saa->channels[ch*3+2].envelope[ LEFT] = envelope[mode][step] & mask;
164 if (saa->env_reverse_right[ch] & 0x01)
165 {
166 saa->channels[ch*3+0].envelope[RIGHT] =
167 saa->channels[ch*3+1].envelope[RIGHT] =
168 saa->channels[ch*3+2].envelope[RIGHT] = (15 - envelope[mode][step]) & mask;
169 }
170 else
171 {
172 saa->channels[ch*3+0].envelope[RIGHT] =
173 saa->channels[ch*3+1].envelope[RIGHT] =
174 saa->channels[ch*3+2].envelope[RIGHT] = envelope[mode][step] & mask;
175 }
176 }
177 else
178 {
179 /* envelope mode off, set all envelope factors to 16 */
180 saa->channels[ch*3+0].envelope[ LEFT] =
181 saa->channels[ch*3+1].envelope[ LEFT] =
182 saa->channels[ch*3+2].envelope[ LEFT] =
183 saa->channels[ch*3+0].envelope[RIGHT] =
184 saa->channels[ch*3+1].envelope[RIGHT] =
185 saa->channels[ch*3+2].envelope[RIGHT] = 16;
186 }
187 }
188
189
saa1099_update(int chip,INT16 ** buffer,int length)190 static void saa1099_update(int chip, INT16 **buffer, int length)
191 {
192 struct SAA1099 *saa = &saa1099[chip];
193 int j, ch;
194
195 /* if the channels are disabled we're done */
196 if (!saa->all_ch_enable)
197 {
198 /* init output data */
199 memset(buffer[LEFT],0,length*sizeof(INT16));
200 memset(buffer[RIGHT],0,length*sizeof(INT16));
201 return;
202 }
203
204 for (ch = 0; ch < 2; ch++)
205 {
206 switch (saa->noise_params[ch])
207 {
208 case 0: saa->noise[ch].freq = 31250.0 * 2; break;
209 case 1: saa->noise[ch].freq = 15625.0 * 2; break;
210 case 2: saa->noise[ch].freq = 7812.5 * 2; break;
211 case 3: saa->noise[ch].freq = saa->channels[ch * 3].freq; break;
212 }
213 }
214
215 /* fill all data needed */
216 for( j = 0; j < length; j++ )
217 {
218 int output_l = 0, output_r = 0;
219
220 /* for each channel */
221 for (ch = 0; ch < 6; ch++)
222 {
223 if (saa->channels[ch].freq == 0.0)
224 saa->channels[ch].freq = (double)((2 * 15625) << saa->channels[ch].octave) /
225 (511.0 - (double)saa->channels[ch].frequency);
226
227 /* check the actual position in the square wave */
228 saa->channels[ch].counter -= saa->channels[ch].freq;
229 while (saa->channels[ch].counter < 0)
230 {
231 /* calculate new frequency now after the half wave is updated */
232 saa->channels[ch].freq = (double)((2 * 15625) << saa->channels[ch].octave) /
233 (511.0 - (double)saa->channels[ch].frequency);
234
235 saa->channels[ch].counter += sample_rate;
236 saa->channels[ch].level ^= 1;
237
238 /* eventually clock the envelope counters */
239 if (ch == 1 && saa->env_clock[0] == 0)
240 saa1099_envelope(chip, 0);
241 if (ch == 4 && saa->env_clock[1] == 0)
242 saa1099_envelope(chip, 1);
243 }
244
245 /* if the noise is enabled */
246 if (saa->channels[ch].noise_enable)
247 {
248 /* if the noise level is high (noise 0: chan 0-2, noise 1: chan 3-5) */
249 if (saa->noise[ch/3].level & 1)
250 {
251 /* subtract to avoid overflows, also use only half amplitude */
252 output_l -= saa->channels[ch].amplitude[ LEFT] * saa->channels[ch].envelope[ LEFT] / 16 / 2;
253 output_r -= saa->channels[ch].amplitude[RIGHT] * saa->channels[ch].envelope[RIGHT] / 16 / 2;
254 }
255 }
256
257 /* if the square wave is enabled */
258 if (saa->channels[ch].freq_enable)
259 {
260 /* if the channel level is high */
261 if (saa->channels[ch].level & 1)
262 {
263 output_l += saa->channels[ch].amplitude[ LEFT] * saa->channels[ch].envelope[ LEFT] / 16;
264 output_r += saa->channels[ch].amplitude[RIGHT] * saa->channels[ch].envelope[RIGHT] / 16;
265 }
266 }
267 }
268
269 for (ch = 0; ch < 2; ch++)
270 {
271 /* check the actual position in noise generator */
272 saa->noise[ch].counter -= saa->noise[ch].freq;
273 while (saa->noise[ch].counter < 0)
274 {
275 saa->noise[ch].counter += sample_rate;
276 if( ((saa->noise[ch].level & 0x4000) == 0) == ((saa->noise[ch].level & 0x0040) == 0) )
277 saa->noise[ch].level = (saa->noise[ch].level << 1) | 1;
278 else
279 saa->noise[ch].level <<= 1;
280 }
281 }
282 /* write sound data to the buffer */
283 buffer[LEFT][j] = output_l / 6;
284 buffer[RIGHT][j] = output_r / 6;
285 }
286 }
287
saa1099_write_port_w(int chip,int offset,int data)288 static void saa1099_write_port_w( int chip, int offset, int data )
289 {
290 struct SAA1099 *saa = &saa1099[chip];
291 if(offset == 1) {
292 // address port
293 saa->selected_reg = data & 0x1f;
294 if (saa->selected_reg == 0x18 || saa->selected_reg == 0x19) {
295 /* clock the envelope channels */
296 if (saa->env_clock[0]) saa1099_envelope(chip,0);
297 if (saa->env_clock[1]) saa1099_envelope(chip,1);
298 }
299 return;
300 }
301 int reg = saa->selected_reg;
302 int ch;
303
304 switch (reg)
305 {
306 /* channel i amplitude */
307 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05:
308 ch = reg & 7;
309 saa->channels[ch].amplitude[LEFT] = amplitude_lookup[data & 0x0f];
310 saa->channels[ch].amplitude[RIGHT] = amplitude_lookup[(data >> 4) & 0x0f];
311 break;
312 /* channel i frequency */
313 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d:
314 ch = reg & 7;
315 saa->channels[ch].frequency = data & 0xff;
316 break;
317 /* channel i octave */
318 case 0x10: case 0x11: case 0x12:
319 ch = (reg - 0x10) << 1;
320 saa->channels[ch + 0].octave = data & 0x07;
321 saa->channels[ch + 1].octave = (data >> 4) & 0x07;
322 break;
323 /* channel i frequency enable */
324 case 0x14:
325 saa->channels[0].freq_enable = data & 0x01;
326 saa->channels[1].freq_enable = data & 0x02;
327 saa->channels[2].freq_enable = data & 0x04;
328 saa->channels[3].freq_enable = data & 0x08;
329 saa->channels[4].freq_enable = data & 0x10;
330 saa->channels[5].freq_enable = data & 0x20;
331 break;
332 /* channel i noise enable */
333 case 0x15:
334 saa->channels[0].noise_enable = data & 0x01;
335 saa->channels[1].noise_enable = data & 0x02;
336 saa->channels[2].noise_enable = data & 0x04;
337 saa->channels[3].noise_enable = data & 0x08;
338 saa->channels[4].noise_enable = data & 0x10;
339 saa->channels[5].noise_enable = data & 0x20;
340 break;
341 /* noise generators parameters */
342 case 0x16:
343 saa->noise_params[0] = data & 0x03;
344 saa->noise_params[1] = (data >> 4) & 0x03;
345 break;
346 /* envelope generators parameters */
347 case 0x18: case 0x19:
348 ch = reg - 0x18;
349 saa->env_reverse_right[ch] = data & 0x01;
350 saa->env_mode[ch] = (data >> 1) & 0x07;
351 saa->env_bits[ch] = data & 0x10;
352 saa->env_clock[ch] = data & 0x20;
353 saa->env_enable[ch] = data & 0x80;
354 /* reset the envelope */
355 saa->env_step[ch] = 0;
356 break;
357 /* channels enable & reset generators */
358 case 0x1c:
359 saa->all_ch_enable = data & 0x01;
360 saa->sync_state = data & 0x02;
361 if (data & 0x02)
362 {
363 int i;
364 // logerror("%04x: (SAA1099 #%d) -reg 0x1c- Chip reset\n",activecpu_get_pc(), chip);
365 /* Synch & Reset generators */
366 for (i = 0; i < 6; i++)
367 {
368 saa->channels[i].level = 0;
369 saa->channels[i].counter = 0.0;
370 }
371 }
372 break;
373 default: /* Error! */
374 // logerror("%04x: (SAA1099 #%d) Unknown operation (reg:%02x, data:%02x)\n",activecpu_get_pc(), chip, reg, data);
375 LOG(LOG_MISC,LOG_ERROR)("CMS Unkown write to reg %x with %x",reg, data);
376 }
377 }
378
write_cms(Bitu port,Bitu val,Bitu)379 static void write_cms(Bitu port, Bitu val, Bitu /* iolen */) {
380 if(cms_chan && (!cms_chan->enabled)) cms_chan->Enable(true);
381 last_command = PIC_Ticks;
382 switch (port-base_port) {
383 case 0:
384 saa1099_write_port_w(0,0,val);
385 break;
386 case 1:
387 saa1099_write_port_w(0,1,val);
388 break;
389 case 2:
390 saa1099_write_port_w(1,0,val);
391 break;
392 case 3:
393 saa1099_write_port_w(1,1,val);
394 break;
395 }
396 }
397
CMS_CallBack(Bitu len)398 static void CMS_CallBack(Bitu len) {
399 if (len > CMS_BUFFER_SIZE) return;
400
401 saa1099_update(0, &cms_buf_point[0], (int)len);
402 saa1099_update(1, &cms_buf_point[2], (int)len);
403
404 Bit16s * stream=(Bit16s *) MixTemp;
405 /* Mix chip outputs */
406 for (Bitu l=0;l<len;l++) {
407 register Bits left, right;
408 left = cms_buffer[0][LEFT][l] + cms_buffer[1][LEFT][l];
409 right = cms_buffer[0][RIGHT][l] + cms_buffer[1][RIGHT][l];
410
411 if (left>MAX_AUDIO) *stream=MAX_AUDIO;
412 else if (left<MIN_AUDIO) *stream=MIN_AUDIO;
413 else *stream=(Bit16s)left;
414 stream++;
415
416 if (right>MAX_AUDIO) *stream=MAX_AUDIO;
417 else if (right<MIN_AUDIO) *stream=MIN_AUDIO;
418 else *stream=(Bit16s)right;
419 stream++;
420 }
421 if(cms_chan) cms_chan->AddSamples_s16(len,(Bit16s *)MixTemp);
422 if (last_command + 10000 < PIC_Ticks) if(cms_chan) cms_chan->Enable(false);
423 }
424
425 // The Gameblaster detection
426 static Bit8u cms_detect_register = 0xff;
427
write_cms_detect(Bitu port,Bitu val,Bitu)428 static void write_cms_detect(Bitu port, Bitu val, Bitu /* iolen */) {
429 switch(port-base_port) {
430 case 0x6:
431 case 0x7:
432 cms_detect_register = val;
433 break;
434 }
435 }
436
read_cms_detect(Bitu port,Bitu)437 static Bitu read_cms_detect(Bitu port, Bitu /* iolen */) {
438 Bit8u retval = 0xff;
439 switch(port-base_port) {
440 case 0x4:
441 retval = 0x7f;
442 break;
443 case 0xa:
444 case 0xb:
445 retval = cms_detect_register;
446 break;
447 }
448 return retval;
449 }
450
451
452 class CMS:public Module_base {
453 private:
454 IO_WriteHandleObject WriteHandler;
455 IO_WriteHandleObject DetWriteHandler;
456 IO_ReadHandleObject DetReadHandler;
457 MixerObject MixerChan;
458
459 public:
CMS(Section * configuration)460 CMS(Section* configuration):Module_base(configuration) {
461 Section_prop * section = static_cast<Section_prop *>(configuration);
462 Bitu sample_rate_temp = section->Get_int("oplrate");
463 sample_rate = static_cast<double>(sample_rate_temp);
464 base_port = section->Get_hex("sbbase");
465 WriteHandler.Install(base_port, write_cms, IO_MB,4);
466
467 // A standalone Gameblaster has a magic chip on it which is
468 // sometimes used for detection.
469 const char * sbtype=section->Get_string("sbtype");
470 if (!strcasecmp(sbtype,"gb")) {
471 DetWriteHandler.Install(base_port+4,write_cms_detect,IO_MB,12);
472 DetReadHandler.Install(base_port,read_cms_detect,IO_MB,16);
473 }
474
475 /* Register the Mixer CallBack */
476 cms_chan = MixerChan.Install(CMS_CallBack,sample_rate_temp,"CMS");
477
478 last_command = PIC_Ticks;
479
480 for (int s=0;s<2;s++) {
481 struct SAA1099 *saa = &saa1099[s];
482 memset(saa, 0, sizeof(struct SAA1099));
483 }
484 }
~CMS()485 ~CMS() {
486 cms_chan = 0;
487 }
488 };
489
490
491 static CMS* test;
492
CMS_Init(Section * sec)493 void CMS_Init(Section* sec) {
494 test = new CMS(sec);
495 }
CMS_ShutDown(Section * sec)496 void CMS_ShutDown(Section* sec) {
497 delete test;
498 }
499