mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-01 18:42:40 +00:00
MSM6258: VGM EXPORT!!!
This commit is contained in:
parent
b5c53319ef
commit
8b7b21d909
4 changed files with 90 additions and 3 deletions
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue