Kurumitsu-8L: add (nonstandard) VGM export

This commit is contained in:
Natt Akuma 2025-06-28 01:19:25 +07:00
parent 434fc96bba
commit dcf784c43f
5 changed files with 38 additions and 10 deletions

View file

@ -583,7 +583,7 @@ class DivEngine {
void processRow(int i, bool afterDelay);
void nextOrder();
void nextRow();
void performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write, int streamOff, double* loopTimer, double* loopFreq, int* loopSample, bool* sampleDir, bool isSecond, int* pendingFreq, int* playingSample, int* setPos, unsigned int* sampleOff8, unsigned int* sampleLen8, size_t bankOffset, bool directStream, bool* sampleStoppable, bool dpcm07, DivDispatch** writeNES, int rateCorrection);
void performVGMWrite(SafeWriter* w, int disIdx, DivSystem sys, DivRegWrite& write, int streamOff, double* loopTimer, double* loopFreq, int* loopSample, bool* sampleDir, bool isSecond, int* pendingFreq, int* playingSample, int* setPos, unsigned int* sampleOff8, unsigned int* sampleLen8, size_t bankOffset, bool directStream, bool* sampleStoppable, bool dpcm07, DivDispatch** writeNES, int rateCorrection);
// returns true if end of song.
bool nextTick(bool noAccum=false, bool inhibitLowLat=false);
bool perSystemEffect(int ch, unsigned char effect, unsigned char effectVal);

View file

@ -1438,6 +1438,8 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo
break;
case DIV_INS_UPD1771C:
break;
case DIV_INS_KURUMITSU_8L:
break;
case DIV_INS_MAX:
break;
case DIV_INS_NULL:

View file

@ -269,7 +269,6 @@ void DivPlatformKurumitsu8L::tick(bool sysTick) {
chan[i].keyOn=false;
if (i==7) {
DivSample* s=parent->getSample(chan[i].sample);
size_t maxPos=getSampleMemCapacity();
unsigned int start, length, loop;
start=sampleOff[chan[i].sample];
if (s->isLoopable()) {
@ -530,7 +529,9 @@ int DivPlatformKurumitsu8L::getRegisterPoolSize() {
}
const void* DivPlatformKurumitsu8L::getSampleMem(int index) {
return index == 0 ? sampleMem : NULL;
if (index == 0) return sampleMem;
if (index == 1) return wtMem;
return NULL;
}
size_t DivPlatformKurumitsu8L::getSampleMemCapacity(int index) {
@ -557,12 +558,12 @@ const DivMemoryComposition* DivPlatformKurumitsu8L::getMemCompo(int index) {
}
void DivPlatformKurumitsu8L::renderSamples(int sysID) {
size_t maxPos=getSampleMemCapacity();
int maxPos=getSampleMemCapacity();
memset(sampleMem,0,maxPos);
romMemCompo.entries.clear();
romMemCompo.capacity=maxPos;
size_t memPos=0;
int memPos=0;
for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
@ -659,12 +660,12 @@ void DivPlatformKurumitsu8L::setFlags(const DivConfig& flags) {
}
void DivPlatformKurumitsu8L::poke(unsigned int addr, unsigned short val) {
if (addr < getRegisterPoolSize()) chWrite(addr>>4,addr&0xf,val);
if (addr < (unsigned int)getRegisterPoolSize()) chWrite(addr>>4,addr&0xf,val);
}
void DivPlatformKurumitsu8L::poke(std::vector<DivRegWrite>& wlist) {
for (DivRegWrite& i: wlist) {
if (i.addr < getRegisterPoolSize()) chWrite(i.addr>>4,i.addr&0xf,i.val);
if (i.addr < (unsigned int)getRegisterPoolSize()) chWrite(i.addr>>4,i.addr&0xf,i.val);
}
}

View file

@ -2343,7 +2343,7 @@ void DivEngine::registerSystems() {
);
sysDefs[DIV_SYSTEM_KURUMITSU_8L]=new DivSysDef(
_("Kurumitsu-8L"), NULL, 0xfe, 0, 8, false, true, 0, false, 1U<<DIV_SAMPLE_DEPTH_8BIT, 256, 256,
_("Kurumitsu-8L"), NULL, 0xfe, 0, 8, false, true, 0x151, false, 1U<<DIV_SAMPLE_DEPTH_8BIT, 256, 256,
_(":grins:"),
{_("Channel 1"), _("Channel 2"), _("Channel 3"), _("Channel 4"), _("Channel 5"), _("Channel 6"), _("Channel 7"), _("Sample")},
{"CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7", "CH8"},

View file

@ -24,7 +24,7 @@
// this function is so long
// may as well make it something else
void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write, int streamOff, double* loopTimer, double* loopFreq, int* loopSample, bool* sampleDir, bool isSecond, int* pendingFreq, int* playingSample, int* setPos, unsigned int* sampleOff8, unsigned int* sampleLen8, size_t bankOffset, bool directStream, bool* sampleStoppable, bool dpcm07, DivDispatch** writeNES, int rateCorrection) {
void DivEngine::performVGMWrite(SafeWriter* w, int disIdx, DivSystem sys, DivRegWrite& write, int streamOff, double* loopTimer, double* loopFreq, int* loopSample, bool* sampleDir, bool isSecond, int* pendingFreq, int* playingSample, int* setPos, unsigned int* sampleOff8, unsigned int* sampleLen8, size_t bankOffset, bool directStream, bool* sampleStoppable, bool dpcm07, DivDispatch** writeNES, int rateCorrection) {
unsigned char baseAddr1=isSecond?0xa0:0x50;
unsigned char baseAddr2=isSecond?0x80:0;
unsigned short baseAddr2S=isSecond?0x8000:0;
@ -1216,6 +1216,23 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
w->writeC(write.addr&0xff);
w->writeC(write.val);
break;
case DIV_SYSTEM_KURUMITSU_8L: // HACK
if (write.addr>=0x10000) {
// wavetable writes
const signed char* wtMem=(const signed char*)disCont[disIdx].dispatch->getSampleMem(1);
w->writeC(0x67);
w->writeC(0x66);
w->writeC(0xc0);
w->writeI(write.val+2);
w->writeI(write.addr&0xffff);
w->write(&wtMem[write.addr&0xffff],write.val);
} else {
// register writes
w->writeC(0xa0);
w->writeC(baseAddr2|(write.addr&0xff));
w->writeC(write.val);
}
break;
default:
logW("write not handled!");
break;
@ -2018,6 +2035,14 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
howManyChips++;
}
break;
// HACK
case DIV_SYSTEM_KURUMITSU_8L:
if (!hasAY) {
hasAY=disCont[i].dispatch->chipClock|0x40000000;
willExport[i]=true;
writeSegaPCM[0]=disCont[i].dispatch;
}
break;
default:
break;
}
@ -2851,7 +2876,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
lastOne=i.second.time;
}
// write write
performVGMWrite(w,song.system[i.first],i.second.write,streamIDs[i.first],loopTimer,loopFreq,loopSample,sampleDir,isSecond[i.first],pendingFreq,playingSample,setPos,sampleOff8,sampleLen8,bankOffset[i.first],directStream,sampleStoppable,dpcm07,writeNES,correctedRate);
performVGMWrite(w,i.first,song.system[i.first],i.second.write,streamIDs[i.first],loopTimer,loopFreq,loopSample,sampleDir,isSecond[i.first],pendingFreq,playingSample,setPos,sampleOff8,sampleLen8,bankOffset[i.first],directStream,sampleStoppable,dpcm07,writeNES,correctedRate);
writeCount++;
}
sortedWrites.clear();