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