Mercurial > repos > blastem
comparison ym2612.c @ 2243:0d1d5dccdd28
Initial implementation of oscilloscope debug view
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 22 Nov 2022 17:57:02 -0800 |
parents | cfd53c94fffb |
children | 74112041b2c7 |
comparison
equal
deleted
inserted
replaced
2240:8e8db9141209 | 2243:0d1d5dccdd28 |
---|---|
154 { | 154 { |
155 memset(context->part1_regs, 0, sizeof(context->part1_regs)); | 155 memset(context->part1_regs, 0, sizeof(context->part1_regs)); |
156 memset(context->part2_regs, 0, sizeof(context->part2_regs)); | 156 memset(context->part2_regs, 0, sizeof(context->part2_regs)); |
157 memset(context->operators, 0, sizeof(context->operators)); | 157 memset(context->operators, 0, sizeof(context->operators)); |
158 FILE* savedlogs[NUM_CHANNELS]; | 158 FILE* savedlogs[NUM_CHANNELS]; |
159 uint8_t saved_scope_channel[NUM_CHANNELS]; | |
159 for (int i = 0; i < NUM_CHANNELS; i++) | 160 for (int i = 0; i < NUM_CHANNELS; i++) |
160 { | 161 { |
161 savedlogs[i] = context->channels[i].logfile; | 162 savedlogs[i] = context->channels[i].logfile; |
163 saved_scope_channel[i] = context->channels[i].scope_channel; | |
162 } | 164 } |
163 memset(context->channels, 0, sizeof(context->channels)); | 165 memset(context->channels, 0, sizeof(context->channels)); |
164 memset(context->ch3_supp, 0, sizeof(context->ch3_supp)); | 166 memset(context->ch3_supp, 0, sizeof(context->ch3_supp)); |
165 context->selected_reg = 0; | 167 context->selected_reg = 0; |
166 context->csm_keyon = 0; | 168 context->csm_keyon = 0; |
177 | 179 |
178 //some games seem to expect that the LR flags start out as 1 | 180 //some games seem to expect that the LR flags start out as 1 |
179 for (int i = 0; i < NUM_CHANNELS; i++) { | 181 for (int i = 0; i < NUM_CHANNELS; i++) { |
180 context->channels[i].lr = 0xC0; | 182 context->channels[i].lr = 0xC0; |
181 context->channels[i].logfile = savedlogs[i]; | 183 context->channels[i].logfile = savedlogs[i]; |
184 context->channels[i].scope_channel = saved_scope_channel[i]; | |
182 if (i < 3) { | 185 if (i < 3) { |
183 context->part1_regs[REG_LR_AMS_PMS - YM_PART1_START + i] = 0xC0; | 186 context->part1_regs[REG_LR_AMS_PMS - YM_PART1_START + i] = 0xC0; |
184 } else { | 187 } else { |
185 context->part2_regs[REG_LR_AMS_PMS - YM_PART2_START + i - 3] = 0xC0; | 188 context->part2_regs[REG_LR_AMS_PMS - YM_PART2_START + i - 3] = 0xC0; |
186 } | 189 } |
494 if (channel != 5 || !context->dac_enable) { | 497 if (channel != 5 || !context->dac_enable) { |
495 //printf("updating operator %d of channel %d\n", op, channel); | 498 //printf("updating operator %d of channel %d\n", op, channel); |
496 ym_operator * operator = context->operators + op; | 499 ym_operator * operator = context->operators + op; |
497 ym_channel * chan = context->channels + channel; | 500 ym_channel * chan = context->channels + channel; |
498 uint16_t phase = operator->phase_counter >> 10 & 0x3FF; | 501 uint16_t phase = operator->phase_counter >> 10 & 0x3FF; |
502 uint32_t old_phase = operator->phase_counter; | |
499 operator->phase_counter += operator->phase_inc;//ym_calc_phase_inc(context, operator, op); | 503 operator->phase_counter += operator->phase_inc;//ym_calc_phase_inc(context, operator, op); |
504 operator->phase_overflow = (old_phase & 0xFFFFF) > (operator->phase_counter & 0xFFFFF); | |
500 int16_t mod = 0; | 505 int16_t mod = 0; |
501 if (op & 3) { | 506 if (op & 3) { |
502 if (operator->mod_src[0]) { | 507 if (operator->mod_src[0]) { |
503 mod = *operator->mod_src[0]; | 508 mod = *operator->mod_src[0]; |
504 if (operator->mod_src[1]) { | 509 if (operator->mod_src[1]) { |
566 operator->output = output; | 571 operator->output = output; |
567 //Update the channel output if we've updated all operators | 572 //Update the channel output if we've updated all operators |
568 if (op % 4 == 3) { | 573 if (op % 4 == 3) { |
569 if (chan->algorithm < 4) { | 574 if (chan->algorithm < 4) { |
570 chan->output = operator->output; | 575 chan->output = operator->output; |
576 chan->phase_overflow = operator->phase_overflow; | |
571 } else if(chan->algorithm == 4) { | 577 } else if(chan->algorithm == 4) { |
572 chan->output = operator->output + context->operators[channel * 4 + 2].output; | 578 ym_operator *other_op = context->operators + channel * 4 + 2; |
579 chan->output = operator->output + other_op->output; | |
580 if (operator->phase_inc < other_op->phase_inc) { | |
581 chan->phase_overflow = operator->phase_overflow; | |
582 } else { | |
583 chan->phase_overflow = other_op->phase_overflow; | |
584 } | |
573 } else { | 585 } else { |
574 output = 0; | 586 output = 0; |
587 uint32_t lowest_phase_inc = 0xFFFFFFFF; | |
575 for (uint32_t op = ((chan->algorithm == 7) ? 0 : 1) + channel*4; op < (channel+1)*4; op++) { | 588 for (uint32_t op = ((chan->algorithm == 7) ? 0 : 1) + channel*4; op < (channel+1)*4; op++) { |
576 output += context->operators[op].output; | 589 output += context->operators[op].output; |
590 if (context->operators[op].phase_inc < lowest_phase_inc) { | |
591 lowest_phase_inc = context->operators[op].phase_inc; | |
592 chan->phase_overflow = context->operators[op].phase_overflow; | |
593 } | |
577 } | 594 } |
578 chan->output = output; | 595 chan->output = output; |
579 } | |
580 if (first_key_on) { | |
581 int16_t value = context->channels[channel].output & 0x3FE0; | |
582 if (value & 0x2000) { | |
583 value |= 0xC000; | |
584 } | |
585 } | 596 } |
586 } | 597 } |
587 //puts("operator update done"); | 598 //puts("operator update done"); |
588 } | 599 } |
589 } | 600 } |
608 } else { | 619 } else { |
609 value -= context->zero_offset; | 620 value -= context->zero_offset; |
610 } | 621 } |
611 if (context->channels[i].logfile) { | 622 if (context->channels[i].logfile) { |
612 fwrite(&value, sizeof(value), 1, context->channels[i].logfile); | 623 fwrite(&value, sizeof(value), 1, context->channels[i].logfile); |
624 } | |
625 if (context->scope) { | |
626 scope_add_sample(context->scope, context->channels[i].scope_channel, value, context->channels[i].phase_overflow); | |
613 } | 627 } |
614 if (context->channels[i].lr & 0x80) { | 628 if (context->channels[i].lr & 0x80) { |
615 left += (value * context->volume_mult) / context->volume_div; | 629 left += (value * context->volume_mult) / context->volume_div; |
616 } else if (context->zero_offset) { | 630 } else if (context->zero_offset) { |
617 if (value >= 0) { | 631 if (value >= 0) { |
1380 } else { | 1394 } else { |
1381 context->last_status = context->status; | 1395 context->last_status = context->status; |
1382 context->last_status_cycle = context->write_cycle; | 1396 context->last_status_cycle = context->write_cycle; |
1383 } | 1397 } |
1384 } | 1398 } |
1399 | |
1400 void ym_enable_scope(ym2612_context *context, oscilloscope *scope) | |
1401 { | |
1402 static const char *names[] = { | |
1403 "YM2612 #1", | |
1404 "YM2612 #2", | |
1405 "YM2612 #3", | |
1406 "YM2612 #4", | |
1407 "YM2612 #5", | |
1408 "YM2612 #6" | |
1409 }; | |
1410 context->scope = scope; | |
1411 for (int i = 0; i < NUM_CHANNELS; i++) | |
1412 { | |
1413 //TODO: calculate actual sample rate based on current clock settings | |
1414 context->channels[i].scope_channel = scope_add_channel(scope, names[i], 53267); | |
1415 } | |
1416 } |