changeset 403:f0a3f86595ae

Fix YM2612 timers
author Mike Pavone <pavone@retrodev.com>
date Sun, 16 Jun 2013 00:56:23 -0700
parents de2c085ce174
children 88fa2ad53e64
files ym2612.c ym2612.h
diffstat 2 files changed, 35 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/ym2612.c	Sat Jun 15 23:50:59 2013 -0700
+++ b/ym2612.c	Sun Jun 16 00:56:23 2013 -0700
@@ -159,32 +159,34 @@
 #define YM_VOLUME_DIVIDER 2
 #define YM_MOD_SHIFT 1
 
+#define TIMER_A_MAX 1023
+#define TIMER_B_MAX (255*16)
+
 void ym_run(ym2612_context * context, uint32_t to_cycle)
 {
 	//printf("Running YM2612 from cycle %d to cycle %d\n", context->current_cycle, to_cycle);
 	//TODO: Fix channel update order OR remap channels in register write
 	for (; context->current_cycle < to_cycle; context->current_cycle += context->clock_inc) {
 		//Update timers at beginning of 144 cycle period
-		if (!context->current_op && context->timer_control & BIT_TIMERA_ENABLE) {
-			if (context->timer_a) {
-				context->timer_a--;
-			} else {
-				if (context->timer_control & BIT_TIMERA_OVEREN) {
-					context->status |= BIT_STATUS_TIMERA;
+		if (!context->current_op) {
+			if (context->timer_control & BIT_TIMERA_ENABLE) {
+				if (context->timer_a != TIMER_A_MAX) {
+					context->timer_a++;
+				} else {
+					if (context->timer_control & BIT_TIMERA_OVEREN) {
+						context->status |= BIT_STATUS_TIMERA;
+					}
+					context->timer_a = context->timer_a_load;
 				}
-				context->timer_a = context->timer_a_load;
 			}
 			if (context->timer_control & BIT_TIMERB_ENABLE) {
-				uint32_t b_cyc = (context->current_cycle / OP_UPDATE_PERIOD) % 16;
-				if (!b_cyc) {
-					if (context->timer_b) {
-						context->timer_b--;
-					} else {
-						if (context->timer_control & BIT_TIMERB_OVEREN) {
-							context->status |= BIT_STATUS_TIMERB;
-						}
-						context->timer_b = context->timer_b_load;
+				if (context->timer_b != TIMER_B_MAX) {
+					context->timer_b++;
+				} else {
+					if (context->timer_control & BIT_TIMERB_OVEREN) {
+						context->status |= BIT_STATUS_TIMERB;
 					}
+					context->timer_b = context->timer_b_load;
 				}
 			}
 		}
@@ -512,10 +514,22 @@
 			context->timer_a_load |= value & 0x3;
 			break;
 		case REG_TIMERB:
-			context->timer_b_load = value;
+			context->timer_b_load = value * 16;
 			break;
 		case REG_TIME_CTRL: {
-			context->timer_control = value & 0x3F;
+			if (value & BIT_TIMERA_ENABLE && !(context->timer_control & BIT_TIMERA_ENABLE)) {
+				context->timer_a = context->timer_a_load;
+			}
+			if (value & BIT_TIMERB_ENABLE && !(context->timer_control & BIT_TIMERB_ENABLE)) {
+				context->timer_b = context->timer_b_load;
+			}
+			context->timer_control = value & 0xF;
+			if (value & BIT_TIMERA_RESET) {
+				context->status &= ~BIT_STATUS_TIMERA;
+			}
+			if (value & BIT_TIMERB_RESET) {
+				context->status &= ~BIT_STATUS_TIMERB;
+			}
 			uint8_t old_mode = context->ch3_mode;
 			context->ch3_mode = value & 0xC0;
 			if (context->ch3_mode != old_mode) {
--- a/ym2612.h	Sat Jun 15 23:50:59 2013 -0700
+++ b/ym2612.h	Sun Jun 16 00:56:23 2013 -0700
@@ -55,13 +55,14 @@
 	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     ch3_mode;
 	uint8_t     current_op;
 	uint8_t     current_env_op;
-	uint8_t     timer_b;
-	uint8_t     timer_b_load;
+	
 	uint8_t     timer_control;
 	uint8_t     dac_enable;
 	uint8_t     status;