changeset 747:85c98a222fea

Merge
author Michael Pavone <pavone@retrodev.com>
date Thu, 28 May 2015 23:05:32 -0700
parents 25c9e9d39997 (diff) 9d4d40f833d0 (current diff)
children 45b62d237b7b
files debug.c
diffstat 3 files changed, 77 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/debug.c	Thu May 28 23:04:49 2015 -0700
+++ b/debug.c	Thu May 28 23:05:32 2015 -0700
@@ -768,6 +768,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	Thu May 28 23:04:49 2015 -0700
+++ b/ym2612.c	Thu May 28 23:05:32 2015 -0700
@@ -108,6 +108,8 @@
 };
 int16_t lfo_pm_table[128 * 32 * 8];
 
+uint16_t ams_shift[] = {8, 3, 1, 0};
+
 #define MAX_ENVELOPE 0xFFC
 #define YM_DIVIDER 2
 #define CYCLE_NEVER 0xFFFFFFFF
@@ -268,16 +270,16 @@
 					context->timer_b = context->timer_b_load;
 				}
 			}
-		}
-		//Update LFO
-		if (context->lfo_enable) {
-			if (context->lfo_counter) {
-				context->lfo_counter--;
-			} else {
-				context->lfo_counter = lfo_timer_values[context->lfo_freq];
-				context->lfo_am_step += 2;
-				context->lfo_am_step &= 0xFE;
-				context->lfo_pm_step = context->lfo_am_step / 8;
+			//Update LFO
+			if (context->lfo_enable) {
+				if (context->lfo_counter) {
+					context->lfo_counter--;
+				} else {
+					context->lfo_counter = lfo_timer_values[context->lfo_freq];
+					context->lfo_am_step += 2;
+					context->lfo_am_step &= 0xFE;
+					context->lfo_pm_step = context->lfo_am_step / 8;
+				}
 			}
 		}
 		//Update Envelope Generator
@@ -427,6 +429,10 @@
 				break;
 			}
 			uint16_t env = operator->envelope + operator->total_level;
+			if (operator->am) {
+				uint16_t base_am = (context->lfo_am_step & 0x80 ? context->lfo_am_step : ~context->lfo_am_step) & 0x7E;
+				env += base_am >> ams_shift[chan->ams];
+			}
 			if (env > MAX_ENVELOPE) {
 				env = MAX_ENVELOPE;
 			}
@@ -605,7 +611,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 +621,7 @@
 	//multiple
 	if (operator->multiple) {
 		inc *= operator->multiple;
+		inc &= 0xFFFFF;
 	} else {
 		//0.5
 		inc >>= 1;
@@ -748,6 +755,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 +829,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	Thu May 28 23:04:49 2015 -0700
+++ b/ym2612.h	Thu May 28 23:05:32 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_