From 4ed40d37d6c488ac17f5aeb7b92f72b25d356fa8 Mon Sep 17 00:00:00 2001 From: cam900 Date: Wed, 27 Aug 2025 21:02:51 +0900 Subject: [PATCH] Add sample limit in OPL4 PCM, Reduce duplicate it has 512 (if header at 0x000000) or 128 (otherwise; first 384 sample is from bottommost area (ex: YRW801 ROM) in this case) sample limits --- src/engine/platform/opl.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 762bde308..5a8f81a4e 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -37,6 +37,9 @@ #define PCM_CHECK(ch) ((chipType==4) && (ch>=pcmChanOffs)) #define PCM_REG(ch) (ch-pcmChanOffs) +// check if PCM in RAM (and size is <= 2MB) - 4MB uses whole sample area +#define PCM_IN_RAM (ramSize<=0x200000) + // N = invalid #define N 255 @@ -1466,7 +1469,7 @@ void DivPlatformOPL::tick(bool sysTick) { ctrl|=(chan[i].active?0x80:0)|(chan[i].damp?0x40:0)|(chan[i].lfoReset?0x20:0)|(chan[i].ch?0x10:0)|(isMuted[i]?8:(chan[i].pan&0xf)); int waveNum=chan[i].sample; if (waveNum>=0) { - if (ramSize<=0x200000) { + if (PCM_IN_RAM) { waveNum=CLAMP(waveNum,0,0x7f)|0x180; } if (chan[i].keyOn) { @@ -2941,7 +2944,7 @@ void DivPlatformOPL::reset() { if (chipType==4) { immWrite(0x105,3); // Reset wavetable header - immWrite(0x202,(ramSize<=0x200000)?0x10:0x00); + immWrite(0x202,PCM_IN_RAM?0x10:0x00); // initialize mixer volume fmMixL=7; fmMixR=7; @@ -3209,7 +3212,7 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) { pcm.setClockFrequency(chipClock); rate=chipClock/768; chipRateBase=chipClock/684; - immWrite(0x202,(ramSize<=0x200000)?0x10:0x00); + immWrite(0x202,PCM_IN_RAM?0x10:0x00); break; case 759: rate=48000; @@ -3232,7 +3235,7 @@ const void* DivPlatformOPL::getSampleMem(int index) { size_t DivPlatformOPL::getSampleMemCapacity(int index) { return (index==0 && pcmChanOffs>=0)? - ((ramSize<=0x200000)?0x200000+ramSize:ramSize): + (PCM_IN_RAM?0x200000+ramSize:ramSize): ((index==0 && adpcmChan>=0)?262144:0); } @@ -3269,10 +3272,16 @@ void DivPlatformOPL::renderSamples(int sysID) { memCompo.name="Sample Memory"; if (pcmChanOffs>=0) { // OPL4 PCM - size_t memPos=((ramSize<=0x200000)?0x200600:0x1800); - const int maxSample=(ramSize<=0x200000)?127:511; + size_t memPos=(PCM_IN_RAM?0x200600:0x1800); + const int maxSample=PCM_IN_RAM?128:512; int sampleCount=parent->song.sampleLen; - if (sampleCount>maxSample) sampleCount=maxSample; + if (sampleCount>maxSample) { + // mark the rest as unavailable + for (int i=maxSample; isong.sample[i]; if (!s->renderOn[0][sysID]) { @@ -3335,7 +3344,7 @@ void DivPlatformOPL::renderSamples(int sysID) { // instrument table for (int i=0; isong.sample[i]; - unsigned int insAddr=(i*12)+((ramSize<=0x200000)?0x200000:0); + unsigned int insAddr=(i*12)+(PCM_IN_RAM?0x200000:0); unsigned char bitDepth; int endPos=CLAMP(s->isLoopable()?s->loopEnd:(s->samples+1),1,0x10000); int loop=s->isLoopable()?CLAMP(s->loopStart,0,endPos-2):(endPos-2); @@ -3366,12 +3375,12 @@ void DivPlatformOPL::renderSamples(int sysID) { pcmMem[6+insAddr]=(~(endPos-1))&0xff; // on MultiPCM this consists of instrument params, but on OPL4 this is not used pcmMem[7+insAddr]=0; // LFO, VIB - pcmMem[8+insAddr]=(0xf << 4) | (0xf << 0); // AR, D1R + pcmMem[8+insAddr]=(0xf<<4)|(0xf<<0); // AR, D1R pcmMem[9+insAddr]=0; // DL, D2R - pcmMem[10+insAddr]=(0xf << 4) | (0xf << 0); // RC, RR + pcmMem[10+insAddr]=(0xf<<4)|(0xf<<0); // RC, RR pcmMem[11+insAddr]=0; // AM } - if (ramSize<=0x200000) { + if (PCM_IN_RAM) { memCompo.entries.push_back(DivMemoryEntry(DIV_MEMORY_RESERVED,"ROM data",0,0,0x200000)); }