comparison ym2612.c @ 448:e85a107e6ec0

Fix handling of key on in YM2612 core
author Mike Pavone <pavone@retrodev.com>
date Sat, 20 Jul 2013 23:49:31 -0700
parents 7e8e179116af
children b7c3b2d22858
comparison
equal deleted inserted replaced
447:e730fc040169 448:e85a107e6ec0
160 } 160 }
161 if (!did_tbl_init) { 161 if (!did_tbl_init) {
162 //populate sine table 162 //populate sine table
163 for (int32_t i = 0; i < 512; i++) { 163 for (int32_t i = 0; i < 512; i++) {
164 double sine = sin( ((double)(i*2+1) / SINE_TABLE_SIZE) * M_PI_2 ); 164 double sine = sin( ((double)(i*2+1) / SINE_TABLE_SIZE) * M_PI_2 );
165 165
166 //table stores 4.8 fixed pointed representation of the base 2 log 166 //table stores 4.8 fixed pointed representation of the base 2 log
167 sine_table[i] = round_fixed_point(-log2(sine), 8); 167 sine_table[i] = round_fixed_point(-log2(sine), 8);
168 } 168 }
169 //populate power table 169 //populate power table
170 for (int32_t i = 0; i < POW_TABLE_SIZE; i++) { 170 for (int32_t i = 0; i < POW_TABLE_SIZE; i++) {
306 operator->envelope = 0; 306 operator->envelope = 0;
307 operator->env_phase = PHASE_DECAY; 307 operator->env_phase = PHASE_DECAY;
308 } 308 }
309 } else { 309 } else {
310 if (first_key_on) { 310 if (first_key_on) {
311 dfprintf(debug_file, "Changing op %d envelope %d by %d in %s phase\n", op, operator->envelope, envelope_inc, 311 dfprintf(debug_file, "Changing op %d envelope %d by %d in %s phase\n", op, operator->envelope, envelope_inc,
312 operator->env_phase == PHASE_SUSTAIN ? "sustain" : (operator->env_phase == PHASE_DECAY ? "decay": "release")); 312 operator->env_phase == PHASE_SUSTAIN ? "sustain" : (operator->env_phase == PHASE_DECAY ? "decay": "release"));
313 } 313 }
314 operator->envelope += envelope_inc; 314 operator->envelope += envelope_inc;
315 //clamp to max attenuation value 315 //clamp to max attenuation value
316 if (operator->envelope > MAX_ENVELOPE) { 316 if (operator->envelope > MAX_ENVELOPE) {
326 if (context->current_env_op == NUM_OPERATORS) { 326 if (context->current_env_op == NUM_OPERATORS) {
327 context->current_env_op = 0; 327 context->current_env_op = 0;
328 context->env_counter++; 328 context->env_counter++;
329 } 329 }
330 } 330 }
331 331
332 //Update Phase Generator 332 //Update Phase Generator
333 uint32_t channel = context->current_op / 4; 333 uint32_t channel = context->current_op / 4;
334 if (channel != 5 || !context->dac_enable) { 334 if (channel != 5 || !context->dac_enable) {
335 uint32_t op = context->current_op; 335 uint32_t op = context->current_op;
336 //printf("updating operator %d of channel %d\n", op, channel); 336 //printf("updating operator %d of channel %d\n", op, channel);
346 if (operator->multiple) { 346 if (operator->multiple) {
347 lfo_mod *= operator->multiple; 347 lfo_mod *= operator->multiple;
348 } else { 348 } else {
349 lfo_mod >>= 1; 349 lfo_mod >>= 1;
350 } 350 }
351 operator->phase_counter += lfo_mod; 351 operator->phase_counter += lfo_mod;
352 } 352 }
353 int16_t mod = 0; 353 int16_t mod = 0;
354 switch (op % 4) 354 switch (op % 4)
355 { 355 {
356 case 0://Operator 1 356 case 0://Operator 1
411 } 411 }
412 if (first_key_on) { 412 if (first_key_on) {
413 dfprintf(debug_file, "op %d, base phase: %d, mod: %d, sine: %d, out: %d\n", op, phase, mod, sine_table[(phase+mod) & 0x1FF], pow_table[sine_table[phase & 0x1FF] + env]); 413 dfprintf(debug_file, "op %d, base phase: %d, mod: %d, sine: %d, out: %d\n", op, phase, mod, sine_table[(phase+mod) & 0x1FF], pow_table[sine_table[phase & 0x1FF] + env]);
414 } 414 }
415 phase += mod; 415 phase += mod;
416 416
417 int16_t output = pow_table[sine_table[phase & 0x1FF] + env]; 417 int16_t output = pow_table[sine_table[phase & 0x1FF] + env];
418 if (phase & 0x200) { 418 if (phase & 0x200) {
419 output = -output; 419 output = -output;
420 } 420 }
421 operator->output = output; 421 operator->output = output;
559 } else { 559 } else {
560 inc <<= (channel->block-1); 560 inc <<= (channel->block-1);
561 } 561 }
562 //detune 562 //detune
563 detune = detune_table[channel->keycode][operator->detune & 0x3]; 563 detune = detune_table[channel->keycode][operator->detune & 0x3];
564 } 564 }
565 if (operator->detune & 0x40) { 565 if (operator->detune & 0x40) {
566 inc -= detune; 566 inc -= detune;
567 //this can underflow, mask to 17-bit result 567 //this can underflow, mask to 17-bit result
568 inc &= 0x1FFFF; 568 inc &= 0x1FFFF;
569 } else { 569 } else {
598 context->lfo_enable = value & 0x8; 598 context->lfo_enable = value & 0x8;
599 if (!context->lfo_enable) { 599 if (!context->lfo_enable) {
600 context->lfo_am_step = context->lfo_pm_step = 0; 600 context->lfo_am_step = context->lfo_pm_step = 0;
601 } 601 }
602 context->lfo_freq = value & 0x7; 602 context->lfo_freq = value & 0x7;
603 603
604 break; 604 break;
605 case REG_TIMERA_HIGH: 605 case REG_TIMERA_HIGH:
606 context->timer_a_load &= 0x3; 606 context->timer_a_load &= 0x3;
607 context->timer_a_load |= value << 2; 607 context->timer_a_load |= value << 2;
608 break; 608 break;
642 if (channel > 2) { 642 if (channel > 2) {
643 channel--; 643 channel--;
644 } 644 }
645 for (uint8_t op = channel * 4, bit = 0x10; op < (channel + 1) * 4; op++, bit <<= 1) { 645 for (uint8_t op = channel * 4, bit = 0x10; op < (channel + 1) * 4; op++, bit <<= 1) {
646 if (value & bit) { 646 if (value & bit) {
647 first_key_on = 1; 647 if (context->operators[op].env_phase == PHASE_RELEASE)
648 //printf("Key On for operator %d in channel %d\n", op, channel); 648 {
649 context->operators[op].phase_counter = 0; 649 first_key_on = 1;
650 context->operators[op].env_phase = PHASE_ATTACK; 650 //printf("Key On for operator %d in channel %d\n", op, channel);
651 context->operators[op].envelope = MAX_ENVELOPE; 651 context->operators[op].phase_counter = 0;
652 context->operators[op].env_phase = PHASE_ATTACK;
653 }
652 } else { 654 } else {
653 //printf("Key Off for operator %d in channel %d\n", op, channel); 655 //printf("Key Off for operator %d in channel %d\n", op, channel);
654 context->operators[op].env_phase = PHASE_RELEASE; 656 context->operators[op].env_phase = PHASE_RELEASE;
655 } 657 }
656 } 658 }
751 //printf("Write of %X to LR_AMS_PMS reg for channel %d\n", value, channel); 753 //printf("Write of %X to LR_AMS_PMS reg for channel %d\n", value, channel);
752 break; 754 break;
753 } 755 }
754 } 756 }
755 } 757 }
756 758
757 context->write_cycle = context->current_cycle; 759 context->write_cycle = context->current_cycle;
758 context->status |= 0x80; 760 context->status |= 0x80;
759 } 761 }
760 762
761 uint8_t ym_read_status(ym2612_context * context) 763 uint8_t ym_read_status(ym2612_context * context)