comparison ym2612.c @ 1301:babff81e4cfd

Initial implementation of YM2612 SSG-EG mode
author Michael Pavone <pavone@retrodev.com>
date Mon, 27 Mar 2017 00:40:10 -0700
parents 4b893b02444e
children 1b3fe6e03e7b
comparison
equal deleted inserted replaced
1300:4b893b02444e 1301:babff81e4cfd
252 #define TIMER_A_MAX 1023 252 #define TIMER_A_MAX 1023
253 #define TIMER_B_MAX 255 253 #define TIMER_B_MAX 255
254 254
255 #define CSM_MODE 0x80 255 #define CSM_MODE 0x80
256 256
257 static void keyon(ym_operator *op, ym_channel *channel) 257 #define SSG_ENABLE 8
258 #define SSG_INVERT 4
259 #define SSG_ALTERNATE 2
260 #define SSG_HOLD 1
261
262 #define SSG_CENTER 0x800
263
264 static void start_envelope(ym_operator *op, ym_channel *channel)
258 { 265 {
259 //Deal with "infinite" attack rates 266 //Deal with "infinite" attack rates
260 uint8_t rate = op->rates[PHASE_ATTACK]; 267 uint8_t rate = op->rates[PHASE_ATTACK];
261 if (rate) { 268 if (rate) {
262 uint8_t ks = channel->keycode >> op->key_scaling;; 269 uint8_t ks = channel->keycode >> op->key_scaling;;
266 op->env_phase = PHASE_DECAY; 273 op->env_phase = PHASE_DECAY;
267 op->envelope = 0; 274 op->envelope = 0;
268 } else { 275 } else {
269 op->env_phase = PHASE_ATTACK; 276 op->env_phase = PHASE_ATTACK;
270 } 277 }
278 }
279
280 static void keyon(ym_operator *op, ym_channel *channel)
281 {
282 start_envelope(op, channel);
271 op->phase_counter = 0; 283 op->phase_counter = 0;
284 op->inverted = op->ssg & SSG_INVERT;
272 } 285 }
273 286
274 static const uint8_t keyon_bits[] = {0x10, 0x40, 0x20, 0x80}; 287 static const uint8_t keyon_bits[] = {0x10, 0x40, 0x20, 0x80};
288
289 static void keyoff(ym_operator *op)
290 {
291 op->env_phase = PHASE_RELEASE;
292 if (op->inverted) {
293 //Nemesis says the inversion state doesn't change here, but I don't see how that is observable either way
294 op->inverted = 0;
295 op->envelope = (SSG_CENTER - op->envelope) & MAX_ENVELOPE;
296 }
297 }
275 298
276 static void csm_keyoff(ym2612_context *context) 299 static void csm_keyoff(ym2612_context *context)
277 { 300 {
278 context->csm_keyon = 0; 301 context->csm_keyon = 0;
279 uint8_t changes = 0xF0 ^ context->channels[2].keyon; 302 uint8_t changes = 0xF0 ^ context->channels[2].keyon;
280 for (uint8_t op = 2*4, bit = 0; op < 3*4; op++, bit++) 303 for (uint8_t op = 2*4, bit = 0; op < 3*4; op++, bit++)
281 { 304 {
282 if (changes & keyon_bits[bit]) { 305 if (changes & keyon_bits[bit]) {
283 context->operators[op].env_phase = PHASE_RELEASE; 306 keyoff(context->operators + op);
284 } 307 }
285 } 308 }
286 } 309 }
287 310
288 void ym_run(ym2612_context * context, uint32_t to_cycle) 311 void ym_run(ym2612_context * context, uint32_t to_cycle)
387 } else { 410 } else {
388 if (first_key_on) { 411 if (first_key_on) {
389 dfprintf(debug_file, "Changing op %d envelope %d by %d in %s phase\n", op, operator->envelope, envelope_inc, 412 dfprintf(debug_file, "Changing op %d envelope %d by %d in %s phase\n", op, operator->envelope, envelope_inc,
390 operator->env_phase == PHASE_SUSTAIN ? "sustain" : (operator->env_phase == PHASE_DECAY ? "decay": "release")); 413 operator->env_phase == PHASE_SUSTAIN ? "sustain" : (operator->env_phase == PHASE_DECAY ? "decay": "release"));
391 } 414 }
415 if (operator->ssg) {
416 if (operator->envelope < SSG_CENTER) {
417 envelope_inc *= 4;
418 } else {
419 envelope_inc = 0;
420 }
421 }
392 //envelope value is 10-bits, but it will be used as a 4.8 value 422 //envelope value is 10-bits, but it will be used as a 4.8 value
393 operator->envelope += envelope_inc << 2; 423 operator->envelope += envelope_inc << 2;
394 //clamp to max attenuation value 424 //clamp to max attenuation value
395 if (operator->envelope > MAX_ENVELOPE) { 425 if (
426 operator->envelope > MAX_ENVELOPE
427 || (operator->env_phase == PHASE_RELEASE && operator->envelope >= SSG_CENTER)
428 ) {
396 operator->envelope = MAX_ENVELOPE; 429 operator->envelope = MAX_ENVELOPE;
397 } 430 }
398 } 431 }
399 } 432 }
400 context->current_env_op++; 433 context->current_env_op++;
466 mod = context->operators[op-3].output >> YM_MOD_SHIFT; 499 mod = context->operators[op-3].output >> YM_MOD_SHIFT;
467 break; 500 break;
468 } 501 }
469 break; 502 break;
470 } 503 }
471 uint16_t env = operator->envelope + operator->total_level; 504 uint16_t env = operator->envelope;
505 if (operator->ssg) {
506 if (env >= SSG_CENTER) {
507 if (operator->ssg & SSG_ALTERNATE) {
508 if (operator->env_phase != PHASE_RELEASE && (
509 !(operator->ssg & SSG_HOLD) || ((operator->ssg ^ operator->inverted) & SSG_INVERT) == 0
510 )) {
511 operator->inverted ^= SSG_INVERT;
512 }
513 } else if (!(operator->ssg & SSG_HOLD)) {
514 phase = operator->phase_counter = 0;
515 }
516 if (
517 (operator->env_phase == PHASE_DECAY || operator->env_phase == PHASE_SUSTAIN)
518 && !(operator->ssg & SSG_HOLD)
519 ) {
520 start_envelope(operator, chan);
521 env = operator->envelope;
522 }
523 }
524 if (operator->inverted) {
525 env = (SSG_CENTER - env) & MAX_ENVELOPE;
526 }
527 }
528 env += operator->total_level;
472 if (operator->am) { 529 if (operator->am) {
473 uint16_t base_am = (context->lfo_am_step & 0x80 ? context->lfo_am_step : ~context->lfo_am_step) & 0x7E; 530 uint16_t base_am = (context->lfo_am_step & 0x80 ? context->lfo_am_step : ~context->lfo_am_step) & 0x7E;
474 if (ams_shift[chan->ams] >= 0) { 531 if (ams_shift[chan->ams] >= 0) {
475 env += base_am >> ams_shift[chan->ams]; 532 env += base_am >> ams_shift[chan->ams];
476 } else { 533 } else {
785 first_key_on = 1; 842 first_key_on = 1;
786 //printf("Key On for operator %d in channel %d\n", op, channel); 843 //printf("Key On for operator %d in channel %d\n", op, channel);
787 keyon(context->operators + op, context->channels + channel); 844 keyon(context->operators + op, context->channels + channel);
788 } else { 845 } else {
789 //printf("Key Off for operator %d in channel %d\n", op, channel); 846 //printf("Key Off for operator %d in channel %d\n", op, channel);
790 context->operators[op].env_phase = PHASE_RELEASE; 847 keyoff(context->operators + op);
791 } 848 }
792 } 849 }
793 } 850 }
794 } 851 }
795 break; 852 break;
838 operator->rates[PHASE_RELEASE] = (value & 0xF) << 1 | 1; 895 operator->rates[PHASE_RELEASE] = (value & 0xF) << 1 | 1;
839 operator->sustain_level = (value & 0xF0) << 3; 896 operator->sustain_level = (value & 0xF0) << 3;
840 if (operator->sustain_level == 0x780) { 897 if (operator->sustain_level == 0x780) {
841 operator->sustain_level = MAX_ENVELOPE; 898 operator->sustain_level = MAX_ENVELOPE;
842 } 899 }
900 break;
901 case REG_SSG_EG:
902 if (!(value & SSG_ENABLE)) {
903 value = 0;
904 }
905 if ((value ^ operator->ssg) & SSG_INVERT) {
906 operator->inverted ^= SSG_INVERT;
907 }
908 operator->ssg = value;
843 break; 909 break;
844 } 910 }
845 } 911 }
846 } else { 912 } else {
847 uint8_t channel = context->selected_reg & 0x3; 913 uint8_t channel = context->selected_reg & 0x3;