Mercurial > repos > blastem
comparison ym2612.c @ 1798:5278b6e44fc1
Optionally emulate the offset around zero in the imperfect DAC of a discrete YM2612
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 24 Mar 2019 19:59:41 -0700 |
parents | 804f13c090b4 |
children | 1d1198f16279 |
comparison
equal
deleted
inserted
replaced
1797:5ff8f0d28188 | 1798:5278b6e44fc1 |
---|---|
254 } | 254 } |
255 } | 255 } |
256 } | 256 } |
257 } | 257 } |
258 ym_reset(context); | 258 ym_reset(context); |
259 ym_enable_zero_offset(context, 1); | |
259 } | 260 } |
260 | 261 |
261 void ym_free(ym2612_context *context) | 262 void ym_free(ym2612_context *context) |
262 { | 263 { |
263 render_free_source(context->audio); | 264 render_free_source(context->audio); |
265 ym_finalize_log(); | 266 ym_finalize_log(); |
266 } | 267 } |
267 free(context); | 268 free(context); |
268 } | 269 } |
269 | 270 |
270 #define YM_VOLUME_MULTIPLIER 2 | 271 void ym_enable_zero_offset(ym2612_context *context, uint8_t enabled) |
271 #define YM_VOLUME_DIVIDER 3 | 272 { |
273 if (enabled) { | |
274 context->zero_offset = 0x70; | |
275 context->volume_mult = 79; | |
276 context->volume_div = 120; | |
277 } else { | |
278 context->zero_offset = 0; | |
279 context->volume_mult = 2; | |
280 context->volume_div = 3; | |
281 } | |
282 } | |
272 #define YM_MOD_SHIFT 1 | 283 #define YM_MOD_SHIFT 1 |
273 | 284 |
274 #define CSM_MODE 0x80 | 285 #define CSM_MODE 0x80 |
275 | 286 |
276 #define SSG_ENABLE 8 | 287 #define SSG_ENABLE 8 |
547 if (first_key_on) { | 558 if (first_key_on) { |
548 int16_t value = context->channels[channel].output & 0x3FE0; | 559 int16_t value = context->channels[channel].output & 0x3FE0; |
549 if (value & 0x2000) { | 560 if (value & 0x2000) { |
550 value |= 0xC000; | 561 value |= 0xC000; |
551 } | 562 } |
552 dfprintf(debug_file, "channel %d output: %d\n", channel, (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER); | 563 dfprintf(debug_file, "channel %d output: %d\n", channel, (value * context->volume_mult) / context->volume_div); |
553 } | 564 } |
554 } | 565 } |
555 //puts("operator update done"); | 566 //puts("operator update done"); |
556 } | 567 } |
557 context->current_op++; | 568 context->current_op++; |
569 value &= 0x3FE0; | 580 value &= 0x3FE0; |
570 if (value & 0x2000) { | 581 if (value & 0x2000) { |
571 value |= 0xC000; | 582 value |= 0xC000; |
572 } | 583 } |
573 } | 584 } |
585 if (value >= 0) { | |
586 value += context->zero_offset; | |
587 } else { | |
588 value -= context->zero_offset; | |
589 } | |
574 if (context->channels[i].logfile) { | 590 if (context->channels[i].logfile) { |
575 fwrite(&value, sizeof(value), 1, context->channels[i].logfile); | 591 fwrite(&value, sizeof(value), 1, context->channels[i].logfile); |
576 } | 592 } |
577 if (context->channels[i].lr & 0x80) { | 593 if (context->channels[i].lr & 0x80) { |
578 left += (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER; | 594 left += (value * context->volume_mult) / context->volume_div; |
579 } | 595 } |
580 if (context->channels[i].lr & 0x40) { | 596 if (context->channels[i].lr & 0x40) { |
581 right += (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER; | 597 right += (value * context->volume_mult) / context->volume_div; |
582 } | 598 } |
583 } | 599 } |
584 render_put_stereo_sample(context->audio, left, right); | 600 render_put_stereo_sample(context->audio, left, right); |
585 } | 601 } |
586 | 602 |