# HG changeset patch # User Michael Pavone # Date 1432785201 25200 # Node ID 2317bdca03b4724b8dd208acc75fbb5720c9f5ac # Parent 8972378e314fe1e53e8554d5490f039886767308 Add a basic YM-2612 command to the debugger. Fix negative detune values and get the correct precision for the multiplication step of phase inc calculation diff -r 8972378e314f -r 2317bdca03b4 debug.c --- a/debug.c Tue May 26 22:22:30 2015 -0700 +++ b/debug.c Wed May 27 20:53:21 2015 -0700 @@ -760,6 +760,23 @@ } break; } + case 'y': { + genesis_context * gen = context->system; + //YM-2612 debug commands + switch(input_buf[1]) + { + case 'c': + if (input_buf[2] == ' ') { + int channel = atoi(input_buf+3)-1; + ym_print_channel_info(gen->ym, channel); + } else { + for (int i = 0; i < 6; i++) { + ym_print_channel_info(gen->ym, i); + } + } + } + break; + } #ifndef NO_Z80 case 'z': { genesis_context * gen = context->system; diff -r 8972378e314f -r 2317bdca03b4 ym2612.c --- a/ym2612.c Tue May 26 22:22:30 2015 -0700 +++ b/ym2612.c Wed May 27 20:53:21 2015 -0700 @@ -605,7 +605,7 @@ //detune detune = detune_table[channel->keycode][operator->detune & 0x3]; } - if (operator->detune & 0x40) { + if (operator->detune & 0x4) { inc -= detune; //this can underflow, mask to 17-bit result inc &= 0x1FFFF; @@ -615,6 +615,7 @@ //multiple if (operator->multiple) { inc *= operator->multiple; + inc &= 0xFFFFF; } else { //0.5 inc >>= 1; @@ -748,6 +749,7 @@ break; case REG_DECAY_AM: //TODO: AM flag for LFO + operator->am = value & 0x80; operator->rates[PHASE_DECAY] = value & 0x1F; break; case REG_SUSTAIN_RATE: @@ -821,3 +823,42 @@ return context->status; } +void ym_print_channel_info(ym2612_context *context, int channel) +{ + ym_channel *chan = context->channels + channel; + printf("\n***Channel %d***\n" + "Algorithm: %d\n" + "Feedback: %d\n" + "Pan: %s\n" + "AMS: %d\n" + "PMS: %d\n", + channel+1, chan->algorithm, chan->feedback, + chan->lr == 0xC0 ? "LR" : chan->lr == 0x80 ? "L" : chan->lr == 0x40 ? "R" : "", + chan->ams, chan->pms); + for (int operator = channel * 4; operator < channel * 4+4; operator++) + { + int dispnum = operator - channel * 4 + 1; + if (dispnum == 2) { + dispnum = 3; + } else if (dispnum == 3) { + dispnum = 2; + } + ym_operator *op = context->operators + operator; + printf("\nOperator %d:\n" + " Multiple: %d\n" + " Detune: %d\n" + " Total Level: %d\n" + " Attack Rate: %d\n" + " Key Scaling: %d\n" + " Decay Rate: %d\n" + " Sustain Level: %d\n" + " Sustain Rate: %d\n" + " Release Rate: %d\n" + " Amplitude Modulation %s\n", + dispnum, op->multiple, op->detune, op->total_level, + op->rates[PHASE_ATTACK], op->key_scaling, op->rates[PHASE_DECAY], + op->sustain_level, op->rates[PHASE_SUSTAIN], op->rates[PHASE_RELEASE], + op->am ? "On" : "Off"); + } +} + diff -r 8972378e314f -r 2317bdca03b4 ym2612.h --- a/ym2612.h Tue May 26 22:22:30 2015 -0700 +++ b/ym2612.h Wed May 27 20:53:21 2015 -0700 @@ -26,6 +26,7 @@ uint8_t key_scaling; uint8_t multiple; uint8_t detune; + uint8_t am; uint8_t env_phase; } ym_operator; @@ -105,6 +106,7 @@ uint8_t ym_read_status(ym2612_context * context); uint8_t ym_load_gst(ym2612_context * context, FILE * gstfile); uint8_t ym_save_gst(ym2612_context * context, FILE * gstfile); +void ym_print_channel_info(ym2612_context *context, int channel); #endif //YM2612_H_