Mercurial > repos > blastem
comparison ym2612.c @ 383:72933100c55c
Initial implementation of channel 3 special mode
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 04 Jun 2013 21:23:12 -0700 |
parents | b904859964e5 |
children | 6e5c4f3ab0e2 |
comparison
equal
deleted
inserted
replaced
382:b904859964e5 | 383:72933100c55c |
---|---|
452 { | 452 { |
453 uint32_t chan_num = op / 4; | 453 uint32_t chan_num = op / 4; |
454 //printf("ym_update_phase_inc | channel: %d, op: %d\n", chan_num, op); | 454 //printf("ym_update_phase_inc | channel: %d, op: %d\n", chan_num, op); |
455 //base frequency | 455 //base frequency |
456 ym_channel * channel = context->channels + chan_num; | 456 ym_channel * channel = context->channels + chan_num; |
457 uint32_t inc = channel->fnum; | 457 uint32_t inc, detune; |
458 if (!channel->block) { | 458 if (chan_num == 2 && context->ch3_mode && (op < (2*4 + 3))) { |
459 inc >>= 1; | 459 inc = context->ch3_supp[op-2*4].fnum; |
460 if (!context->ch3_supp[op-2*4].block) { | |
461 inc >>= 1; | |
462 } else { | |
463 inc <<= (context->ch3_supp[op-2*4].block-1); | |
464 } | |
465 //detune | |
466 detune = detune_table[context->ch3_supp[op-2*4].keycode][operator->detune & 0x3]; | |
460 } else { | 467 } else { |
461 inc <<= (channel->block-1); | 468 inc = channel->fnum; |
462 } | 469 if (!channel->block) { |
463 //detune | 470 inc >>= 1; |
464 uint32_t detune = detune_table[channel->keycode][operator->detune & 0x3]; | 471 } else { |
472 inc <<= (channel->block-1); | |
473 } | |
474 //detune | |
475 detune = detune_table[channel->keycode][operator->detune & 0x3]; | |
476 } | |
465 if (operator->detune & 0x40) { | 477 if (operator->detune & 0x40) { |
466 inc -= detune; | 478 inc -= detune; |
467 //this can underflow, mask to 17-bit result | 479 //this can underflow, mask to 17-bit result |
468 inc &= 0x1FFFF; | 480 inc &= 0x1FFFF; |
469 } else { | 481 } else { |
500 context->timer_a_load |= value & 0x3; | 512 context->timer_a_load |= value & 0x3; |
501 break; | 513 break; |
502 case REG_TIMERB: | 514 case REG_TIMERB: |
503 context->timer_b_load = value; | 515 context->timer_b_load = value; |
504 break; | 516 break; |
505 case REG_TIME_CTRL: | 517 case REG_TIME_CTRL: { |
506 context->timer_control = value; | 518 context->timer_control = value & 0x3F; |
519 uint8_t old_mode = context->ch3_mode; | |
520 context->ch3_mode = value & 0xC0; | |
521 if (context->ch3_mode != old_mode) { | |
522 ym_update_phase_inc(context, context->operators + 2*4, 2*4); | |
523 ym_update_phase_inc(context, context->operators + 2*4+1, 2*4+1); | |
524 ym_update_phase_inc(context, context->operators + 2*4+2, 2*4+2); | |
525 } | |
507 break; | 526 break; |
527 } | |
508 case REG_KEY_ONOFF: { | 528 case REG_KEY_ONOFF: { |
509 uint8_t channel = value & 0x7; | 529 uint8_t channel = value & 0x7; |
510 if (channel < NUM_CHANNELS) { | 530 if (channel < NUM_CHANNELS) { |
511 for (uint8_t op = channel * 4, bit = 0x10; op < (channel + 1) * 4; op++, bit <<= 1) { | 531 for (uint8_t op = channel * 4, bit = 0x10; op < (channel + 1) * 4; op++, bit <<= 1) { |
512 if (value & bit) { | 532 if (value & bit) { |
589 break; | 609 break; |
590 case REG_BLOCK_FNUM_H:{ | 610 case REG_BLOCK_FNUM_H:{ |
591 context->channels[channel].block_fnum_latch = value; | 611 context->channels[channel].block_fnum_latch = value; |
592 break; | 612 break; |
593 } | 613 } |
594 //TODO: Channel 3 special/CSM modes | 614 case REG_FNUM_LOW_CH3: |
615 if (channel < 3) { | |
616 context->ch3_supp[channel].block = context->ch3_supp[channel].block_fnum_latch >> 3 & 0x7; | |
617 context->ch3_supp[channel].fnum = (context->ch3_supp[channel].block_fnum_latch & 0x7) << 8 | value; | |
618 context->ch3_supp[channel].keycode = context->ch3_supp[channel].block << 2 | fnum_to_keycode[context->ch3_supp[channel].fnum >> 7]; | |
619 if (context->ch3_mode) { | |
620 ym_update_phase_inc(context, context->operators + 2*4 + channel, 2*4); | |
621 } | |
622 } | |
623 break; | |
624 case REG_BLOCK_FN_CH3: | |
625 if (channel < 3) { | |
626 context->ch3_supp[channel].block_fnum_latch = value; | |
627 } | |
628 break; | |
595 case REG_ALG_FEEDBACK: | 629 case REG_ALG_FEEDBACK: |
596 context->channels[channel].algorithm = value & 0x7; | 630 context->channels[channel].algorithm = value & 0x7; |
597 context->channels[channel].feedback = value >> 3 & 0x7; | 631 context->channels[channel].feedback = value >> 3 & 0x7; |
598 break; | 632 break; |
599 case REG_LR_AMS_PMS: | 633 case REG_LR_AMS_PMS: |