From fc7b94876de8bea663e6958ff5472ee91447b774 Mon Sep 17 00:00:00 2001 From: Laurens Holst Date: Tue, 24 May 2022 00:48:14 +0200 Subject: [PATCH] Fix Y8950 ADPCM samples. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reverting back to before 70ead337f3, and setting register 8 to 256Kbit RAM mode. This is what MSX has natively, and allows for the most compact sample storage with only 4 byte alignment. Additionally, setting register 8 before writing the start / stop addresses. Back story: VGMPlay MSX only supports Y8950 256K DRAM mode and ROM mode (for the latter it makes sure address writes are shifted). 64K DRAM mode is not supported because it’s not used by anything and the addresses are specified weirdly with some middle bits having to be masked out. The original code in Furnace before the change 70ead337f3 was almost correct except it needed to set register 8 to 0 to select the 256K DRAM mode. It was set to ROM mode so the address shift did not match up. After 70ead337f3 (address shift change) it was also more or less correct except in “furnacePCM” direct-sample mode the shift was not updated accordingly. In 1a446c1cdd it selected 64K RAM mode, but for this the addresses need to be specified differently (see Y8950 manual page 18), and it’s not really the best choice anyway. --- src/engine/platform/opl.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index cb6d832fa..aed4c315c 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -734,12 +734,12 @@ int DivPlatformOPL::dispatch(DivCommand c) { chan[c.chan].sample=ins->amiga.getSample(c.value); if (chan[c.chan].sample>=0 && chan[c.chan].samplesong.sampleLen) { DivSample* s=parent->getSample(chan[c.chan].sample); - immWrite(9,(s->offB>>5)&0xff); - immWrite(10,(s->offB>>13)&0xff); + immWrite(8,0); + immWrite(9,(s->offB>>2)&0xff); + immWrite(10,(s->offB>>10)&0xff); int end=s->offB+s->lengthB-1; - immWrite(11,(end>>5)&0xff); - immWrite(12,(end>>13)&0xff); - immWrite(8,2); + immWrite(11,(end>>2)&0xff); + immWrite(12,(end>>10)&0xff); immWrite(7,(s->loopStart>=0)?0xb0:0xa0); // start/repeat if (c.value!=DIV_NOTE_NULL) { chan[c.chan].note=c.value; @@ -769,12 +769,12 @@ int DivPlatformOPL::dispatch(DivCommand c) { break; } DivSample* s=parent->getSample(12*sampleBank+c.value%12); + immWrite(8,0); immWrite(9,(s->offB>>2)&0xff); immWrite(10,(s->offB>>10)&0xff); int end=s->offB+s->lengthB-1; immWrite(11,(end>>2)&0xff); immWrite(12,(end>>10)&0xff); - immWrite(8,2); immWrite(7,(s->loopStart>=0)?0xb0:0xa0); // start/repeat int freq=(65536.0*(double)s->rate)/(double)rate; immWrite(16,freq&0xff); @@ -1703,7 +1703,7 @@ int DivPlatformOPL::init(DivEngine* p, int channels, int sugRate, unsigned int f adpcmBMemLen=0; iface.adpcmBMem=adpcmBMem; iface.sampleBank=0; - adpcmB=new ymfm::adpcm_b_engine(iface,5); + adpcmB=new ymfm::adpcm_b_engine(iface,2); } reset();