Mercurial > repos > blastem
comparison ym2612.c @ 396:09328dbe6700
Fix output of algorithm 4 and make some other minor YM2612 core improvements
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 11 Jun 2013 23:36:18 -0700 |
parents | 6e5c4f3ab0e2 |
children | f0a3f86595ae |
comparison
equal
deleted
inserted
replaced
395:0b5f93358a93 | 396:09328dbe6700 |
---|---|
261 uint32_t op = context->current_op; | 261 uint32_t op = context->current_op; |
262 //printf("updating operator %d of channel %d\n", op, channel); | 262 //printf("updating operator %d of channel %d\n", op, channel); |
263 ym_operator * operator = context->operators + op; | 263 ym_operator * operator = context->operators + op; |
264 ym_channel * chan = context->channels + channel; | 264 ym_channel * chan = context->channels + channel; |
265 //TODO: Modulate phase by LFO if necessary | 265 //TODO: Modulate phase by LFO if necessary |
266 uint16_t phase = operator->phase_counter >> 10 & 0x3FF; | |
266 operator->phase_counter += operator->phase_inc; | 267 operator->phase_counter += operator->phase_inc; |
267 uint16_t phase = operator->phase_counter >> 10 & 0x3FF; | |
268 int16_t mod = 0; | 268 int16_t mod = 0; |
269 switch (op % 4) | 269 switch (op % 4) |
270 { | 270 { |
271 case 0://Operator 1 | 271 case 0://Operator 1 |
272 if (chan->feedback) { | 272 if (chan->feedback) { |
337 //Update the channel output if we've updated all operators | 337 //Update the channel output if we've updated all operators |
338 if (op % 4 == 3) { | 338 if (op % 4 == 3) { |
339 if (chan->algorithm < 4) { | 339 if (chan->algorithm < 4) { |
340 chan->output = operator->output; | 340 chan->output = operator->output; |
341 } else if(chan->algorithm == 4) { | 341 } else if(chan->algorithm == 4) { |
342 chan->output = operator->output + context->operators[channel * 4 + 1].output; | 342 chan->output = operator->output + context->operators[channel * 4 + 2].output; |
343 } else { | 343 } else { |
344 output = 0; | 344 output = 0; |
345 for (uint32_t op = ((chan->algorithm == 7) ? 0 : 1) + channel*4; op < (channel+1)*4; op++) { | 345 for (uint32_t op = ((chan->algorithm == 7) ? 0 : 1) + channel*4; op < (channel+1)*4; op++) { |
346 output += context->operators[op].output; | 346 output += context->operators[op].output; |
347 } | 347 } |
357 } | 357 } |
358 //puts("operator update done"); | 358 //puts("operator update done"); |
359 } | 359 } |
360 context->current_op++; | 360 context->current_op++; |
361 context->buffer_fraction += context->buffer_inc; | 361 context->buffer_fraction += context->buffer_inc; |
362 if (context->buffer_fraction > 1.0) { | |
363 context->buffer_fraction -= 1.0; | |
364 context->audio_buffer[context->buffer_pos] = 0; | |
365 context->audio_buffer[context->buffer_pos + 1] = 0; | |
366 for (int i = 0; i < NUM_CHANNELS; i++) { | |
367 int16_t value = context->channels[i].output & 0x3FE0; | |
368 if (value & 0x2000) { | |
369 value |= 0xC000; | |
370 } | |
371 if (context->channels[i].lr & 0x80) { | |
372 context->audio_buffer[context->buffer_pos] += value / YM_VOLUME_DIVIDER; | |
373 } | |
374 if (context->channels[i].lr & 0x40) { | |
375 context->audio_buffer[context->buffer_pos+1] += value / YM_VOLUME_DIVIDER; | |
376 } | |
377 } | |
378 context->buffer_pos += 2; | |
379 if (context->buffer_pos == context->sample_limit) { | |
380 render_wait_ym(context); | |
381 } | |
382 } | |
383 if (context->current_op == NUM_OPERATORS) { | 362 if (context->current_op == NUM_OPERATORS) { |
384 context->current_op = 0; | 363 context->current_op = 0; |
364 if (context->buffer_fraction > 1.0) { | |
365 context->buffer_fraction -= 1.0; | |
366 context->audio_buffer[context->buffer_pos] = 0; | |
367 context->audio_buffer[context->buffer_pos + 1] = 0; | |
368 for (int i = 0; i < NUM_CHANNELS; i++) { | |
369 int16_t value = context->channels[i].output & 0x3FE0; | |
370 if (value & 0x2000) { | |
371 value |= 0xC000; | |
372 } | |
373 if (context->channels[i].lr & 0x80) { | |
374 context->audio_buffer[context->buffer_pos] += value / YM_VOLUME_DIVIDER; | |
375 } | |
376 if (context->channels[i].lr & 0x40) { | |
377 context->audio_buffer[context->buffer_pos+1] += value / YM_VOLUME_DIVIDER; | |
378 } | |
379 } | |
380 context->buffer_pos += 2; | |
381 if (context->buffer_pos == context->sample_limit) { | |
382 render_wait_ym(context); | |
383 } | |
384 } | |
385 } | 385 } |
386 } | 386 } |
387 if (context->current_cycle >= context->write_cycle + (BUSY_CYCLES * context->clock_inc / 6)) { | 387 if (context->current_cycle >= context->write_cycle + (BUSY_CYCLES * context->clock_inc / 6)) { |
388 context->status &= 0x7F; | 388 context->status &= 0x7F; |
389 context->write_cycle = CYCLE_NEVER; | 389 context->write_cycle = CYCLE_NEVER; |
547 break; | 547 break; |
548 } | 548 } |
549 case REG_DAC: | 549 case REG_DAC: |
550 if (context->dac_enable) { | 550 if (context->dac_enable) { |
551 context->channels[5].output = (((int16_t)value) - 0x80) << 6; | 551 context->channels[5].output = (((int16_t)value) - 0x80) << 6; |
552 //printf("DAC Write %X(%d)\n", value, context->channels[5].output); | 552 //printf("DAC Write %X(%d) @ %d\n", value, context->channels[5].output, context->current_cycle); |
553 } | 553 } |
554 break; | 554 break; |
555 case REG_DAC_ENABLE: | 555 case REG_DAC_ENABLE: |
556 //printf("DAC Enable: %X\n", value); | 556 //printf("DAC Enable: %X\n", value); |
557 context->dac_enable = value & 0x80; | 557 context->dac_enable = value & 0x80; |