changeset 2002:fc8fd89aeba9

Fix VGM delay calculation overflow when a YM-2612 write follows a PSG write in close succession
author Mike Pavone <pavone@retrodev.com>
date Tue, 14 Jul 2020 20:19:47 -0700
parents f77d36a975ff
children 4c418ee9a9d8
files vgm.c
diffstat 1 files changed, 11 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/vgm.c	Sun Jul 12 23:09:02 2020 -0700
+++ b/vgm.c	Tue Jul 14 20:19:47 2020 -0700
@@ -60,8 +60,15 @@
 	}
 }
 
+#include "util.h"
 static void add_wait(vgm_writer *writer, uint32_t cycle)
 {
+	if (cycle < writer->last_cycle) {
+		//This can happen when a YM-2612 write happens immediately after a PSG write
+		//due to the relatively low granularity of the PSG's internal clock
+		//given that VGM only has a granularity of 44.1 kHz ignoring this is harmless
+		return;
+	}
 	uint64_t last_sample = (uint64_t)writer->last_cycle * (uint64_t)44100;
 	last_sample /= (uint64_t)writer->master_clock;
 	uint64_t sample = (uint64_t)cycle * (uint64_t)44100;
@@ -73,10 +80,12 @@
 	wait_commands(writer, delta);
 }
 
+static uint8_t last_cmd;
 void vgm_sn76489_write(vgm_writer *writer, uint32_t cycle, uint8_t value)
 {
 	add_wait(writer, cycle);
 	uint8_t cmd[2] = {CMD_PSG, value};
+	last_cmd = CMD_PSG;
 	fwrite(cmd, 1, sizeof(cmd), writer->f);
 }
 
@@ -89,6 +98,7 @@
 {
 	add_wait(writer, cycle);
 	uint8_t cmd[3] = {CMD_YM2612_0, reg, value};
+	last_cmd = CMD_YM2612_0;
 	fwrite(cmd, 1, sizeof(cmd), writer->f);
 }
 
@@ -96,6 +106,7 @@
 {
 	add_wait(writer, cycle);
 	uint8_t cmd[3] = {CMD_YM2612_1, reg, value};
+	last_cmd = CMD_YM2612_1;
 	fwrite(cmd, 1, sizeof(cmd), writer->f);
 }