changeset 739:2317bdca03b4

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
author Michael Pavone <pavone@retrodev.com>
date Wed, 27 May 2015 20:53:21 -0700
parents 8972378e314f
children 25c9e9d39997
files debug.c ym2612.c ym2612.h
diffstat 3 files changed, 61 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- 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;
--- 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");
+	}
+}
+
--- 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_