1 /**********************************************************************************************
2  *
3  *   Yamaha YMZ280B driver
4  *   by Aaron Giles
5  *
6  **********************************************************************************************/
7 
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <math.h>
12 
13 #include "driver.h"
14 #include "adpcm.h"
15 #include "state.h"
16 
17 
18 #define MAX_SAMPLE_CHUNK	10000
19 #define MAKE_WAVS			0
20 
21 #define FRAC_BITS			14
22 #define FRAC_ONE			(1 << FRAC_BITS)
23 #define FRAC_MASK			(FRAC_ONE - 1)
24 
25 #if MAKE_WAVS
26 #include "wavwrite.h"
27 #endif
28 
29 
30 /* struct describing a single playing ADPCM voice */
31 struct YMZ280BVoice
32 {
33 	UINT8 playing;			/* 1 if we are actively playing */
34 
35 	UINT8 keyon;			/* 1 if the key is on */
36 	UINT8 looping;			/* 1 if looping is enabled */
37 	UINT8 mode;				/* current playback mode */
38 	UINT16 fnum;			/* frequency */
39 	UINT8 level;			/* output level */
40 	UINT8 pan;				/* panning */
41 
42 	UINT32 start;			/* start address, in nibbles */
43 	UINT32 stop;			/* stop address, in nibbles */
44 	UINT32 loop_start;		/* loop start address, in nibbles */
45 	UINT32 loop_end;		/* loop end address, in nibbles */
46 	UINT32 position;		/* current position, in nibbles */
47 
48 	INT32 signal;			/* current ADPCM signal */
49 	INT32 step;				/* current ADPCM step */
50 
51 	INT32 loop_signal;		/* signal at loop start */
52 	INT32 loop_step;		/* step at loop start */
53 	UINT32 loop_count;		/* number of loops so far */
54 
55 	INT32 output_left;		/* output volume (left) */
56 	INT32 output_right;		/* output volume (right) */
57 	INT32 output_step;		/* step value for frequency conversion */
58 	INT32 output_pos;		/* current fractional position */
59 	INT16 last_sample;		/* last sample output */
60 	INT16 curr_sample;		/* current sample target */
61 };
62 
63 struct YMZ280BChip
64 {
65 	int stream;						/* which stream are we using */
66 	UINT8 *region_base;				/* pointer to the base of the region */
67 	UINT8 current_register;			/* currently accessible register */
68 	UINT8 status_register;			/* current status register */
69 	UINT8 irq_state;				/* current IRQ state */
70 	UINT8 irq_mask;					/* current IRQ mask */
71 	UINT8 irq_enable;				/* current IRQ enable */
72 	UINT8 keyon_enable;				/* key on enable */
73 	double master_clock;			/* master clock frequency */
74 	void (*irq_callback)(int);		/* IRQ callback */
75 	struct YMZ280BVoice	voice[8];	/* the 8 voices */
76 
77 #if MAKE_WAVS
78 	void *		wavresample;			/* resampled waveform */
79 #endif
80 };
81 
82 static struct YMZ280BChip ymz280b[MAX_YMZ280B];
83 static INT32 *accumulator;
84 static INT16 *scratch;
85 
86 /* step size index shift table */
87 static int index_scale[8] = { 0x0e6, 0x0e6, 0x0e6, 0x0e6, 0x133, 0x199, 0x200, 0x266 };
88 
89 /* lookup table for the precomputed difference */
90 static int diff_lookup[16];
91 
92 
93 
update_irq_state(struct YMZ280BChip * chip)94 static INLINE void update_irq_state(struct YMZ280BChip *chip)
95 {
96 	int irq_bits = chip->status_register & chip->irq_mask;
97 
98 	/* always off if the enable is off */
99 	if (!chip->irq_enable)
100 		irq_bits = 0;
101 
102 	/* update the state if changed */
103 	if (irq_bits && !chip->irq_state)
104 	{
105 		chip->irq_state = 1;
106 		if (chip->irq_callback)
107 			(*chip->irq_callback)(1);
108 else logerror("ymz280 irq_callback = 0");
109 	}
110 	else if (!irq_bits && chip->irq_state)
111 	{
112 		chip->irq_state = 0;
113 		if (chip->irq_callback)
114 			(*chip->irq_callback)(0);
115 else logerror("ymz280 irq_callback = 0");
116 	}
117 }
118 
119 
update_step(struct YMZ280BChip * chip,struct YMZ280BVoice * voice)120 static INLINE void update_step(struct YMZ280BChip *chip, struct YMZ280BVoice *voice)
121 {
122 	double frequency;
123 
124 	/* handle the sound-off case */
125 	if (Machine->sample_rate == 0)
126 	{
127 		voice->output_step = 0;
128 		return;
129 	}
130 
131 	/* compute the frequency */
132 	if (voice->mode == 1)
133 		frequency = chip->master_clock * (double)((voice->fnum & 0x0ff) + 1) * (1.0 / 256.0);
134 	else
135 		frequency = chip->master_clock * (double)((voice->fnum & 0x1ff) + 1) * (1.0 / 256.0);
136 	voice->output_step = (UINT32)(frequency * (double)FRAC_ONE / (double)Machine->sample_rate);
137 }
138 
139 
update_volumes(struct YMZ280BVoice * voice)140 static INLINE void update_volumes(struct YMZ280BVoice *voice)
141 {
142 	if (voice->pan == 8)
143 	{
144 		voice->output_left = voice->level;
145 		voice->output_right = voice->level;
146 	}
147 	else if (voice->pan < 8)
148 	{
149 		voice->output_left = voice->level;
150 		voice->output_right = voice->level * voice->pan / 8;
151 	}
152 	else
153 	{
154 		voice->output_left = voice->level * (15 - voice->pan) / 8;
155 		voice->output_right = voice->level;
156 	}
157 }
158 
159 
160 /**********************************************************************************************
161 
162      compute_tables -- compute the difference tables
163 
164 ***********************************************************************************************/
165 
compute_tables(void)166 static void compute_tables(void)
167 {
168 	int nib;
169 
170 	/* loop over all nibbles and compute the difference */
171 	for (nib = 0; nib < 16; nib++)
172 	{
173 		int value = (nib & 0x07) * 2 + 1;
174 		diff_lookup[nib] = (nib & 0x08) ? -value : value;
175 	}
176 }
177 
178 
179 
180 /**********************************************************************************************
181 
182      generate_adpcm -- general ADPCM decoding routine
183 
184 ***********************************************************************************************/
185 
generate_adpcm(struct YMZ280BVoice * voice,UINT8 * base,INT16 * buffer,int samples)186 static int generate_adpcm(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer, int samples)
187 {
188 	int position = voice->position;
189 	int signal = voice->signal;
190 	int step = voice->step;
191 	int val;
192 
193 	/* two cases: first cases is non-looping */
194 	if (!voice->looping)
195 	{
196 		/* loop while we still have samples to generate */
197 		while (samples)
198 		{
199 			/* compute the new amplitude and update the current step */
200 			val = base[position / 2] >> ((~position & 1) << 2);
201 			signal += (step * diff_lookup[val & 15]) / 8;
202 
203 			/* clamp to the maximum */
204          MAME_CLAMP_SAMPLE(signal);
205 
206 			/* adjust the step size and clamp */
207 			step = (step * index_scale[val & 7]) >> 8;
208 			if (step > 0x6000)
209 				step = 0x6000;
210 			else if (step < 0x7f)
211 				step = 0x7f;
212 
213 			/* output to the buffer, scaling by the volume */
214 			*buffer++ = signal;
215 			samples--;
216 
217 			/* next! */
218 			position++;
219 			if (position >= voice->stop)
220 				break;
221 		}
222 	}
223 
224 	/* second case: looping */
225 	else
226 	{
227 		/* loop while we still have samples to generate */
228 		while (samples)
229 		{
230 			/* compute the new amplitude and update the current step */
231 			val = base[position / 2] >> ((~position & 1) << 2);
232 			signal += (step * diff_lookup[val & 15]) / 8;
233 
234 			/* clamp to the maximum */
235          MAME_CLAMP_SAMPLE(signal);
236 
237 			/* adjust the step size and clamp */
238 			step = (step * index_scale[val & 7]) >> 8;
239 			if (step > 0x6000)
240 				step = 0x6000;
241 			else if (step < 0x7f)
242 				step = 0x7f;
243 
244 			/* output to the buffer, scaling by the volume */
245 			*buffer++ = signal;
246 			samples--;
247 
248 			/* next! */
249 			position++;
250 			if (position == voice->loop_start && voice->loop_count == 0)
251 			{
252 				voice->loop_signal = signal;
253 				voice->loop_step = step;
254 			}
255 			if (position >= voice->loop_end)
256 			{
257 				if (voice->keyon)
258 				{
259 					position = voice->loop_start;
260 					signal = voice->loop_signal;
261 					step = voice->loop_step;
262 					voice->loop_count++;
263 				}
264 			}
265 			if (position >= voice->stop)
266 				break;
267 		}
268 	}
269 
270 	/* update the parameters */
271 	voice->position = position;
272 	voice->signal = signal;
273 	voice->step = step;
274 
275 	return samples;
276 }
277 
278 
279 
280 /**********************************************************************************************
281 
282      generate_pcm8 -- general 8-bit PCM decoding routine
283 
284 ***********************************************************************************************/
285 
generate_pcm8(struct YMZ280BVoice * voice,UINT8 * base,INT16 * buffer,int samples)286 static int generate_pcm8(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer, int samples)
287 {
288 	int position = voice->position;
289 	int val;
290 
291 	/* two cases: first cases is non-looping */
292 	if (!voice->looping)
293 	{
294 		/* loop while we still have samples to generate */
295 		while (samples)
296 		{
297 			/* fetch the current value */
298 			val = base[position / 2];
299 
300 			/* output to the buffer, scaling by the volume */
301 			*buffer++ = (INT8)val * 256;
302 			samples--;
303 
304 			/* next! */
305 			position += 2;
306 			if (position >= voice->stop)
307 				break;
308 		}
309 	}
310 
311 	/* second case: looping */
312 	else
313 	{
314 		/* loop while we still have samples to generate */
315 		while (samples)
316 		{
317 			/* fetch the current value */
318 			val = base[position / 2];
319 
320 			/* output to the buffer, scaling by the volume */
321 			*buffer++ = (INT8)val * 256;
322 			samples--;
323 
324 			/* next! */
325 			position += 2;
326 			if (position >= voice->loop_end)
327 			{
328 				if (voice->keyon)
329 					position = voice->loop_start;
330 			}
331 			if (position >= voice->stop)
332 				break;
333 		}
334 	}
335 
336 	/* update the parameters */
337 	voice->position = position;
338 
339 	return samples;
340 }
341 
342 
343 
344 /**********************************************************************************************
345 
346      generate_pcm16 -- general 16-bit PCM decoding routine
347 
348 ***********************************************************************************************/
349 
generate_pcm16(struct YMZ280BVoice * voice,UINT8 * base,INT16 * buffer,int samples)350 static int generate_pcm16(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer, int samples)
351 {
352 	int position = voice->position;
353 	int val;
354 
355 	/* two cases: first cases is non-looping */
356 	if (!voice->looping)
357 	{
358 		/* loop while we still have samples to generate */
359 		while (samples)
360 		{
361 			/* fetch the current value */
362 			val = (INT16)((base[position / 2 + 1] << 8) + base[position / 2]);
363 
364 			/* output to the buffer, scaling by the volume */
365 			*buffer++ = val;
366 			samples--;
367 
368 			/* next! */
369 			position += 4;
370 			if (position >= voice->stop)
371 				break;
372 		}
373 	}
374 
375 	/* second case: looping */
376 	else
377 	{
378 		/* loop while we still have samples to generate */
379 		while (samples)
380 		{
381 			/* fetch the current value */
382 			val = (INT16)((base[position / 2 + 1] << 8) + base[position / 2]);
383 
384 			/* output to the buffer, scaling by the volume */
385 			*buffer++ = val;
386 			samples--;
387 
388 			/* next! */
389 			position += 4;
390 			if (position >= voice->loop_end)
391 			{
392 				if (voice->keyon)
393 					position = voice->loop_start;
394 			}
395 			if (position >= voice->stop)
396 				break;
397 		}
398 	}
399 
400 	/* update the parameters */
401 	voice->position = position;
402 
403 	return samples;
404 }
405 
406 
407 
408 /**********************************************************************************************
409 
410      ymz280b_update -- update the sound chip so that it is in sync with CPU execution
411 
412 ***********************************************************************************************/
413 
ymz280b_update(int num,INT16 ** buffer,int length)414 static void ymz280b_update(int num, INT16 **buffer, int length)
415 {
416 	struct YMZ280BChip *chip = &ymz280b[num];
417 	INT32 *lacc = accumulator;
418 	INT32 *racc = accumulator + length;
419 	int v;
420 
421 	/* clear out the accumulator */
422 	memset(accumulator, 0, 2 * length * sizeof(accumulator[0]));
423 
424 	/* loop over voices */
425 	for (v = 0; v < 8; v++)
426 	{
427 		struct YMZ280BVoice *voice = &chip->voice[v];
428 		INT16 prev = voice->last_sample;
429 		INT16 curr = voice->curr_sample;
430 		INT16 *curr_data = scratch;
431 		INT32 *ldest = lacc;
432 		INT32 *rdest = racc;
433 		UINT32 new_samples, samples_left;
434 		UINT32 final_pos;
435 		int remaining = length;
436 		int lvol = voice->output_left;
437 		int rvol = voice->output_right;
438 
439 		/* quick out if we're not playing and we're at 0 */
440 		if (!voice->playing && curr == 0)
441 			continue;
442 
443 		/* finish off the current sample */
444 		if (voice->output_pos > 0)
445 		{
446 			/* interpolate */
447 			while (remaining > 0 && voice->output_pos < FRAC_ONE)
448 			{
449 				int interp_sample = (((INT32)prev * (FRAC_ONE - voice->output_pos)) + ((INT32)curr * voice->output_pos)) >> FRAC_BITS;
450 				*ldest++ += interp_sample * lvol;
451 				*rdest++ += interp_sample * rvol;
452 				voice->output_pos += voice->output_step;
453 				remaining--;
454 			}
455 
456 			/* if we're over, continue; otherwise, we're done */
457 			if (voice->output_pos >= FRAC_ONE)
458 				voice->output_pos -= FRAC_ONE;
459 			else
460 				continue;
461 		}
462 
463 		/* compute how many new samples we need */
464 		final_pos = voice->output_pos + remaining * voice->output_step;
465 		new_samples = (final_pos + FRAC_ONE) >> FRAC_BITS;
466 		if (new_samples > MAX_SAMPLE_CHUNK)
467 			new_samples = MAX_SAMPLE_CHUNK;
468 		samples_left = new_samples;
469 
470 		/* generate them into our buffer */
471 		if (voice->playing)
472 		{
473 			switch (voice->mode)
474 			{
475 				case 1:	samples_left = generate_adpcm(voice, chip->region_base, scratch, new_samples);	break;
476 				case 2:	samples_left = generate_pcm8(voice, chip->region_base, scratch, new_samples);	break;
477 				case 3:	samples_left = generate_pcm16(voice, chip->region_base, scratch, new_samples);	break;
478 				default:
479 				case 0:	samples_left = 0; memset(scratch, 0, new_samples * sizeof(scratch[0]));			break;
480 			}
481 		}
482 
483 		/* if there are leftovers, ramp back to 0 */
484 		if (samples_left)
485 		{
486 			int base = new_samples - samples_left;
487 			int i, t = (base == 0) ? curr : scratch[base - 1];
488 			for (i = 0; i < samples_left; i++)
489 			{
490 				if (t < 0) t = -((-t * 15) >> 4);
491 				else if (t > 0) t = (t * 15) >> 4;
492 				scratch[base + i] = t;
493 			}
494 
495 			/* if we hit the end and IRQs are enabled, signal it */
496 			if (base != 0)
497 			{
498 				voice->playing = 0;
499 				chip->status_register |= 1 << v;
500 				update_irq_state(chip);
501 			}
502 		}
503 
504 		/* advance forward one sample */
505 		prev = curr;
506 		curr = *curr_data++;
507 
508 		/* then sample-rate convert with linear interpolation */
509 		while (remaining > 0)
510 		{
511 			/* interpolate */
512 			while (remaining > 0 && voice->output_pos < FRAC_ONE)
513 			{
514 				int interp_sample = (((INT32)prev * (FRAC_ONE - voice->output_pos)) + ((INT32)curr * voice->output_pos)) >> FRAC_BITS;
515 				*ldest++ += interp_sample * lvol;
516 				*rdest++ += interp_sample * rvol;
517 				voice->output_pos += voice->output_step;
518 				remaining--;
519 			}
520 
521 			/* if we're over, grab the next samples */
522 			if (voice->output_pos >= FRAC_ONE)
523 			{
524 				voice->output_pos -= FRAC_ONE;
525 				prev = curr;
526 				curr = *curr_data++;
527 			}
528 		}
529 
530 		/* remember the last samples */
531 		voice->last_sample = prev;
532 		voice->curr_sample = curr;
533 	}
534 
535 	/* mix and clip the result */
536 	for (v = 0; v < length; v++)
537 	{
538 		int lsamp = lacc[v] / 256;
539 		int rsamp = racc[v] / 256;
540 
541       MAME_CLAMP_SAMPLE(lsamp);
542       MAME_CLAMP_SAMPLE(rsamp);
543 
544 		buffer[0][v] = lsamp;
545 		buffer[1][v] = rsamp;
546 	}
547 
548 #if MAKE_WAVS
549 	/* log the resampled data */
550 	if (chip->wavresample)
551 		wav_add_data_16lr(chip->wavresample, buffer[0], buffer[1], length);
552 #endif
553 }
554 
555 
556 //ks s
557 static int chip_num;
YMZ280B_state_save_update_step(void)558 static void YMZ280B_state_save_update_step(void)
559 {
560 	int i,j;
561 	for (i = 0; i < chip_num; i++)
562 	{
563 		for (j = 0; j < 8; j++)
564 		{
565 			struct YMZ280BChip *chip = &ymz280b[i];
566 			struct YMZ280BVoice *voice = &chip->voice[j];
567 			update_step(chip, voice);
568 		}
569 	}
570 }
571 //ks e
572 /**********************************************************************************************
573 
574      YMZ280B_sh_start -- start emulation of the YMZ280B
575 
576 ***********************************************************************************************/
577 
YMZ280B_sh_start(const struct MachineSound * msound)578 int YMZ280B_sh_start(const struct MachineSound *msound)
579 {
580 	const struct YMZ280Binterface *intf = msound->sound_interface;
581 	char stream_name[2][40];
582 	const char *stream_name_ptrs[2];
583 	int vol[2];
584 	int i;
585 
586 	/* compute ADPCM tables */
587 	compute_tables();
588 
589 	/* initialize the voices */
590 	memset(&ymz280b, 0, sizeof(ymz280b));
591 	for (i = 0; i < intf->num; i++)
592 	{
593 		/* generate the name and create the stream */
594 		sprintf(stream_name[0], "%s #%d Ch1", sound_name(msound), i);
595 		sprintf(stream_name[1], "%s #%d Ch2", sound_name(msound), i);
596 		stream_name_ptrs[0] = stream_name[0];
597 		stream_name_ptrs[1] = stream_name[1];
598 
599 		/* set the volumes */
600 		vol[0] = intf->mixing_level[i] & 0xffff;
601 		vol[1] = intf->mixing_level[i] >> 16;
602 
603 		/* create the stream */
604 		ymz280b[i].stream = stream_init_multi(2, stream_name_ptrs, vol, Machine->sample_rate, i, ymz280b_update);
605 		if (ymz280b[i].stream == -1)
606 			return 1;
607 
608 		/* initialize the rest of the structure */
609 		ymz280b[i].master_clock = (double)intf->baseclock[i] / 384.0;
610 		ymz280b[i].region_base = memory_region(intf->region[i]);
611 		ymz280b[i].irq_callback = intf->irq_callback[i];
612 	}
613 
614 	/* allocate memory */
615 	accumulator = malloc(sizeof(accumulator[0]) * 2 * MAX_SAMPLE_CHUNK);
616 	scratch = malloc(sizeof(scratch[0]) * MAX_SAMPLE_CHUNK);
617 	if (!accumulator || !scratch)
618 		return 1;
619 
620 //ks s
621 	/* state save */
622 	for (i = 0; i < intf->num; i++)
623 	{
624 		int j;
625 		state_save_register_UINT8("YMZ280B", i, "current_register", &ymz280b[i].current_register,1);
626 		state_save_register_UINT8("YMZ280B", i, "status_register", &ymz280b[i].status_register,1);
627 		state_save_register_UINT8("YMZ280B", i, "irq_state", &ymz280b[i].irq_state,1);
628 		state_save_register_UINT8("YMZ280B", i, "irq_mask", &ymz280b[i].irq_mask,1);
629 		state_save_register_UINT8("YMZ280B", i, "irq_enable", &ymz280b[i].irq_enable,1);
630 		state_save_register_UINT8("YMZ280B", i, "keyon_enable", &ymz280b[i].keyon_enable,1);
631 		for (j = 0; j < 8; j++)
632 		{
633 			state_save_register_UINT8 ("YMZ280B.voice", i*8+j, "playing", &ymz280b[i].voice[j].playing,1);
634 			state_save_register_UINT8 ("YMZ280B.voice", i*8+j, "keyon", &ymz280b[i].voice[j].keyon,1);
635 			state_save_register_UINT8 ("YMZ280B.voice", i*8+j, "looping", &ymz280b[i].voice[j].looping,1);
636 			state_save_register_UINT8 ("YMZ280B.voice", i*8+j, "mode", &ymz280b[i].voice[j].mode,1);
637 			state_save_register_UINT16 ("YMZ280B.voice", i*8+j, "fnum", &ymz280b[i].voice[j].fnum,1);
638 			state_save_register_UINT8 ("YMZ280B.voice", i*8+j, "level", &ymz280b[i].voice[j].level,1);
639 			state_save_register_UINT8 ("YMZ280B.voice", i*8+j, "pan", &ymz280b[i].voice[j].pan,1);
640 			state_save_register_UINT32 ("YMZ280B.voice", i*8+j, "start", &ymz280b[i].voice[j].start,1);
641 			state_save_register_UINT32 ("YMZ280B.voice", i*8+j, "stop", &ymz280b[i].voice[j].stop,1);
642 			state_save_register_UINT32 ("YMZ280B.voice", i*8+j, "loop_start", &ymz280b[i].voice[j].loop_start,1);
643 			state_save_register_UINT32 ("YMZ280B.voice", i*8+j, "loop_end", &ymz280b[i].voice[j].loop_end,1);
644 			state_save_register_UINT32 ("YMZ280B.voice", i*8+j, "position", &ymz280b[i].voice[j].position,1);
645 			state_save_register_INT32 ("YMZ280B.voice", i*8+j, "signal", &ymz280b[i].voice[j].signal,1);
646 			state_save_register_INT32 ("YMZ280B.voice", i*8+j, "step", &ymz280b[i].voice[j].step,1);
647 			state_save_register_INT32 ("YMZ280B.voice", i*8+j, "loop_signal", &ymz280b[i].voice[j].loop_signal,1);
648 			state_save_register_INT32 ("YMZ280B.voice", i*8+j, "loop_step", &ymz280b[i].voice[j].loop_step,1);
649 			state_save_register_UINT32 ("YMZ280B.voice", i*8+j, "loop_count", &ymz280b[i].voice[j].loop_count,1);
650 			state_save_register_INT32 ("YMZ280B.voice", i*8+j, "output_left", &ymz280b[i].voice[j].output_left,1);
651 			state_save_register_INT32 ("YMZ280B.voice", i*8+j, "output_right", &ymz280b[i].voice[j].output_right,1);
652 			state_save_register_INT32 ("YMZ280B.voice", i*8+j, "output_pos", &ymz280b[i].voice[j].output_pos,1);
653 			state_save_register_INT16 ("YMZ280B.voice", i*8+j, "last_sample", &ymz280b[i].voice[j].last_sample,1);
654 			state_save_register_INT16 ("YMZ280B.voice", i*8+j, "curr_sample", &ymz280b[i].voice[j].curr_sample,1);
655 		}
656 	}
657 	state_save_register_func_postload(YMZ280B_state_save_update_step);
658 	chip_num = intf->num;
659 //ks e
660 
661 #if MAKE_WAVS
662 	ymz280b[0].wavresample = wav_open("resamp.wav", Machine->sample_rate, 2);
663 #endif
664 
665 	/* success */
666 	return 0;
667 }
668 
669 
670 
671 /**********************************************************************************************
672 
673      YMZ280B_sh_stop -- stop emulation of the YMZ280B
674 
675 ***********************************************************************************************/
676 
YMZ280B_sh_stop(void)677 void YMZ280B_sh_stop(void)
678 {
679 	/* free memory */
680 	if (accumulator)
681 		free(accumulator);
682 	accumulator = NULL;
683 
684 	if (scratch)
685 		free(scratch);
686 	scratch = NULL;
687 
688 #if MAKE_WAVS
689 {
690 	int i;
691 
692 	for (i = 0; i < MAX_BSMT2000; i++)
693 	{
694 		if (ymz280b[i].wavresample)
695 			wav_close(ymz280b[i].wavresample);
696 	}
697 }
698 #endif
699 }
700 
701 
702 
703 /**********************************************************************************************
704 
705      write_to_register -- handle a write to the current register
706 
707 ***********************************************************************************************/
708 
write_to_register(struct YMZ280BChip * chip,int data)709 static void write_to_register(struct YMZ280BChip *chip, int data)
710 {
711 	struct YMZ280BVoice *voice;
712 	int i;
713 
714 	/* force an update */
715 	stream_update(chip->stream, 0);
716 
717 	/* lower registers follow a pattern */
718 	if (chip->current_register < 0x80)
719 	{
720 		voice = &chip->voice[(chip->current_register >> 2) & 7];
721 
722 		switch (chip->current_register & 0xe3)
723 		{
724 			case 0x00:		/* pitch low 8 bits */
725 				voice->fnum = (voice->fnum & 0x100) | (data & 0xff);
726 				update_step(chip, voice);
727 				break;
728 
729 			case 0x01:		/* pitch upper 1 bit, loop, key on, mode */
730 				voice->fnum = (voice->fnum & 0xff) | ((data & 0x01) << 8);
731 				voice->looping = (data & 0x10) >> 4;
732 				voice->mode = (data & 0x60) >> 5;
733 				if (!voice->keyon && (data & 0x80) && chip->keyon_enable)
734 				{
735 					voice->playing = 1;
736 					voice->position = voice->start;
737 					voice->signal = voice->loop_signal = 0;
738 					voice->step = voice->loop_step = 0x7f;
739 					voice->loop_count = 0;
740 				}
741 				if (voice->keyon && !(data & 0x80) && !voice->looping)
742 //ks start
743 				{
744 					voice->playing = 0;
745 //					chip->status_register &= ~(1 << ((chip->current_register >> 2) & 7));
746 				}
747 //ks end
748 				voice->keyon = (data & 0x80) >> 7;
749 				update_step(chip, voice);
750 				break;
751 
752 			case 0x02:		/* total level */
753 				voice->level = data;
754 				update_volumes(voice);
755 				break;
756 
757 			case 0x03:		/* pan */
758 				voice->pan = data & 0x0f;
759 				update_volumes(voice);
760 				break;
761 
762 			case 0x20:		/* start address high */
763 				voice->start = (voice->start & (0x00ffff << 1)) | (data << 17);
764 				break;
765 
766 			case 0x21:		/* loop start address high */
767 				voice->loop_start = (voice->loop_start & (0x00ffff << 1)) | (data << 17);
768 				break;
769 
770 			case 0x22:		/* loop end address high */
771 				voice->loop_end = (voice->loop_end & (0x00ffff << 1)) | (data << 17);
772 				break;
773 
774 			case 0x23:		/* stop address high */
775 				voice->stop = (voice->stop & (0x00ffff << 1)) | (data << 17);
776 				break;
777 
778 			case 0x40:		/* start address middle */
779 				voice->start = (voice->start & (0xff00ff << 1)) | (data << 9);
780 				break;
781 
782 			case 0x41:		/* loop start address middle */
783 				voice->loop_start = (voice->loop_start & (0xff00ff << 1)) | (data << 9);
784 				break;
785 
786 			case 0x42:		/* loop end address middle */
787 				voice->loop_end = (voice->loop_end & (0xff00ff << 1)) | (data << 9);
788 				break;
789 
790 			case 0x43:		/* stop address middle */
791 				voice->stop = (voice->stop & (0xff00ff << 1)) | (data << 9);
792 				break;
793 
794 			case 0x60:		/* start address low */
795 				voice->start = (voice->start & (0xffff00 << 1)) | (data << 1);
796 				break;
797 
798 			case 0x61:		/* loop start address low */
799 				voice->loop_start = (voice->loop_start & (0xffff00 << 1)) | (data << 1);
800 				break;
801 
802 			case 0x62:		/* loop end address low */
803 				voice->loop_end = (voice->loop_end & (0xffff00 << 1)) | (data << 1);
804 				break;
805 
806 			case 0x63:		/* stop address low */
807 				voice->stop = (voice->stop & (0xffff00 << 1)) | (data << 1);
808 				break;
809 
810 			default:
811 				logerror("YMZ280B: unknown register write %02X = %02X\n", chip->current_register, data);
812 				break;
813 		}
814 	}
815 
816 	/* upper registers are special */
817 	else
818 	{
819 		switch (chip->current_register)
820 		{
821 			case 0xfe:		/* IRQ mask */
822 				chip->irq_mask = data;
823 				update_irq_state(chip);
824 				break;
825 
826 			case 0xff:		/* IRQ enable, test, etc */
827 				chip->irq_enable = (data & 0x10) >> 4;
828 				update_irq_state(chip);
829 //ks start
830 				if (chip->keyon_enable && !(data & 0x80))
831 					for (i = 0; i < 8; i++)
832 						chip->voice[i].playing = 0;
833 				if (!chip->keyon_enable && (data & 0x80))
834 					for (i = 0; i < 8; i++)
835 						if (chip->voice[i].keyon && chip->voice[i].looping)
836 							chip->voice[i].playing = 1;
837 				chip->keyon_enable = (data & 0x80) >> 7;
838 //ks end
839 				break;
840 
841 			default:
842 				logerror("YMZ280B: unknown register write %02X = %02X\n", chip->current_register, data);
843 				break;
844 		}
845 	}
846 }
847 
848 
849 
850 /**********************************************************************************************
851 
852      compute_status -- determine the status bits
853 
854 ***********************************************************************************************/
855 
compute_status(struct YMZ280BChip * chip)856 static int compute_status(struct YMZ280BChip *chip)
857 {
858 	UINT8 result = chip->status_register;
859 
860 	/* force an update */
861 	stream_update(chip->stream, 0);
862 
863 	/* clear the IRQ state */
864 	chip->status_register = 0;
865 	update_irq_state(chip);
866 
867 	return result;
868 }
869 
870 
871 
872 /**********************************************************************************************
873 
874      YMZ280B_status_0_r/YMZ280B_status_1_r -- handle a read from the status register
875 
876 ***********************************************************************************************/
877 
READ_HANDLER(YMZ280B_status_0_r)878 READ_HANDLER( YMZ280B_status_0_r )
879 {
880 	return compute_status(&ymz280b[0]);
881 }
882 
READ_HANDLER(YMZ280B_status_1_r)883 READ_HANDLER( YMZ280B_status_1_r )
884 {
885 	return compute_status(&ymz280b[1]);
886 }
887 
READ16_HANDLER(YMZ280B_status_0_lsb_r)888 READ16_HANDLER( YMZ280B_status_0_lsb_r )
889 {
890 	return compute_status(&ymz280b[0]);
891 }
892 
READ16_HANDLER(YMZ280B_status_0_msb_r)893 READ16_HANDLER( YMZ280B_status_0_msb_r )
894 {
895 	return compute_status(&ymz280b[0]) << 8;
896 }
897 
READ16_HANDLER(YMZ280B_status_1_lsb_r)898 READ16_HANDLER( YMZ280B_status_1_lsb_r )
899 {
900 	return compute_status(&ymz280b[1]);
901 }
902 
READ16_HANDLER(YMZ280B_status_1_msb_r)903 READ16_HANDLER( YMZ280B_status_1_msb_r )
904 {
905 	return compute_status(&ymz280b[1]) << 8;
906 }
907 
908 /**********************************************************************************************
909 
910      YMZ280B_register_0_w/YMZ280B_register_1_w -- handle a write to the register select
911 
912 ***********************************************************************************************/
913 
WRITE_HANDLER(YMZ280B_register_0_w)914 WRITE_HANDLER( YMZ280B_register_0_w )
915 {
916 	ymz280b[0].current_register = data;
917 }
918 
WRITE_HANDLER(YMZ280B_register_1_w)919 WRITE_HANDLER( YMZ280B_register_1_w )
920 {
921 	ymz280b[1].current_register = data;
922 }
923 
WRITE16_HANDLER(YMZ280B_register_0_lsb_w)924 WRITE16_HANDLER( YMZ280B_register_0_lsb_w )
925 {
926 	if (ACCESSING_LSB)	ymz280b[0].current_register = data & 0xff;
927 }
928 
WRITE16_HANDLER(YMZ280B_register_0_msb_w)929 WRITE16_HANDLER( YMZ280B_register_0_msb_w )
930 {
931 	if (ACCESSING_MSB)	ymz280b[0].current_register = (data >> 8) & 0xff;
932 }
933 
WRITE16_HANDLER(YMZ280B_register_1_lsb_w)934 WRITE16_HANDLER( YMZ280B_register_1_lsb_w )
935 {
936 	if (ACCESSING_LSB)	ymz280b[1].current_register = data & 0xff;
937 }
938 
WRITE16_HANDLER(YMZ280B_register_1_msb_w)939 WRITE16_HANDLER( YMZ280B_register_1_msb_w )
940 {
941 	if (ACCESSING_MSB)	ymz280b[1].current_register = (data >> 8) & 0xff;
942 }
943 
944 /**********************************************************************************************
945 
946      YMZ280B_data_0_w/YMZ280B_data_1_w -- handle a write to the current register
947 
948 ***********************************************************************************************/
949 
WRITE_HANDLER(YMZ280B_data_0_w)950 WRITE_HANDLER( YMZ280B_data_0_w )
951 {
952 	write_to_register(&ymz280b[0], data);
953 }
954 
WRITE_HANDLER(YMZ280B_data_1_w)955 WRITE_HANDLER( YMZ280B_data_1_w )
956 {
957 	write_to_register(&ymz280b[1], data);
958 }
959 
WRITE16_HANDLER(YMZ280B_data_0_lsb_w)960 WRITE16_HANDLER( YMZ280B_data_0_lsb_w )
961 {
962 	if (ACCESSING_LSB)	write_to_register(&ymz280b[0], data & 0xff);
963 }
964 
WRITE16_HANDLER(YMZ280B_data_0_msb_w)965 WRITE16_HANDLER( YMZ280B_data_0_msb_w )
966 {
967 	if (ACCESSING_MSB)	write_to_register(&ymz280b[0], (data >> 8) & 0xff);
968 }
969 
WRITE16_HANDLER(YMZ280B_data_1_lsb_w)970 WRITE16_HANDLER( YMZ280B_data_1_lsb_w )
971 {
972 	if (ACCESSING_LSB)	write_to_register(&ymz280b[1], data & 0xff);
973 }
974 
WRITE16_HANDLER(YMZ280B_data_1_msb_w)975 WRITE16_HANDLER( YMZ280B_data_1_msb_w )
976 {
977 	if (ACCESSING_MSB)	write_to_register(&ymz280b[1], (data >> 8) & 0xff);
978 }
979 
980