MSM6258: VGM EXPORT!!!

This commit is contained in:
tildearrow 2023-09-11 01:19:02 -05:00
parent b5c53319ef
commit 8b7b21d909
4 changed files with 90 additions and 3 deletions

View file

@ -30,6 +30,16 @@ const char** DivPlatformMSM6258::getRegisterSheet() {
return NULL;
}
static const int msmRates[4]={
4, 3, 2, 2
};
int DivPlatformMSM6258::calcVGMRate() {
int ret=chipClock/((clockSel+1)*512*msmRates[rateSel&3]);
logD("MSM rate: %d",ret);
return ret;
}
void DivPlatformMSM6258::acquire(short** buf, size_t len) {
for (size_t h=0; h<len; h++) {
if (--msmClockCount<0) {
@ -93,6 +103,7 @@ void DivPlatformMSM6258::tick(bool sysTick) {
if (rateSel!=(chan[i].std.duty.val&3)) {
rateSel=chan[i].std.duty.val&3;
rWrite(12,rateSel);
updateSampleFreq=true;
}
}
if (chan[i].std.panL.had) {
@ -105,6 +116,7 @@ void DivPlatformMSM6258::tick(bool sysTick) {
if (clockSel!=(chan[i].std.ex1.val&1)) {
clockSel=chan[i].std.ex1.val&1;
rWrite(8,clockSel);
updateSampleFreq=true;
}
}
if (chan[i].std.phaseReset.had) {
@ -113,12 +125,23 @@ void DivPlatformMSM6258::tick(bool sysTick) {
}
}
}
if (updateSampleFreq) {
int newRate=calcVGMRate();
if (dumpWrites) addWrite(0xffff0001,newRate);
updateSampleFreq=false;
}
if (chan[i].keyOn || chan[i].keyOff) {
samplePos=0;
rWrite(0,1); // turn off
// turn off
if (dumpWrites) addWrite(0xffff0002,0);
rWrite(0,1);
if (chan[i].active && !chan[i].keyOff) {
if (sample>=0 && sample<parent->song.sampleLen) {
// turn on
rWrite(0,2);
if (dumpWrites) addWrite(0xffff0000,sample);
int newRate=calcVGMRate();
if (dumpWrites) addWrite(0xffff0001,newRate);
} else {
sample=-1;
}
@ -220,10 +243,12 @@ int DivPlatformMSM6258::dispatch(DivCommand c) {
case DIV_CMD_SAMPLE_FREQ:
rateSel=c.value&3;
rWrite(12,rateSel);
updateSampleFreq=true;
break;
case DIV_CMD_SAMPLE_MODE:
clockSel=c.value&1;
rWrite(8,clockSel);
updateSampleFreq=true;
break;
case DIV_CMD_PANNING: {
if (c.value==0 && c.value2==0) {
@ -317,8 +342,10 @@ void DivPlatformMSM6258::reset() {
msmPan=3;
rateSel=2;
clockSel=0;
updateSampleFreq=true;
if (dumpWrites) {
addWrite(0xffffffff,0);
addWrite(0xffff0001,calcVGMRate());
}
for (int i=0; i<1; i++) {
chan[i]=DivPlatformMSM6258::Channel();

View file

@ -50,12 +50,15 @@ class DivPlatformMSM6258: public DivDispatch {
unsigned char sampleBank, msmPan, msmDivider, rateSel, msmClock, clockSel;
signed char msmDividerCount, msmClockCount;
bool updateSampleFreq;
short msmOut;
int delay, updateOsc, sample, samplePos;
friend void putDispatchChip(void*,int);
friend void putDispatchChan(void*,int,int);
int calcVGMRate();
public:
void acquire(short** buf, size_t len);

View file

@ -1820,7 +1820,7 @@ void DivEngine::registerSystems() {
sysDefs[DIV_SYSTEM_GA20]=new DivSysDef(
"Irem GA20", NULL, 0xc7, 0, 4, false, true, 0x171, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
"yet another PCM chip from Irem.",
"yet another PCM chip from Irem. like Amiga, but less pitch resolution and no sample loop.",
{"Channel 1", "Channel 2", "Channel 3", "Channel 4"},
{"CH1", "CH2", "CH3", "CH4"},
{DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},

View file

@ -549,6 +549,11 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
w->writeC(8);
w->writeC(0xff);
break;
case DIV_SYSTEM_MSM6258:
w->writeC(0xb8); // stop
w->writeC(baseAddr2|0);
w->writeC(1);
break;
case DIV_SYSTEM_MSM6295:
w->writeC(0xb8); // disable all channels
w->writeC(baseAddr2|0);
@ -1055,6 +1060,12 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
w->writeC(write.addr&0xff);
w->writeC(write.val);
break;
case DIV_SYSTEM_MSM6258:
w->writeC(0xb7);
w->writeC(baseAddr2|(write.addr&0x7f));
w->writeC(write.val);
logV("MSM write to %.2x %.2x",write.addr,write.val);
break;
case DIV_SYSTEM_MSM6295:
w->writeC(0xb8);
w->writeC(baseAddr2|(write.addr&0x7f));
@ -1238,6 +1249,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
bool writeDACSamples=false;
bool writeNESSamples=false;
bool writePCESamples=false;
bool writeVOXSamples=false;
DivDispatch* writeADPCM_OPNA[2]={NULL,NULL};
DivDispatch* writeADPCM_OPNB[2]={NULL,NULL};
DivDispatch* writeADPCM_Y8950[2]={NULL,NULL};
@ -1746,6 +1758,21 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
writeRF5C68[0]=disCont[i].dispatch;
}
break;
case DIV_SYSTEM_MSM6258:
if (!hasOKIM6258) {
hasOKIM6258=disCont[i].dispatch->chipClock;
CHIP_VOL(23,0.65);
willExport[i]=true;
writeVOXSamples=true;
} else if (!(hasOKIM6258&0x40000000)) {
isSecond[i]=true;
CHIP_VOL_SECOND(23,0.65);
willExport[i]=true;
writeVOXSamples=true;
hasOKIM6258|=0x40000000;
howManyChips++;
}
break;
case DIV_SYSTEM_MSM6295:
if (!hasOKIM6295) {
hasOKIM6295=disCont[i].dispatch->chipClock;
@ -1927,7 +1954,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
w->writeI(hasMultiPCM);
w->writeI(hasuPD7759);
w->writeI(hasOKIM6258);
w->writeC(0); // flags
w->writeC(hasOKIM6258?10:0); // flags
w->writeC(0); // K flags
w->writeC(c140Type); // C140 chip type
w->writeC(0); // reserved
@ -2066,6 +2093,18 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
}
}
if (writeVOXSamples && !directStream) for (int i=0; i<song.sampleLen; i++) {
DivSample* sample=song.sample[i];
w->writeC(0x67);
w->writeC(0x66);
w->writeC(4);
w->writeI(sample->lengthVOX);
for (unsigned int j=0; j<sample->lengthVOX; j++) {
unsigned char actualData=(sample->dataVOX[j]>>4)|(sample->dataVOX[j]<<4);
w->writeC(actualData);
}
}
for (int i=0; i<2; i++) {
// SegaPCM
if (writeSegaPCM[i]!=NULL && writeSegaPCM[i]->getSampleMemUsage(0)>0) {
@ -2344,6 +2383,24 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
w->writeI(24000); // default
streamID++;
break;
case DIV_SYSTEM_MSM6258:
w->writeC(0x90);
w->writeC(streamID);
w->writeC(isSecond[i]?0x97:0x17);
w->writeC(0); // port
w->writeC(1); // data input
w->writeC(0x91);
w->writeC(streamID);
w->writeC(4);
w->writeC(1);
w->writeC(0);
w->writeC(0x92);
w->writeC(streamID);
w->writeI(1000); // safe value
streamID++;
break;
default:
break;
}