6
YMZ280B 8-Channel PCMD8 PCM/ADPCM Decoder
8
Features as listed in LSI-4MZ280B3 data sheet:
9
Voice data stored in external memory can be played back simultaneously for up to eight voices
10
Voice data format can be selected from 4-bit ADPCM, 8-bit PCM and 16-bit PCM
11
Control of voice data external memory
12
Up to 16M bytes of ROM or SRAM (x 8 bits, access time 150ms max) can be connected
13
Continuous access is possible
14
Loop playback between selective addresses is possible
15
Voice data playback frequency control
16
4-bit ADPCM ................ 0.172 to 44.1kHz in 256 steps
17
8-bit PCM, 16-bit PCM ...... 0.172 to 88.2kHz in 512 steps
18
256 steps total level and 16 steps panpot can be set
19
Voice signal is output in stereo 16-bit 2's complement MSB-first format
28
#define MAX_SAMPLE_CHUNK 10000
32
#define FRAC_ONE (1 << FRAC_BITS)
33
#define FRAC_MASK (FRAC_ONE - 1)
35
#define INTERNAL_BUFFER_SIZE (1 << 15)
36
#define INTERNAL_SAMPLE_RATE (chip->master_clock * 2.0)
43
/* struct describing a single playing ADPCM voice */
46
UINT8 playing; /* 1 if we are actively playing */
48
UINT8 keyon; /* 1 if the key is on */
49
UINT8 looping; /* 1 if looping is enabled */
50
UINT8 mode; /* current playback mode */
51
UINT16 fnum; /* frequency */
52
UINT8 level; /* output level */
53
UINT8 pan; /* panning */
55
UINT32 start; /* start address, in nibbles */
56
UINT32 stop; /* stop address, in nibbles */
57
UINT32 loop_start; /* loop start address, in nibbles */
58
UINT32 loop_end; /* loop end address, in nibbles */
59
UINT32 position; /* current position, in nibbles */
61
INT32 signal; /* current ADPCM signal */
62
INT32 step; /* current ADPCM step */
64
INT32 loop_signal; /* signal at loop start */
65
INT32 loop_step; /* step at loop start */
66
UINT32 loop_count; /* number of loops so far */
68
INT32 output_left; /* output volume (left) */
69
INT32 output_right; /* output volume (right) */
70
INT32 output_step; /* step value for frequency conversion */
71
INT32 output_pos; /* current fractional position */
72
INT16 last_sample; /* last sample output */
73
INT16 curr_sample; /* current sample target */
74
UINT8 irq_schedule; /* 1 if the IRQ state is updated by timer */
77
typedef struct _ymz280b_state ymz280b_state;
80
sound_stream * stream; /* which stream are we using */
81
UINT8 *region_base; /* pointer to the base of the region */
82
UINT8 current_register; /* currently accessible register */
83
UINT8 status_register; /* current status register */
84
UINT8 irq_state; /* current IRQ state */
85
UINT8 irq_mask; /* current IRQ mask */
86
UINT8 irq_enable; /* current IRQ enable */
87
UINT8 keyon_enable; /* key on enable */
88
double master_clock; /* master clock frequency */
89
void (*irq_callback)(device_t *, int); /* IRQ callback */
90
struct YMZ280BVoice voice[8]; /* the 8 voices */
91
UINT32 rom_readback_addr; /* where the CPU can read the ROM */
92
devcb_resolved_read8 ext_ram_read; /* external RAM read handler */
93
devcb_resolved_write8 ext_ram_write; /* external RAM write handler */
96
void * wavresample; /* resampled waveform */
103
/* step size index shift table */
104
static const int index_scale[8] = { 0x0e6, 0x0e6, 0x0e6, 0x0e6, 0x133, 0x199, 0x200, 0x266 };
106
/* lookup table for the precomputed difference */
107
static int diff_lookup[16];
110
static TIMER_CALLBACK( update_irq_state_timer_0 );
111
static TIMER_CALLBACK( update_irq_state_timer_1 );
112
static TIMER_CALLBACK( update_irq_state_timer_2 );
113
static TIMER_CALLBACK( update_irq_state_timer_3 );
114
static TIMER_CALLBACK( update_irq_state_timer_4 );
115
static TIMER_CALLBACK( update_irq_state_timer_5 );
116
static TIMER_CALLBACK( update_irq_state_timer_6 );
117
static TIMER_CALLBACK( update_irq_state_timer_7 );
119
static const struct { timer_expired_func func; const char *name; } update_irq_state_cb[] =
121
{ FUNC(update_irq_state_timer_0) },
122
{ FUNC(update_irq_state_timer_1) },
123
{ FUNC(update_irq_state_timer_2) },
124
{ FUNC(update_irq_state_timer_3) },
125
{ FUNC(update_irq_state_timer_4) },
126
{ FUNC(update_irq_state_timer_5) },
127
{ FUNC(update_irq_state_timer_6) },
128
{ FUNC(update_irq_state_timer_7) }
132
INLINE ymz280b_state *get_safe_token(device_t *device)
134
assert(device != NULL);
135
assert(device->type() == YMZ280B);
136
return (ymz280b_state *)downcast<legacy_device_base *>(device)->token();
140
INLINE void update_irq_state(ymz280b_state *chip)
142
int irq_bits = chip->status_register & chip->irq_mask;
144
/* always off if the enable is off */
145
if (!chip->irq_enable)
148
/* update the state if changed */
149
if (irq_bits && !chip->irq_state)
152
if (chip->irq_callback)
153
(*chip->irq_callback)(chip->device, 1);
154
else logerror("YMZ280B: IRQ generated, but no callback specified!");
156
else if (!irq_bits && chip->irq_state)
159
if (chip->irq_callback)
160
(*chip->irq_callback)(chip->device, 0);
161
else logerror("YMZ280B: IRQ generated, but no callback specified!");
166
INLINE void update_step(ymz280b_state *chip, struct YMZ280BVoice *voice)
170
/* compute the frequency */
171
if (voice->mode == 1)
172
frequency = chip->master_clock * (double)((voice->fnum & 0x0ff) + 1) * (1.0 / 256.0);
174
frequency = chip->master_clock * (double)((voice->fnum & 0x1ff) + 1) * (1.0 / 256.0);
175
voice->output_step = (UINT32)(frequency * (double)FRAC_ONE / INTERNAL_SAMPLE_RATE);
179
INLINE void update_volumes(struct YMZ280BVoice *voice)
183
voice->output_left = voice->level;
184
voice->output_right = voice->level;
186
else if (voice->pan < 8)
188
voice->output_left = voice->level;
189
voice->output_right = voice->level * voice->pan / 8;
193
voice->output_left = voice->level * (15 - voice->pan) / 8;
194
voice->output_right = voice->level;
199
static void YMZ280B_state_save_update_step(ymz280b_state *chip)
202
for (j = 0; j < 8; j++)
204
struct YMZ280BVoice *voice = &chip->voice[j];
205
update_step(chip, voice);
206
if(voice->irq_schedule)
207
chip->device->machine().scheduler().timer_set(attotime::zero, update_irq_state_cb[j].func, update_irq_state_cb[j].name, 0, chip);
212
static void update_irq_state_timer_common(void *param, int voicenum)
214
ymz280b_state *chip = (ymz280b_state *)param;
215
struct YMZ280BVoice *voice = &chip->voice[voicenum];
217
if(!voice->irq_schedule) return;
220
chip->status_register |= 1 << voicenum;
221
update_irq_state(chip);
222
voice->irq_schedule = 0;
225
static TIMER_CALLBACK( update_irq_state_timer_0 ) { update_irq_state_timer_common(ptr, 0); }
226
static TIMER_CALLBACK( update_irq_state_timer_1 ) { update_irq_state_timer_common(ptr, 1); }
227
static TIMER_CALLBACK( update_irq_state_timer_2 ) { update_irq_state_timer_common(ptr, 2); }
228
static TIMER_CALLBACK( update_irq_state_timer_3 ) { update_irq_state_timer_common(ptr, 3); }
229
static TIMER_CALLBACK( update_irq_state_timer_4 ) { update_irq_state_timer_common(ptr, 4); }
230
static TIMER_CALLBACK( update_irq_state_timer_5 ) { update_irq_state_timer_common(ptr, 5); }
231
static TIMER_CALLBACK( update_irq_state_timer_6 ) { update_irq_state_timer_common(ptr, 6); }
232
static TIMER_CALLBACK( update_irq_state_timer_7 ) { update_irq_state_timer_common(ptr, 7); }
235
/**********************************************************************************************
237
compute_tables -- compute the difference tables
239
***********************************************************************************************/
241
static void compute_tables(void)
245
/* loop over all nibbles and compute the difference */
246
for (nib = 0; nib < 16; nib++)
248
int value = (nib & 0x07) * 2 + 1;
249
diff_lookup[nib] = (nib & 0x08) ? -value : value;
255
/**********************************************************************************************
257
generate_adpcm -- general ADPCM decoding routine
259
***********************************************************************************************/
261
static int generate_adpcm(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer, int samples)
263
int position = voice->position;
264
int signal = voice->signal;
265
int step = voice->step;
268
/* two cases: first cases is non-looping */
271
/* loop while we still have samples to generate */
274
/* compute the new amplitude and update the current step */
275
val = base[position / 2] >> ((~position & 1) << 2);
276
signal += (step * diff_lookup[val & 15]) / 8;
278
/* clamp to the maximum */
281
else if (signal < -32768)
284
/* adjust the step size and clamp */
285
step = (step * index_scale[val & 7]) >> 8;
288
else if (step < 0x7f)
291
/* output to the buffer, scaling by the volume */
297
if (position >= voice->stop)
302
/* second case: looping */
305
/* loop while we still have samples to generate */
308
/* compute the new amplitude and update the current step */
309
val = base[position / 2] >> ((~position & 1) << 2);
310
signal += (step * diff_lookup[val & 15]) / 8;
312
/* clamp to the maximum */
315
else if (signal < -32768)
318
/* adjust the step size and clamp */
319
step = (step * index_scale[val & 7]) >> 8;
322
else if (step < 0x7f)
325
/* output to the buffer, scaling by the volume */
331
if (position == voice->loop_start && voice->loop_count == 0)
333
voice->loop_signal = signal;
334
voice->loop_step = step;
336
if (position >= voice->loop_end)
340
position = voice->loop_start;
341
signal = voice->loop_signal;
342
step = voice->loop_step;
346
if (position >= voice->stop)
351
/* update the parameters */
352
voice->position = position;
353
voice->signal = signal;
361
/**********************************************************************************************
363
generate_pcm8 -- general 8-bit PCM decoding routine
365
***********************************************************************************************/
367
static int generate_pcm8(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer, int samples)
369
int position = voice->position;
372
/* two cases: first cases is non-looping */
375
/* loop while we still have samples to generate */
378
/* fetch the current value */
379
val = base[position / 2];
381
/* output to the buffer, scaling by the volume */
382
*buffer++ = (INT8)val * 256;
387
if (position >= voice->stop)
392
/* second case: looping */
395
/* loop while we still have samples to generate */
398
/* fetch the current value */
399
val = base[position / 2];
401
/* output to the buffer, scaling by the volume */
402
*buffer++ = (INT8)val * 256;
407
if (position >= voice->loop_end)
410
position = voice->loop_start;
412
if (position >= voice->stop)
417
/* update the parameters */
418
voice->position = position;
425
/**********************************************************************************************
427
generate_pcm16 -- general 16-bit PCM decoding routine
429
***********************************************************************************************/
431
static int generate_pcm16(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer, int samples)
433
int position = voice->position;
436
/* two cases: first cases is non-looping */
439
/* loop while we still have samples to generate */
442
/* fetch the current value */
443
val = (INT16)((base[position / 2 + 1] << 8) + base[position / 2]);
445
/* output to the buffer, scaling by the volume */
451
if (position >= voice->stop)
456
/* second case: looping */
459
/* loop while we still have samples to generate */
462
/* fetch the current value */
463
val = (INT16)((base[position / 2 + 1] << 8) + base[position / 2]);
465
/* output to the buffer, scaling by the volume */
471
if (position >= voice->loop_end)
474
position = voice->loop_start;
476
if (position >= voice->stop)
481
/* update the parameters */
482
voice->position = position;
489
/**********************************************************************************************
491
ymz280b_update -- update the sound chip so that it is in sync with CPU execution
493
***********************************************************************************************/
495
static STREAM_UPDATE( ymz280b_update )
497
ymz280b_state *chip = (ymz280b_state *)param;
498
stream_sample_t *lacc = outputs[0];
499
stream_sample_t *racc = outputs[1];
502
/* clear out the accumulator */
503
memset(lacc, 0, samples * sizeof(lacc[0]));
504
memset(racc, 0, samples * sizeof(racc[0]));
506
/* loop over voices */
507
for (v = 0; v < 8; v++)
509
struct YMZ280BVoice *voice = &chip->voice[v];
510
INT16 prev = voice->last_sample;
511
INT16 curr = voice->curr_sample;
512
INT16 *curr_data = chip->scratch;
515
UINT32 new_samples, samples_left;
517
int remaining = samples;
518
int lvol = voice->output_left;
519
int rvol = voice->output_right;
521
/* quick out if we're not playing and we're at 0 */
522
if (!voice->playing && curr == 0)
525
/* finish off the current sample */
526
// if (voice->output_pos > 0)
529
while (remaining > 0 && voice->output_pos < FRAC_ONE)
531
int interp_sample = (((INT32)prev * (FRAC_ONE - voice->output_pos)) + ((INT32)curr * voice->output_pos)) >> FRAC_BITS;
532
*ldest++ += interp_sample * lvol;
533
*rdest++ += interp_sample * rvol;
534
voice->output_pos += voice->output_step;
538
/* if we're over, continue; otherwise, we're done */
539
if (voice->output_pos >= FRAC_ONE)
540
voice->output_pos -= FRAC_ONE;
545
/* compute how many new samples we need */
546
final_pos = voice->output_pos + remaining * voice->output_step;
547
new_samples = (final_pos + FRAC_ONE) >> FRAC_BITS;
548
if (new_samples > MAX_SAMPLE_CHUNK)
549
new_samples = MAX_SAMPLE_CHUNK;
550
samples_left = new_samples;
552
/* generate them into our buffer */
557
case 1: samples_left = generate_adpcm(voice, chip->region_base, chip->scratch, new_samples); break;
558
case 2: samples_left = generate_pcm8(voice, chip->region_base, chip->scratch, new_samples); break;
559
case 3: samples_left = generate_pcm16(voice, chip->region_base, chip->scratch, new_samples); break;
561
case 0: samples_left = 0; memset(chip->scratch, 0, new_samples * sizeof(chip->scratch[0])); break;
565
/* if there are leftovers, ramp back to 0 */
568
int base = new_samples - samples_left;
569
int i, t = (base == 0) ? curr : chip->scratch[base - 1];
570
for (i = 0; i < samples_left; i++)
572
if (t < 0) t = -((-t * 15) >> 4);
573
else if (t > 0) t = (t * 15) >> 4;
574
chip->scratch[base + i] = t;
577
/* if we hit the end and IRQs are enabled, signal it */
582
/* set update_irq_state_timer. IRQ is signaled on next CPU execution. */
583
chip->device->machine().scheduler().timer_set(attotime::zero, update_irq_state_cb[v].func, update_irq_state_cb[v].name, 0, chip);
584
voice->irq_schedule = 1;
588
/* advance forward one sample */
592
/* then sample-rate convert with linear interpolation */
593
while (remaining > 0)
596
while (remaining > 0 && voice->output_pos < FRAC_ONE)
598
int interp_sample = (((INT32)prev * (FRAC_ONE - voice->output_pos)) + ((INT32)curr * voice->output_pos)) >> FRAC_BITS;
599
*ldest++ += interp_sample * lvol;
600
*rdest++ += interp_sample * rvol;
601
voice->output_pos += voice->output_step;
605
/* if we're over, grab the next samples */
606
if (voice->output_pos >= FRAC_ONE)
608
voice->output_pos -= FRAC_ONE;
614
/* remember the last samples */
615
voice->last_sample = prev;
616
voice->curr_sample = curr;
619
for (v = 0; v < samples; v++)
621
outputs[0][v] /= 256;
622
outputs[1][v] /= 256;
628
/**********************************************************************************************
630
DEVICE_START( ymz280b ) -- start emulation of the YMZ280B
632
***********************************************************************************************/
634
static DEVICE_START( ymz280b )
636
static const ymz280b_interface defintrf = { 0 };
637
const ymz280b_interface *intf = (device->static_config() != NULL) ? (const ymz280b_interface *)device->static_config() : &defintrf;
638
ymz280b_state *chip = get_safe_token(device);
640
chip->device = device;
641
chip->ext_ram_read.resolve(intf->ext_read, *device);
642
chip->ext_ram_write.resolve(intf->ext_write, *device);
644
/* compute ADPCM tables */
647
/* initialize the rest of the structure */
648
chip->master_clock = (double)device->clock() / 384.0;
649
chip->region_base = *device->region();
650
chip->irq_callback = intf->irq_callback;
652
/* create the stream */
653
chip->stream = device->machine().sound().stream_alloc(*device, 0, 2, INTERNAL_SAMPLE_RATE, chip, ymz280b_update);
655
/* allocate memory */
656
chip->scratch = auto_alloc_array(device->machine(), INT16, MAX_SAMPLE_CHUNK);
661
device->save_item(NAME(chip->current_register));
662
device->save_item(NAME(chip->status_register));
663
device->save_item(NAME(chip->irq_state));
664
device->save_item(NAME(chip->irq_mask));
665
device->save_item(NAME(chip->irq_enable));
666
device->save_item(NAME(chip->keyon_enable));
667
device->save_item(NAME(chip->rom_readback_addr));
668
for (j = 0; j < 8; j++)
670
device->save_item(NAME(chip->voice[j].playing), j);
671
device->save_item(NAME(chip->voice[j].keyon), j);
672
device->save_item(NAME(chip->voice[j].looping), j);
673
device->save_item(NAME(chip->voice[j].mode), j);
674
device->save_item(NAME(chip->voice[j].fnum), j);
675
device->save_item(NAME(chip->voice[j].level), j);
676
device->save_item(NAME(chip->voice[j].pan), j);
677
device->save_item(NAME(chip->voice[j].start), j);
678
device->save_item(NAME(chip->voice[j].stop), j);
679
device->save_item(NAME(chip->voice[j].loop_start), j);
680
device->save_item(NAME(chip->voice[j].loop_end), j);
681
device->save_item(NAME(chip->voice[j].position), j);
682
device->save_item(NAME(chip->voice[j].signal), j);
683
device->save_item(NAME(chip->voice[j].step), j);
684
device->save_item(NAME(chip->voice[j].loop_signal), j);
685
device->save_item(NAME(chip->voice[j].loop_step), j);
686
device->save_item(NAME(chip->voice[j].loop_count), j);
687
device->save_item(NAME(chip->voice[j].output_left), j);
688
device->save_item(NAME(chip->voice[j].output_right), j);
689
device->save_item(NAME(chip->voice[j].output_pos), j);
690
device->save_item(NAME(chip->voice[j].last_sample), j);
691
device->save_item(NAME(chip->voice[j].curr_sample), j);
692
device->save_item(NAME(chip->voice[j].irq_schedule), j);
696
device->machine().save().register_postload(save_prepost_delegate(FUNC(YMZ280B_state_save_update_step), chip));
699
chip->wavresample = wav_open("resamp.wav", INTERNAL_SAMPLE_RATE, 2);
705
/**********************************************************************************************
707
write_to_register -- handle a write to the current register
709
***********************************************************************************************/
711
static void write_to_register(ymz280b_state *chip, int data)
713
struct YMZ280BVoice *voice;
716
/* force an update */
717
chip->stream->update();
719
/* lower registers follow a pattern */
720
if (chip->current_register < 0x80)
722
voice = &chip->voice[(chip->current_register >> 2) & 7];
724
switch (chip->current_register & 0xe3)
726
case 0x00: /* pitch low 8 bits */
727
voice->fnum = (voice->fnum & 0x100) | (data & 0xff);
728
update_step(chip, voice);
731
case 0x01: /* pitch upper 1 bit, loop, key on, mode */
732
voice->fnum = (voice->fnum & 0xff) | ((data & 0x01) << 8);
733
voice->looping = (data & 0x10) >> 4;
734
voice->mode = (data & 0x60) >> 5;
735
if (!voice->keyon && (data & 0x80) && chip->keyon_enable)
738
voice->position = voice->start;
739
voice->signal = voice->loop_signal = 0;
740
voice->step = voice->loop_step = 0x7f;
741
voice->loop_count = 0;
743
/* if update_irq_state_timer is set, cancel it. */
744
voice->irq_schedule = 0;
746
if (voice->keyon && !(data & 0x80) && !voice->looping)
750
/* if update_irq_state_timer is set, cancel it. */
751
voice->irq_schedule = 0;
753
voice->keyon = (data & 0x80) >> 7;
754
update_step(chip, voice);
757
case 0x02: /* total level */
759
update_volumes(voice);
763
voice->pan = data & 0x0f;
764
update_volumes(voice);
767
case 0x20: /* start address high */
768
voice->start = (voice->start & (0x00ffff << 1)) | (data << 17);
771
case 0x21: /* loop start address high */
772
voice->loop_start = (voice->loop_start & (0x00ffff << 1)) | (data << 17);
775
case 0x22: /* loop end address high */
776
voice->loop_end = (voice->loop_end & (0x00ffff << 1)) | (data << 17);
779
case 0x23: /* stop address high */
780
voice->stop = (voice->stop & (0x00ffff << 1)) | (data << 17);
783
case 0x40: /* start address middle */
784
voice->start = (voice->start & (0xff00ff << 1)) | (data << 9);
787
case 0x41: /* loop start address middle */
788
voice->loop_start = (voice->loop_start & (0xff00ff << 1)) | (data << 9);
791
case 0x42: /* loop end address middle */
792
voice->loop_end = (voice->loop_end & (0xff00ff << 1)) | (data << 9);
795
case 0x43: /* stop address middle */
796
voice->stop = (voice->stop & (0xff00ff << 1)) | (data << 9);
799
case 0x60: /* start address low */
800
voice->start = (voice->start & (0xffff00 << 1)) | (data << 1);
803
case 0x61: /* loop start address low */
804
voice->loop_start = (voice->loop_start & (0xffff00 << 1)) | (data << 1);
807
case 0x62: /* loop end address low */
808
voice->loop_end = (voice->loop_end & (0xffff00 << 1)) | (data << 1);
811
case 0x63: /* stop address low */
812
voice->stop = (voice->stop & (0xffff00 << 1)) | (data << 1);
816
logerror("YMZ280B: unknown register write %02X = %02X\n", chip->current_register, data);
821
/* upper registers are special */
824
switch (chip->current_register)
826
case 0x84: /* ROM readback / RAM write (high) */
827
chip->rom_readback_addr &= 0xffff;
828
chip->rom_readback_addr |= (data<<16);
831
case 0x85: /* ROM readback / RAM write (med) */
832
chip->rom_readback_addr &= 0xff00ff;
833
chip->rom_readback_addr |= (data<<8);
836
case 0x86: /* ROM readback / RAM write (low) */
837
chip->rom_readback_addr &= 0xffff00;
838
chip->rom_readback_addr |= data;
841
case 0x87: /* RAM write */
842
if (!chip->ext_ram_write.isnull())
843
chip->ext_ram_write(chip->rom_readback_addr, data);
845
logerror("YMZ280B attempted RAM write to %X\n", chip->rom_readback_addr);
848
case 0xfe: /* IRQ mask */
849
chip->irq_mask = data;
850
update_irq_state(chip);
853
case 0xff: /* IRQ enable, test, etc */
854
chip->irq_enable = (data & 0x10) >> 4;
855
update_irq_state(chip);
857
if (chip->keyon_enable && !(data & 0x80))
859
for (i = 0; i < 8; i++)
861
chip->voice[i].playing = 0;
863
/* if update_irq_state_timer is set, cancel it. */
864
chip->voice[i].irq_schedule = 0;
867
else if (!chip->keyon_enable && (data & 0x80))
869
for (i = 0; i < 8; i++)
871
if (chip->voice[i].keyon && chip->voice[i].looping)
872
chip->voice[i].playing = 1;
875
chip->keyon_enable = (data & 0x80) >> 7;
879
logerror("YMZ280B: unknown register write %02X = %02X\n", chip->current_register, data);
887
/**********************************************************************************************
889
compute_status -- determine the status bits
891
***********************************************************************************************/
893
static int compute_status(ymz280b_state *chip)
897
/* ROM/RAM readback? */
898
if (chip->current_register == 0x86)
900
return chip->region_base[chip->rom_readback_addr];
903
/* force an update */
904
chip->stream->update();
906
result = chip->status_register;
908
/* clear the IRQ state */
909
chip->status_register = 0;
910
update_irq_state(chip);
917
/**********************************************************************************************
919
ymz280b_status_0_r/ymz280b_status_1_r -- handle a read from the status register
921
***********************************************************************************************/
923
READ8_DEVICE_HANDLER( ymz280b_r )
925
ymz280b_state *chip = get_safe_token(device);
927
if ((offset & 1) == 0)
928
return chip->ext_ram_read(chip->rom_readback_addr++ - 1);
930
return compute_status(chip);
934
WRITE8_DEVICE_HANDLER( ymz280b_w )
936
ymz280b_state *chip = get_safe_token(device);
938
if ((offset & 1) == 0)
939
chip->current_register = data;
941
write_to_register(chip, data);
946
/**************************************************************************
948
**************************************************************************/
950
DEVICE_GET_INFO( ymz280b )
954
/* --- the following bits of info are returned as 64-bit signed integers --- */
955
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(ymz280b_state); break;
957
/* --- the following bits of info are returned as pointers to data or functions --- */
958
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( ymz280b ); break;
959
case DEVINFO_FCT_STOP: /* Nothing */ break;
960
case DEVINFO_FCT_RESET: /* Nothing */ break;
962
/* --- the following bits of info are returned as NULL-terminated strings --- */
963
case DEVINFO_STR_NAME: strcpy(info->s, "YMZ280B"); break;
964
case DEVINFO_STR_FAMILY: strcpy(info->s, "Yamaha Wavetable"); break;
965
case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
966
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
967
case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
972
DEFINE_LEGACY_SOUND_DEVICE(YMZ280B, ymz280b);