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 }