2 Nintendo Family BASIC Emulator 'eFamilyBASIC'
5 Author : Takeda.Toshiya
14 //#define APU_USE_QUEUE
16 #define APU_BASEFREQ 1789772.5
17 #define APU_TO_FIXED(x) ((x) << 16)
18 #define APU_FROM_FIXED(x) ((x) >> 16)
20 static const uint8 vbl_length[32] = {
38 static const int freq_limit[8] = {
39 0x3ff, 0x555, 0x666, 0x71c, 0x787, 0x7c1, 0x7e0, 0x7f0
41 static const int noise_freq[16] = {
42 4, 8, 16, 32, 64, 96, 128, 160, 202, 254, 380, 508, 762, 1016, 2034, 4068
44 static const int dmc_clocks[16] = {
45 428, 380, 340, 320, 286, 254, 226, 214, 190, 160, 142, 128, 106, 85, 72, 54
47 static const int duty_lut[4] = {
53 int32 APU::create_rectangle(rectangle_t *chan)
56 double total, sample_weight;
58 if(!chan->enabled || chan->vbl_length <= 0) {
59 return chan->output_vol;
64 chan->vbl_length -= count_rate;
67 // envelope decay at a rate of (env_delay + 1) / 240 secs
68 chan->env_phase -= 4 * count_rate;
69 while(chan->env_phase < 0) {
70 chan->env_phase += chan->env_delay;
72 chan->env_vol = (chan->env_vol + 1) & 0x0f;
73 } else if(chan->env_vol < 0x0f) {
77 if(chan->freq < 8 || (!chan->sweep_inc && chan->freq > chan->freq_limit)) {
78 return chan->output_vol;
81 // frequency sweeping at a rate of (sweep_delay + 1) / 120 secs
82 if(chan->sweep_on && chan->sweep_shifts) {
83 chan->sweep_phase -= 2 * count_rate;
84 while(chan->sweep_phase < 0) {
85 chan->sweep_phase += chan->sweep_delay;
87 if(chan->sweep_complement) {
88 chan->freq += ~(chan->freq >> chan->sweep_shifts);
90 chan->freq -= (chan->freq >> chan->sweep_shifts);
93 chan->freq += (chan->freq >> chan->sweep_shifts);
98 if(chan->fixed_envelope) {
99 output = chan->volume << 8; // fixed volume
101 output = (chan->env_vol ^ 0x0f) << 8;
103 sample_weight = chan->phaseacc;
104 if(sample_weight > cycle_rate) {
105 sample_weight = cycle_rate;
107 total = (chan->adder < chan->duty_flip) ? sample_weight : -sample_weight;
109 chan->phaseacc -= cycle_rate; // number of cycles per sample
110 while(chan->phaseacc < 0) {
111 chan->phaseacc += APU_TO_FIXED(chan->freq + 1);
112 chan->adder = (chan->adder + 1) & 0x0f;
113 sample_weight = APU_TO_FIXED(chan->freq + 1);
114 if(chan->phaseacc > 0) {
115 sample_weight -= chan->phaseacc;
117 total += (chan->adder < chan->duty_flip) ? sample_weight : -sample_weight;
119 chan->output_vol = (int)floor(output * total / cycle_rate + 0.5);
121 return chan->output_vol;
126 int32 APU::create_triangle(triangle_t *chan)
128 double sample_weight, total;
130 if(!chan->enabled || chan->vbl_length <= 0) {
131 return ((chan->output_vol * 21) >> 4);
133 if(chan->counter_started) {
134 if(chan->linear_length > 0) {
135 chan->linear_length -= 4 * count_rate;
137 if(chan->vbl_length > 0 && !chan->holdnote) {
138 chan->vbl_length -= count_rate;
140 } else if(!chan->holdnote && chan->write_latency) {
141 if(--chan->write_latency == 0) {
142 chan->counter_started = true;
145 if(chan->linear_length <= 0 || chan->freq < APU_TO_FIXED(4)) {
146 return ((chan->output_vol * 21) >> 4);
149 sample_weight = chan->phaseacc;
150 if(sample_weight > cycle_rate) {
151 sample_weight = cycle_rate;
153 total = (((chan->adder & 0x10) ? 0x1f : 0) ^ chan->adder) * sample_weight;
155 chan->phaseacc -= cycle_rate; // number of cycles per sample
156 while(chan->phaseacc < 0) {
157 chan->phaseacc += chan->freq;
158 chan->adder = (chan->adder + 1) & 0x1f;
160 sample_weight = chan->freq;
161 if(chan->phaseacc > 0) {
162 sample_weight -= chan->phaseacc;
164 total += (((chan->adder & 0x10) ? 0x1f : 0) ^ chan->adder) * sample_weight;
166 chan->output_vol = (int)floor(total * 512 / cycle_rate + 0.5);
168 return ((chan->output_vol * 21) >> 4);
171 // white noise channel
173 int32 APU::create_noise(noise_t *chan)
177 double sample_weight;
179 if(!chan->enabled || chan->vbl_length <= 0) {
180 return ((chan->output_vol * 13) >> 4);
183 // vbl length counter
184 if(!chan->holdnote) {
185 chan->vbl_length -= count_rate;
188 // envelope decay at a rate of (env_delay + 1) / 240 secs
189 chan->env_phase -= 4 * count_rate;
190 while(chan->env_phase < 0) {
191 chan->env_phase += chan->env_delay;
193 chan->env_vol = (chan->env_vol + 1) & 0x0f;
194 } else if(chan->env_vol < 0x0f) {
199 if(chan->fixed_envelope) {
200 outvol = chan->volume << 8; // fixed volume
202 outvol = (chan->env_vol ^ 0x0f) << 8;
204 sample_weight = chan->phaseacc;
205 if(sample_weight > cycle_rate) {
206 sample_weight = cycle_rate;
208 total = chan->noise_bit ? sample_weight : -sample_weight;
210 chan->phaseacc -= cycle_rate; // number of cycles per sample
211 while(chan->phaseacc < 0) {
212 chan->phaseacc += chan->freq;
213 int bit0 = chan->shift_reg & 1;
214 int tap = (chan->shift_reg & chan->xor_tap) ? 1 : 0;
215 int bit14 = (bit0 ^ tap);
216 chan->shift_reg >>= 1;
217 chan->shift_reg |= (bit14 << 14);
218 chan->noise_bit = bit0 ^ 1;
219 sample_weight = chan->freq;
220 if(chan->phaseacc > 0) {
221 sample_weight -= chan->phaseacc;
223 total += chan->noise_bit ? sample_weight : -sample_weight;
225 chan->output_vol = (int)floor(outvol * total / cycle_rate + 0.5);
227 return ((chan->output_vol * 13) >> 4);
232 inline void APU::dmc_reload(dmc_t *chan)
234 chan->address = chan->cached_addr;
235 chan->dma_length = chan->cached_dmalength;
236 chan->irq_occurred = false;
239 int32 APU::create_dmc(dmc_t *chan)
242 double sample_weight;
245 // only process when channel is alive
246 if(chan->dma_length) {
247 sample_weight = chan->phaseacc;
248 if(sample_weight > cycle_rate) {
249 sample_weight = cycle_rate;
251 total = (chan->regs[1] << 8) * sample_weight;
252 chan->phaseacc -= cycle_rate; // number of cycles per sample
254 while(chan->phaseacc < 0) {
255 chan->phaseacc += chan->freq;
257 if(!(chan->dma_length & 7)) {
258 chan->cur_byte = d_mem->read_data8(chan->address);
261 if(chan->address == 0xffff) {
262 chan->address = 0x8000;
267 if(--chan->dma_length == 0) {
271 // check to see if we should generate an irq
273 chan->irq_occurred = true;
275 // bodge for timestamp queue
276 sample_weight = chan->freq - chan->phaseacc;
277 total += (chan->regs[1] << 8) * sample_weight;
278 while(chan->phaseacc < 0) {
279 chan->phaseacc += chan->freq;
281 chan->enabled = false;
285 delta_bit = (chan->dma_length & 7) ^ 7;
287 if(chan->cur_byte & (1 << delta_bit)) {
288 if(chan->regs[1] < 0x7d) {
292 if(chan->regs[1] > 1) {
296 sample_weight = chan->freq;
297 if(chan->phaseacc > 0) {
298 sample_weight -= chan->phaseacc;
300 total += (chan->regs[1] << 8) * sample_weight;
302 chan->output_vol = (int)floor(total / cycle_rate + 0.5);
304 chan->output_vol = chan->regs[1] << 8;
307 return ((chan->output_vol * 13) >> 4);
310 void APU::enqueue(queue_t *d)
313 q_head = (q_head + 1) & APUQUEUE_MASK;
316 APU::queue_t* APU::dequeue()
319 q_tail = (q_tail + 1) & APUQUEUE_MASK;
323 void APU::write_data_sync(uint32 addr, uint32 data)
330 chan = (addr & 4) >> 2;
331 rectangle[chan].regs[0] = data;
332 rectangle[chan].volume = data & 0x0f;
333 rectangle[chan].env_delay = decay_lut[data & 0x0f];
334 rectangle[chan].holdnote = ((data & 0x20) != 0);
335 rectangle[chan].fixed_envelope = ((data & 0x10) != 0);
336 rectangle[chan].duty_flip = duty_lut[data >> 6];
340 chan = (addr & 4) >> 2;
341 rectangle[chan].regs[1] = data;
342 rectangle[chan].sweep_on = ((data & 0x80) != 0);
343 rectangle[chan].sweep_shifts = data & 7;
344 rectangle[chan].sweep_delay = decay_lut[(data >> 4) & 7];
345 rectangle[chan].sweep_inc = ((data & 0x08) != 0);
346 rectangle[chan].freq_limit = freq_limit[data & 7];
350 chan = (addr & 4) >> 2;
351 rectangle[chan].regs[2] = data;
352 rectangle[chan].freq = (rectangle[chan].freq & ~0xff) | data;
356 chan = (addr & 4) >> 2;
357 rectangle[chan].regs[3] = data;
358 rectangle[chan].vbl_length = vbl_lut[data >> 3];
359 rectangle[chan].env_vol = 0;
360 rectangle[chan].freq = ((data & 7) << 8) | (rectangle[chan].freq & 0xff);
361 rectangle[chan].adder = 0;
362 if(enable_reg & (1 << chan)) {
363 rectangle[chan].enabled = true;
367 triangle.regs[0] = data;
368 triangle.holdnote = ((data & 0x80) != 0);
369 if(!triangle.counter_started && triangle.vbl_length > 0) {
370 triangle.linear_length = trilength_lut[data & 0x7f];
374 triangle.regs[1] = data;
375 triangle.freq = APU_TO_FIXED((((triangle.regs[2] & 7) << 8) + data) + 1);
378 triangle.regs[2] = data;
379 triangle.write_latency = (int)(228 / APU_FROM_FIXED(cycle_rate));
380 triangle.freq = APU_TO_FIXED((((data & 7) << 8) + triangle.regs[1]) + 1);
381 triangle.vbl_length = vbl_lut[data >> 3];
382 triangle.counter_started = false;
383 triangle.linear_length = trilength_lut[triangle.regs[0] & 0x7f];
384 if(enable_reg & 0x04) {
385 triangle.enabled = true;
389 noise.regs[0] = data;
390 noise.env_delay = decay_lut[data & 0x0f];
391 noise.holdnote = ((data & 0x20) != 0);
392 noise.fixed_envelope = ((data & 0x10) != 0);
393 noise.volume = data & 0x0f;
396 noise.regs[1] = data;
397 noise.freq = APU_TO_FIXED(noise_freq[data & 0x0f]);
398 noise.xor_tap = (data & 0x80) ? 0x40: 0x02;
401 noise.regs[2] = data;
402 noise.vbl_length = vbl_lut[data >> 3];
403 noise.env_vol = 0; /* reset envelope */
404 if(enable_reg & 0x08) {
405 noise.enabled = true;
410 dmc.freq = APU_TO_FIXED(dmc_clocks[data & 0x0f]);
411 dmc.looping = ((data & 0x40) != 0);
416 dmc.irq_occurred = false;
419 case 0x4011: /* 7-bit DAC */
420 data &= 0x7f; /* bit 7 ignored */
425 dmc.cached_addr = 0xc000 + (uint16) (data << 6);
429 dmc.cached_dmalength = ((data << 4) + 1) << 3;
432 // bodge for timestamp queue
433 dmc.enabled = ((data & 0x10) != 0);
435 for(chan = 0; chan < 2; chan++) {
436 if(!(data & (1 << chan))) {
437 rectangle[chan].enabled = false;
438 rectangle[chan].vbl_length = 0;
442 triangle.enabled = false;
443 triangle.vbl_length = 0;
444 triangle.linear_length = 0;
445 triangle.counter_started = false;
446 triangle.write_latency = 0;
449 noise.enabled = false;
450 noise.vbl_length = 0;
453 if(!dmc.dma_length) {
458 dmc.irq_occurred = false;
465 count_rate = (data & 0x80) ? 4 : 5;
472 void APU::write_data_cur(uint32 addr, uint32 data)
474 // for sync read $4015
480 chan = (addr & 4) >> 2;
481 rectangle[chan].holdnote_cur = ((data & 0x20) != 0);
485 chan = (addr & 4) >> 2;
486 rectangle[chan].vbl_length_cur = vbl_length[data >> 3] * 5;
487 if(enable_reg_cur & (1 << chan)) {
488 rectangle[chan].enabled_cur = true;
492 triangle.holdnote_cur = ((data & 0x80) != 0);
495 triangle.vbl_length_cur = vbl_length[data >> 3] * 5;
496 if(enable_reg_cur & 0x04) {
497 triangle.enabled_cur = true;
499 triangle.counter_started_cur = true;
502 noise.holdnote_cur = ((data & 0x20) != 0);
505 noise.vbl_length_cur = vbl_length[data >> 3] * 5;
506 if(enable_reg_cur & 0x08) {
507 noise.enabled_cur = true;
511 dmc.freq_cur = dmc_clocks[data & 0x0f];
512 dmc.phaseacc_cur = 0;
513 dmc.looping_cur = ((data & 0x40) != 0);
515 dmc.irq_gen_cur = true;
517 dmc.irq_gen_cur = false;
518 dmc.irq_occurred_cur = false;
522 dmc.cached_dmalength_cur = (data << 4) + 1;
525 enable_reg_cur = data;
526 for(chan = 0; chan < 2; chan++) {
527 if(!(data & (1 << chan))) {
528 rectangle[chan].enabled_cur = false;
529 rectangle[chan].vbl_length_cur = 0;
533 triangle.enabled_cur = false;
534 triangle.vbl_length_cur = 0;
535 triangle.counter_started_cur = false;
538 noise.enabled_cur = false;
539 noise.vbl_length_cur = 0;
542 if(!dmc.dma_length_cur) {
543 dmc.dma_length_cur = dmc.cached_dmalength_cur;
545 dmc.enabled_cur = true;
547 dmc.dma_length_cur = 0;
548 dmc.enabled_cur = false;
549 dmc.irq_occurred_cur = false;
557 void APU::initialize()
559 register_frame_event(this);
560 register_vline_event(this);
567 memset(&queue, 0, APUQUEUE_SIZE * sizeof(queue_t));
571 for(int i = 0; i < 2; i++) {
572 memset(&rectangle[i], 0, sizeof(rectangle[i]));
574 rectangle[0].sweep_complement = true;
575 rectangle[1].sweep_complement = false;
576 memset(&triangle, 0, sizeof(triangle));
577 memset(&noise, 0, sizeof(noise));
578 noise.shift_reg = 0x4000;
579 memset(&dmc, 0, sizeof(dmc));
582 for(uint32 addr = 0x4000; addr <= 0x4013; addr++) {
583 write_data_sync(addr, 0);
584 write_data_cur(addr, 0);
586 write_data_sync(0x4015, 0);
587 write_data_cur(0x4015, 0);
595 void APU::write_data8(uint32 addr, uint32 data)
599 write_data_cur(addr, data);
603 // bodge for timestamp queue
604 dmc.enabled = ((data & 0x10) != 0);
605 case 0x4000: case 0x4001: case 0x4002: case 0x4003:
606 case 0x4004: case 0x4005: case 0x4006: case 0x4007:
607 case 0x4008: case 0x4009: case 0x400a: case 0x400b:
608 case 0x400c: case 0x400d: case 0x400e: case 0x400f:
609 case 0x4010: case 0x4011: case 0x4012: case 0x4013:
611 d.timestamp = get_current_clock();
617 write_data_sync(addr, data);
623 uint32 APU::read_data8(uint32 addr)
627 // return 1 in 0-5 bit pos if a channel is playing
628 if(rectangle[0].enabled_cur && rectangle[0].vbl_length_cur > 0) {
631 if(rectangle[1].enabled_cur && rectangle[1].vbl_length_cur > 0) {
634 if(triangle.enabled_cur && triangle.vbl_length_cur > 0) {
637 if(noise.enabled_cur && noise.vbl_length_cur > 0) {
640 // bodge for timestamp queue
641 if(dmc.enabled_cur) {
644 if(dmc.irq_occurred_cur) {
652 void APU::event_frame()
654 if(!rectangle[0].holdnote_cur && rectangle[0].vbl_length_cur > 0) {
655 rectangle[0].vbl_length_cur -= count_rate;
657 if(!rectangle[1].holdnote_cur && rectangle[1].vbl_length_cur > 0) {
658 rectangle[1].vbl_length_cur -= count_rate;
660 if(triangle.counter_started_cur) {
661 if(triangle.vbl_length_cur > 0 && !triangle.holdnote_cur) {
662 triangle.vbl_length_cur -= count_rate;
665 if(!noise.holdnote_cur && noise.vbl_length_cur > 0) {
666 noise.vbl_length_cur -= count_rate;
670 void APU::event_vline(int v, int clock)
672 bool irq_occurred = false;
674 dmc.phaseacc_cur -= clock;
675 while(dmc.phaseacc_cur < 0) {
676 dmc.phaseacc_cur += dmc.freq_cur * 8;
677 if(dmc.dma_length_cur) {
678 if(--dmc.dma_length_cur == 0) {
679 if(dmc.looping_cur) {
680 dmc.dma_length_cur = dmc.cached_dmalength_cur;
681 dmc.irq_occurred_cur = false;
683 dmc.dma_length_cur = 0;
684 if(dmc.irq_gen_cur) {
685 dmc.irq_occurred_cur = true;
688 dmc.enabled_cur = false;
695 d_cpu->write_signal(SIG_CPU_IRQ, 1, 1);
699 void APU::initialize_sound(int rate, int samples)
701 cycle_rate = (int32)(APU_BASEFREQ * 65536.0 / (float)rate);
703 // lut used for enveloping and frequency sweeps
704 for(int i = 0; i < 16; i++) {
705 decay_lut[i] = (rate / 60) * (i + 1) * 5;
707 // used for note length, based on vblanks and size of audio buffer
708 for(int i = 0; i < 32; i++) {
709 vbl_lut[i] = vbl_length[i] * (rate / 60) * 5;
711 // triangle wave channel's linear length table
712 for(int i = 0; i < 128; i++) {
713 trilength_lut[i] = (rate / 60) * i * 5;
717 void APU::mix(int32* buffer, int num_samples)
719 uint32 cpu_cycles = elapsed_cycles;
721 while(num_samples--) {
724 while((q_head != q_tail) && (queue[q_tail].timestamp <= cpu_cycles)) {
725 queue_t *d = dequeue();
726 write_data_sync(d->addr, d->data);
728 cpu_cycles += APU_FROM_FIXED(cycle_rate);
731 accum += create_rectangle(&rectangle[0]);
732 accum += create_rectangle(&rectangle[1]);
733 accum += create_triangle(&triangle);
734 accum += create_noise(&noise);
735 accum += create_dmc(&dmc);
737 double delta = (max - min) / 32768.0;
747 ave += (max + min) / 2048.0;
750 *buffer++ += apply_volume(accum, volume_l); // L
751 *buffer++ += apply_volume(accum, volume_r); // R
754 // resync cycle counter
755 elapsed_cycles = get_current_clock();
758 void APU::set_volume(int ch, int decibel_l, int decibel_r)
760 volume_l = decibel_to_volume(decibel_l);
761 volume_r = decibel_to_volume(decibel_r);
764 #define STATE_VERSION 1
766 void APU::save_state(FILEIO* state_fio)
768 state_fio->FputUint32(STATE_VERSION);
769 state_fio->FputInt32(this_device_id);
771 state_fio->Fwrite(rectangle, sizeof(rectangle), 1);
772 state_fio->Fwrite(&triangle, sizeof(triangle), 1);
773 state_fio->Fwrite(&noise, sizeof(noise), 1);
774 state_fio->Fwrite(&dmc, sizeof(dmc), 1);
775 state_fio->FputUint32(enable_reg);
776 state_fio->FputUint32(enable_reg_cur);
777 state_fio->FputInt32(count_rate);
778 state_fio->Fwrite(queue, sizeof(queue), 1);
779 state_fio->FputInt32(q_head);
780 state_fio->FputInt32(q_tail);
781 state_fio->FputUint32(elapsed_cycles);
782 state_fio->FputDouble(ave);
783 state_fio->FputDouble(max);
784 state_fio->FputDouble(min);
787 bool APU::load_state(FILEIO* state_fio)
789 if(state_fio->FgetUint32() != STATE_VERSION) {
792 if(state_fio->FgetInt32() != this_device_id) {
795 state_fio->Fread(rectangle, sizeof(rectangle), 1);
796 state_fio->Fread(&triangle, sizeof(triangle), 1);
797 state_fio->Fread(&noise, sizeof(noise), 1);
798 state_fio->Fread(&dmc, sizeof(dmc), 1);
799 enable_reg = state_fio->FgetUint32();
800 enable_reg_cur = state_fio->FgetUint32();
801 count_rate = state_fio->FgetInt32();
802 state_fio->Fread(queue, sizeof(queue), 1);
803 q_head = state_fio->FgetInt32();
804 q_tail = state_fio->FgetInt32();
805 elapsed_cycles = state_fio->FgetUint32();
806 ave = state_fio->FgetDouble();
807 max = state_fio->FgetDouble();
808 min = state_fio->FgetDouble();