changeset 845:3a18b5f63afc

Small fix to how manual YM-2612 timer reloads work. Seems to better match a small test program and gets audio to match up in TM.EE's "I've got Italo Inside" track.
author Michael Pavone <pavone@retrodev.com>
date Sat, 31 Oct 2015 21:11:40 -0700
parents 74e161fe7d39
children 98d7b6073163
files ym2612.c ym2612.h
diffstat 2 files changed, 30 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/ym2612.c	Sat Oct 31 13:49:27 2015 -0700
+++ b/ym2612.c	Sat Oct 31 21:11:40 2015 -0700
@@ -58,6 +58,9 @@
 #define BIT_TIMERA_RESET  0x10
 #define BIT_TIMERB_RESET  0x20
 
+#define BIT_TIMERA_LOAD   0x40
+#define BIT_TIMERB_LOAD   0x80
+
 #define BIT_STATUS_TIMERA 0x1
 #define BIT_STATUS_TIMERB 0x2
 
@@ -241,7 +244,7 @@
 #define YM_MOD_SHIFT 1
 
 #define TIMER_A_MAX 1023
-#define TIMER_B_MAX (255*16)
+#define TIMER_B_MAX 255
 
 void ym_run(ym2612_context * context, uint32_t to_cycle)
 {
@@ -254,22 +257,29 @@
 				if (context->timer_a != TIMER_A_MAX) {
 					context->timer_a++;
 				} else {
-					if (context->timer_control & BIT_TIMERA_OVEREN) {
+					if (context->timer_control & BIT_TIMERA_LOAD) {
+						context->timer_control &= ~BIT_TIMERA_LOAD;
+					} else if (context->timer_control & BIT_TIMERA_OVEREN) {
 						context->status |= BIT_STATUS_TIMERA;
 					}
 					context->timer_a = context->timer_a_load;
 				}
 			}
-			if (context->timer_control & BIT_TIMERB_ENABLE) {
-				if (context->timer_b != TIMER_B_MAX) {
-					context->timer_b++;
-				} else {
-					if (context->timer_control & BIT_TIMERB_OVEREN) {
-						context->status |= BIT_STATUS_TIMERB;
+			if (!context->sub_timer_b) {
+				if (context->timer_control & BIT_TIMERB_ENABLE) {
+					if (context->timer_b != TIMER_B_MAX) {
+						context->timer_b++;
+					} else {
+						if (context->timer_control & BIT_TIMERB_LOAD) {
+							context->timer_control &= ~BIT_TIMERB_LOAD;
+						} else if (context->timer_control & BIT_TIMERB_OVEREN) {
+							context->status |= BIT_STATUS_TIMERB;
+						}
+						context->timer_b = context->timer_b_load;
 					}
-					context->timer_b = context->timer_b_load;
 				}
 			}
+			context->sub_timer_b += 0x10;
 			//Update LFO
 			if (context->lfo_enable) {
 				if (context->lfo_counter) {
@@ -672,16 +682,19 @@
 			context->timer_a_load |= value & 0x3;
 			break;
 		case REG_TIMERB:
-			context->timer_b_load = value * 16;
+			context->timer_b_load = value;
 			break;
 		case REG_TIME_CTRL: {
 			if (value & BIT_TIMERA_ENABLE && !(context->timer_control & BIT_TIMERA_ENABLE)) {
-				context->timer_a = context->timer_a_load;
+				context->timer_a = TIMER_A_MAX;
+				context->timer_control |= BIT_TIMERA_LOAD;
 			}
 			if (value & BIT_TIMERB_ENABLE && !(context->timer_control & BIT_TIMERB_ENABLE)) {
-				context->timer_b = context->timer_b_load;
+				context->timer_b = TIMER_B_MAX;
+				context->timer_control |= BIT_TIMERB_LOAD;
 			}
-			context->timer_control = value & 0xF;
+			context->timer_control &= (BIT_TIMERA_LOAD | BIT_TIMERB_LOAD);
+			context->timer_control |= value & 0xF;
 			if (value & BIT_TIMERA_RESET) {
 				context->status &= ~BIT_STATUS_TIMERA;
 			}
@@ -837,7 +850,7 @@
 		   "Feedback:  %d\n"
 		   "Pan:       %s\n"
 		   "AMS:       %d\n"
-		   "PMS:       %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);
--- a/ym2612.h	Sat Oct 31 13:49:27 2015 -0700
+++ b/ym2612.h	Sat Oct 31 21:11:40 2015 -0700
@@ -75,10 +75,11 @@
 	ym_channel  channels[NUM_CHANNELS];
 	uint16_t    timer_a;
 	uint16_t    timer_a_load;
-	uint16_t    timer_b;
-	uint16_t    timer_b_load;
 	uint16_t    env_counter;
 	ym_supp     ch3_supp[3];
+	uint8_t     timer_b;
+	uint8_t     sub_timer_b;
+	uint8_t     timer_b_load;
 	uint8_t     ch3_mode;
 	uint8_t     current_op;
 	uint8_t     current_env_op;