Merge branch 'master' of github.com:tildearrow/furnace
This commit is contained in:
commit
019b036853
22 changed files with 403 additions and 573 deletions
|
|
@ -201,12 +201,12 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
|
|||
((DivPlatformGenesisExt*)dispatch)->setYMFM(eng->getConfInt("ym2612Core",0));
|
||||
((DivPlatformGenesisExt*)dispatch)->setSoftPCM(false);
|
||||
break;
|
||||
case DIV_SYSTEM_YM2612_FRAC:
|
||||
case DIV_SYSTEM_YM2612_DUALPCM:
|
||||
dispatch=new DivPlatformGenesis;
|
||||
((DivPlatformGenesis*)dispatch)->setYMFM(eng->getConfInt("ym2612Core",0));
|
||||
((DivPlatformGenesis*)dispatch)->setSoftPCM(true);
|
||||
break;
|
||||
case DIV_SYSTEM_YM2612_FRAC_EXT:
|
||||
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
|
||||
dispatch=new DivPlatformGenesisExt;
|
||||
((DivPlatformGenesisExt*)dispatch)->setYMFM(eng->getConfInt("ym2612Core",0));
|
||||
((DivPlatformGenesisExt*)dispatch)->setSoftPCM(true);
|
||||
|
|
@ -269,16 +269,16 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
|
|||
case DIV_SYSTEM_TIA:
|
||||
dispatch=new DivPlatformTIA;
|
||||
break;
|
||||
case DIV_SYSTEM_OPN:
|
||||
case DIV_SYSTEM_YM2203:
|
||||
dispatch=new DivPlatformYM2203;
|
||||
break;
|
||||
case DIV_SYSTEM_OPN_EXT:
|
||||
case DIV_SYSTEM_YM2203_EXT:
|
||||
dispatch=new DivPlatformYM2203Ext;
|
||||
break;
|
||||
case DIV_SYSTEM_PC98:
|
||||
case DIV_SYSTEM_YM2608:
|
||||
dispatch=new DivPlatformYM2608;
|
||||
break;
|
||||
case DIV_SYSTEM_PC98_EXT:
|
||||
case DIV_SYSTEM_YM2608_EXT:
|
||||
dispatch=new DivPlatformYM2608Ext;
|
||||
break;
|
||||
case DIV_SYSTEM_OPLL:
|
||||
|
|
|
|||
|
|
@ -1207,8 +1207,8 @@ void DivEngine::convertOldFlags(unsigned int oldFlags, DivConfig& newFlags, DivS
|
|||
break;
|
||||
case DIV_SYSTEM_YM2612:
|
||||
case DIV_SYSTEM_YM2612_EXT:
|
||||
case DIV_SYSTEM_YM2612_FRAC:
|
||||
case DIV_SYSTEM_YM2612_FRAC_EXT:
|
||||
case DIV_SYSTEM_YM2612_DUALPCM:
|
||||
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
|
||||
switch (oldFlags&0x7fffffff) {
|
||||
case 0:
|
||||
newFlags.set("clockSel",0);
|
||||
|
|
@ -1295,8 +1295,8 @@ void DivEngine::convertOldFlags(unsigned int oldFlags, DivConfig& newFlags, DivS
|
|||
newFlags.set("channels",(int)((oldFlags>>4)&7));
|
||||
if (oldFlags&128) newFlags.set("multiplex",true);
|
||||
break;
|
||||
case DIV_SYSTEM_OPN:
|
||||
case DIV_SYSTEM_OPN_EXT:
|
||||
case DIV_SYSTEM_YM2203:
|
||||
case DIV_SYSTEM_YM2203_EXT:
|
||||
switch (oldFlags&31) {
|
||||
case 0:
|
||||
newFlags.set("clockSel",0);
|
||||
|
|
@ -1329,8 +1329,8 @@ void DivEngine::convertOldFlags(unsigned int oldFlags, DivConfig& newFlags, DivS
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_PC98:
|
||||
case DIV_SYSTEM_PC98_EXT:
|
||||
case DIV_SYSTEM_YM2608:
|
||||
case DIV_SYSTEM_YM2608_EXT:
|
||||
switch (oldFlags&31) {
|
||||
case 0:
|
||||
newFlags.set("clockSel",0);
|
||||
|
|
@ -2484,14 +2484,14 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
case DIV_SYSTEM_YM2610_FULL_EXT:
|
||||
case DIV_SYSTEM_YM2610B:
|
||||
case DIV_SYSTEM_YM2610B_EXT:
|
||||
case DIV_SYSTEM_OPN:
|
||||
case DIV_SYSTEM_OPN_EXT:
|
||||
case DIV_SYSTEM_PC98:
|
||||
case DIV_SYSTEM_PC98_EXT:
|
||||
case DIV_SYSTEM_YM2203:
|
||||
case DIV_SYSTEM_YM2203_EXT:
|
||||
case DIV_SYSTEM_YM2608:
|
||||
case DIV_SYSTEM_YM2608_EXT:
|
||||
case DIV_SYSTEM_YM2612:
|
||||
case DIV_SYSTEM_YM2612_EXT:
|
||||
case DIV_SYSTEM_YM2612_FRAC:
|
||||
case DIV_SYSTEM_YM2612_FRAC_EXT:
|
||||
case DIV_SYSTEM_YM2612_DUALPCM:
|
||||
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
|
||||
opnCount++;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -2514,12 +2514,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
if (ds.version<125) {
|
||||
for (int i=0; i<ds.systemLen; i++) {
|
||||
if (ds.system[i]==DIV_SYSTEM_YM2612_EXT ||
|
||||
ds.system[i]==DIV_SYSTEM_YM2612_FRAC_EXT ||
|
||||
ds.system[i]==DIV_SYSTEM_YM2612_DUALPCM_EXT ||
|
||||
ds.system[i]==DIV_SYSTEM_YM2610_EXT ||
|
||||
ds.system[i]==DIV_SYSTEM_YM2610_FULL_EXT ||
|
||||
ds.system[i]==DIV_SYSTEM_YM2610B_EXT ||
|
||||
ds.system[i]==DIV_SYSTEM_OPN_EXT ||
|
||||
ds.system[i]==DIV_SYSTEM_PC98_EXT) {
|
||||
ds.system[i]==DIV_SYSTEM_YM2203_EXT ||
|
||||
ds.system[i]==DIV_SYSTEM_YM2608_EXT) {
|
||||
ds.systemFlags[i].set("noExtMacros",true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,17 +147,19 @@ class DivPlatformOPN: public DivPlatformFMBase {
|
|||
double fmFreqBase;
|
||||
unsigned int fmDivBase;
|
||||
unsigned int ayDiv;
|
||||
unsigned char csmChan;
|
||||
bool extSys;
|
||||
|
||||
DivConfig ayFlags;
|
||||
|
||||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
DivPlatformOPN(double f=9440540.0, unsigned int d=72, unsigned int a=32, bool isExtSys=false):
|
||||
DivPlatformOPN(double f=9440540.0, unsigned int d=72, unsigned int a=32, bool isExtSys=false, unsigned char cc=255):
|
||||
DivPlatformFMBase(),
|
||||
fmFreqBase(f),
|
||||
fmDivBase(d),
|
||||
ayDiv(a),
|
||||
csmChan(cc),
|
||||
extSys(isExtSys) {}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -554,7 +554,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
switch (c.cmd) {
|
||||
case DIV_CMD_NOTE_ON: {
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_FM);
|
||||
if (c.chan==7 && extMode && softPCM) { // CSM
|
||||
if (c.chan==csmChan && extMode && softPCM) { // CSM
|
||||
chan[c.chan].macroInit(ins);
|
||||
chan[c.chan].insChanged=false;
|
||||
|
||||
|
|
@ -686,7 +686,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
break;
|
||||
}
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
if (c.chan>=5 && c.chan<7) {
|
||||
if (c.chan>=5 && c.chan<csmChan) {
|
||||
chan[c.chan].dacSample=-1;
|
||||
if (dumpWrites) addWrite(0xffff0002,0);
|
||||
if (parent->song.brokenDACMode) {
|
||||
|
|
@ -781,7 +781,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
if (c.chan==7) {
|
||||
if (c.chan==csmChan) {
|
||||
int destFreq=NOTE_PERIODIC(c.value2);
|
||||
bool return2=false;
|
||||
if (destFreq>chan[c.chan].baseFreq) {
|
||||
|
|
@ -850,7 +850,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
break;
|
||||
}
|
||||
case DIV_CMD_LEGATO: {
|
||||
if (c.chan==7) {
|
||||
if (c.chan==csmChan) {
|
||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
||||
} else if (c.chan>=5 && chan[c.chan].furnaceDac && chan[c.chan].dacMode) {
|
||||
chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value,false);
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ class DivPlatformGenesis: public DivPlatformOPN {
|
|||
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
|
||||
void quit();
|
||||
DivPlatformGenesis():
|
||||
DivPlatformOPN(9440540.0, 72, 32) {}
|
||||
DivPlatformOPN(9440540.0, 72, 32, false, 7) {}
|
||||
~DivPlatformGenesis();
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -454,7 +454,7 @@ void DivPlatformGenesisExt::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (writeSomething) {
|
||||
if (chan[7].active) { // CSM
|
||||
if (chan[csmChan].active) { // CSM
|
||||
writeMask^=0xf0;
|
||||
}
|
||||
/*printf(
|
||||
|
|
@ -589,17 +589,17 @@ void DivPlatformGenesisExt::tick(bool sysTick) {
|
|||
}
|
||||
|
||||
if (extMode && softPCM) {
|
||||
if (chan[7].freqChanged) {
|
||||
chan[7].freq=parent->calcFreq(chan[7].baseFreq,chan[7].pitch,chan[7].fixedArp?chan[7].baseNoteOverride:chan[7].arpOff,chan[7].fixedArp,true,0,chan[7].pitch2,chipClock,CHIP_DIVIDER);
|
||||
if (chan[7].freq<1) chan[7].freq=1;
|
||||
if (chan[7].freq>1024) chan[7].freq=1024;
|
||||
int wf=0x400-chan[7].freq;
|
||||
if (chan[csmChan].freqChanged) {
|
||||
chan[csmChan].freq=parent->calcFreq(chan[csmChan].baseFreq,chan[csmChan].pitch,chan[csmChan].fixedArp?chan[csmChan].baseNoteOverride:chan[csmChan].arpOff,chan[csmChan].fixedArp,true,0,chan[csmChan].pitch2,chipClock,CHIP_DIVIDER);
|
||||
if (chan[csmChan].freq<1) chan[csmChan].freq=1;
|
||||
if (chan[csmChan].freq>1024) chan[csmChan].freq=1024;
|
||||
int wf=0x400-chan[csmChan].freq;
|
||||
immWrite(0x24,wf>>2);
|
||||
immWrite(0x25,wf&3);
|
||||
chan[7].freqChanged=false;
|
||||
chan[csmChan].freqChanged=false;
|
||||
}
|
||||
|
||||
if (chan[7].keyOff || chan[7].keyOn) {
|
||||
if (chan[csmChan].keyOff || chan[csmChan].keyOn) {
|
||||
writeNoteOn=true;
|
||||
for (int i=0; i<4; i++) {
|
||||
writeMask|=opChan[i].active<<(4+i);
|
||||
|
|
@ -608,7 +608,7 @@ void DivPlatformGenesisExt::tick(bool sysTick) {
|
|||
}
|
||||
|
||||
if (writeNoteOn) {
|
||||
if (chan[7].active) { // CSM
|
||||
if (chan[csmChan].active) { // CSM
|
||||
writeMask^=0xf0;
|
||||
}
|
||||
/*printf(
|
||||
|
|
@ -622,13 +622,13 @@ void DivPlatformGenesisExt::tick(bool sysTick) {
|
|||
}
|
||||
|
||||
if (extMode && softPCM) {
|
||||
if (chan[7].keyOn) {
|
||||
if (chan[csmChan].keyOn) {
|
||||
immWrite(0x27,0x81);
|
||||
chan[7].keyOn=false;
|
||||
chan[csmChan].keyOn=false;
|
||||
}
|
||||
if (chan[7].keyOff) {
|
||||
if (chan[csmChan].keyOff) {
|
||||
immWrite(0x27,0x40);
|
||||
chan[7].keyOff=false;
|
||||
chan[csmChan].keyOff=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,20 @@
|
|||
#define CHIP_DIVIDER 1
|
||||
|
||||
const char* regCheatSheetPokeMini[]={
|
||||
"Period", "0",
|
||||
"TMR3_SCALE", "1C",
|
||||
"TMR3_OSC", "1D",
|
||||
"TMR3_CTRL_L", "48",
|
||||
"TMR3_CTRL_H", "49",
|
||||
"TMR3_PRE_L", "4A",
|
||||
"TMR3_PRE_H", "4B",
|
||||
"TMR3_PVT_L", "4C",
|
||||
"TMR3_PVT_H", "4D",
|
||||
"TMR3_CNT_L", "4E",
|
||||
"TMR3_CNT_H", "4F",
|
||||
"IO_DIR", "60",
|
||||
"IO_DATA", "61",
|
||||
"AUD_CTRL", "70",
|
||||
"AUD_VOL", "71",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -42,6 +55,37 @@ const char** DivPlatformPokeMini::getRegisterSheet() {
|
|||
return regCheatSheetPokeMini;
|
||||
}
|
||||
|
||||
void DivPlatformPokeMini::rWrite(unsigned char addr, unsigned char val) {
|
||||
if (addr<128) regPool[addr]=val;
|
||||
switch (addr) {
|
||||
case 0x1c:
|
||||
// ignore
|
||||
break;
|
||||
case 0x1d:
|
||||
// ignore
|
||||
break;
|
||||
case 0x48: case 0x49:
|
||||
on=val&4;
|
||||
if (val&2) pos=0;
|
||||
break;
|
||||
case 0x4a:
|
||||
preset=(preset&0xff00)|val;
|
||||
break;
|
||||
case 0x4b:
|
||||
preset=(preset&0xff)|(val<<8);
|
||||
break;
|
||||
case 0x4c:
|
||||
pivot=(pivot&0xff00)|val;
|
||||
break;
|
||||
case 0x4d:
|
||||
pivot=(pivot&0xff)|(val<<8);
|
||||
break;
|
||||
case 0x71:
|
||||
vol=val&3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformPokeMini::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
int out=0;
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
|
|
@ -72,7 +116,7 @@ void DivPlatformPokeMini::tick(bool sysTick) {
|
|||
chan[i].std.next();
|
||||
if (chan[i].std.vol.had) {
|
||||
chan[i].outVol=VOL_SCALE_LINEAR(chan[i].vol,chan[i].std.vol.val,2);
|
||||
vol=(chan[i].outVol==2)?3:chan[i].outVol;
|
||||
rWrite(0x71,(chan[i].outVol==2)?3:chan[i].outVol);
|
||||
}
|
||||
if (NEW_ARP_STRAT) {
|
||||
chan[i].handleArp();
|
||||
|
|
@ -100,13 +144,16 @@ void DivPlatformPokeMini::tick(bool sysTick) {
|
|||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||
if (chan[i].keyOn) {
|
||||
on=true;
|
||||
rWrite(0x48,4);
|
||||
}
|
||||
if (chan[i].keyOff) {
|
||||
on=false;
|
||||
rWrite(0x48,0);
|
||||
}
|
||||
preset=chan[i].freq;
|
||||
pivot=(chan[i].duty*preset)>>8;
|
||||
rWrite(0x4a,chan[i].freq&0xff);
|
||||
rWrite(0x4b,chan[i].freq>>8);
|
||||
int pvt=(chan[i].duty*chan[i].freq)>>8;
|
||||
rWrite(0x4c,pvt&0xff);
|
||||
rWrite(0x4d,pvt>>8);
|
||||
if (chan[i].keyOn) chan[i].keyOn=false;
|
||||
if (chan[i].keyOff) chan[i].keyOff=false;
|
||||
chan[i].freqChanged=false;
|
||||
|
|
@ -122,7 +169,7 @@ int DivPlatformPokeMini::dispatch(DivCommand c) {
|
|||
chan[c.chan].freqChanged=true;
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
vol=(chan[c.chan].outVol==2)?3:chan[c.chan].outVol;
|
||||
rWrite(0x71,(chan[c.chan].outVol==2)?3:chan[c.chan].outVol);
|
||||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_POKEMINI));
|
||||
|
|
@ -151,7 +198,7 @@ int DivPlatformPokeMini::dispatch(DivCommand c) {
|
|||
chan[c.chan].outVol=c.value;
|
||||
}
|
||||
if (chan[c.chan].active) {
|
||||
on=chan[c.chan].vol;
|
||||
rWrite(0x71,(chan[c.chan].outVol==2)?3:chan[c.chan].outVol);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -186,14 +233,13 @@ int DivPlatformPokeMini::dispatch(DivCommand c) {
|
|||
break;
|
||||
}
|
||||
case DIV_CMD_LEGATO:
|
||||
if (c.chan==3) break;
|
||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+((HACKY_LEGATO_MESS)?(chan[c.chan].std.arp.val):(0)));
|
||||
chan[c.chan].freqChanged=true;
|
||||
chan[c.chan].note=c.value;
|
||||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_BEEPER));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_POKEMINI));
|
||||
}
|
||||
if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will && !NEW_ARP_STRAT) chan[c.chan].baseFreq=NOTE_PERIODIC(chan[c.chan].note);
|
||||
chan[c.chan].inPorta=c.value;
|
||||
|
|
@ -239,18 +285,11 @@ DivDispatchOscBuffer* DivPlatformPokeMini::getOscBuffer(int ch) {
|
|||
}
|
||||
|
||||
unsigned char* DivPlatformPokeMini::getRegisterPool() {
|
||||
if (on) {
|
||||
regPool[0]=preset;
|
||||
regPool[1]=preset>>8;
|
||||
} else {
|
||||
regPool[0]=0;
|
||||
regPool[1]=0;
|
||||
}
|
||||
return regPool;
|
||||
}
|
||||
|
||||
int DivPlatformPokeMini::getRegisterPoolSize() {
|
||||
return 2;
|
||||
return 128;
|
||||
}
|
||||
|
||||
void DivPlatformPokeMini::reset() {
|
||||
|
|
@ -272,7 +311,7 @@ void DivPlatformPokeMini::reset() {
|
|||
pivot=0;
|
||||
elapsedMain=0;
|
||||
|
||||
memset(regPool,0,2);
|
||||
memset(regPool,0,128);
|
||||
}
|
||||
|
||||
bool DivPlatformPokeMini::keyOffAffectsArp(int ch) {
|
||||
|
|
@ -294,11 +333,11 @@ void DivPlatformPokeMini::notifyInsDeletion(void* ins) {
|
|||
}
|
||||
|
||||
void DivPlatformPokeMini::poke(unsigned int addr, unsigned short val) {
|
||||
// ???
|
||||
rWrite(addr,val);
|
||||
}
|
||||
|
||||
void DivPlatformPokeMini::poke(std::vector<DivRegWrite>& wlist) {
|
||||
// ???
|
||||
for (DivRegWrite& i: wlist) rWrite(i.addr,i.val);
|
||||
}
|
||||
|
||||
int DivPlatformPokeMini::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) {
|
||||
|
|
|
|||
|
|
@ -37,9 +37,11 @@ class DivPlatformPokeMini: public DivDispatch {
|
|||
int pos;
|
||||
unsigned char timerScale, vol;
|
||||
unsigned short preset, pivot;
|
||||
unsigned char regPool[2];
|
||||
unsigned char regPool[128];
|
||||
unsigned short elapsedMain;
|
||||
|
||||
void rWrite(unsigned char addr, unsigned char val);
|
||||
|
||||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,14 @@ void DivPlatformPOKEY::acquire(short* bufL, short* bufR, size_t start, size_t le
|
|||
}
|
||||
|
||||
mzpokeysnd_process_16(&pokey,&bufL[h],1);
|
||||
|
||||
if (++oscBufDelay>=14) {
|
||||
oscBufDelay=0;
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=pokey.outvol_0<<11;
|
||||
oscBuf[1]->data[oscBuf[1]->needle++]=pokey.outvol_1<<11;
|
||||
oscBuf[2]->data[oscBuf[2]->needle++]=pokey.outvol_2<<11;
|
||||
oscBuf[3]->data[oscBuf[3]->needle++]=pokey.outvol_3<<11;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -409,7 +417,7 @@ void DivPlatformPOKEY::setFlags(const DivConfig& flags) {
|
|||
CHECK_CUSTOM_CLOCK;
|
||||
rate=chipClock;
|
||||
for (int i=0; i<4; i++) {
|
||||
oscBuf[i]->rate=rate/16;
|
||||
oscBuf[i]->rate=rate/14;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -425,6 +433,7 @@ int DivPlatformPOKEY::init(DivEngine* p, int channels, int sugRate, const DivCon
|
|||
parent=p;
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
oscBufDelay=0;
|
||||
for (int i=0; i<4; i++) {
|
||||
isMuted[i]=false;
|
||||
oscBuf[i]=new DivDispatchOscBuffer;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ class DivPlatformPOKEY: public DivDispatch {
|
|||
std::queue<QueuedWrite> writes;
|
||||
unsigned char audctl;
|
||||
bool audctlChanged;
|
||||
unsigned char oscBufDelay;
|
||||
PokeyState pokey;
|
||||
unsigned char regPool[16];
|
||||
friend void putDispatchChip(void*,int);
|
||||
|
|
|
|||
|
|
@ -1637,23 +1637,6 @@ void Update_pokey_sound_mz(PokeyState* ps, unsigned short addr, unsigned char va
|
|||
|
||||
#define MAX_SAMPLE 152
|
||||
|
||||
void mzpokeysnd_process_8(PokeyState* ps, void* sndbuffer, int sndn)
|
||||
{
|
||||
int i;
|
||||
int nsam = sndn;
|
||||
unsigned char *buffer = (unsigned char *) sndbuffer;
|
||||
|
||||
/* if there are two pokeys, then the signal is stereo
|
||||
we assume even sndn */
|
||||
while(nsam >= 1)
|
||||
{
|
||||
buffer[0] = (unsigned char)floor(generate_sample(ps)
|
||||
* (255.0 / 2 / MAX_SAMPLE / 4 * M_PI * 0.95) + 128 + 0.5 + 0.5 * rand() / RAND_MAX - 0.25);
|
||||
buffer += 1;
|
||||
nsam -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void mzpokeysnd_process_16(PokeyState* ps, void* sndbuffer, int sndn)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -1665,7 +1648,7 @@ void mzpokeysnd_process_16(PokeyState* ps, void* sndbuffer, int sndn)
|
|||
while(nsam >= (int) 1)
|
||||
{
|
||||
buffer[0] = (short)floor(generate_sample(ps)
|
||||
* (65535.0 / 2 / MAX_SAMPLE / 4 * M_PI * 0.95) + 0.5 + 0.5 * rand() / RAND_MAX - 0.25);
|
||||
* (65535.0 / 2 / MAX_SAMPLE / 4 * M_PI * 0.95));
|
||||
buffer += 1;
|
||||
nsam -= 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,7 +149,6 @@ typedef struct stPokeyState
|
|||
int outvol_3;
|
||||
} PokeyState;
|
||||
|
||||
void mzpokeysnd_process_8(PokeyState* ps, void* sndbuffer, int sndn);
|
||||
void mzpokeysnd_process_16(PokeyState* ps, void* sndbuffer, int sndn);
|
||||
void Update_pokey_sound_mz(PokeyState* ps, unsigned short addr, unsigned char val, unsigned char gain);
|
||||
|
||||
|
|
|
|||
|
|
@ -64,10 +64,10 @@ enum DivSystem {
|
|||
DIV_SYSTEM_FDS,
|
||||
DIV_SYSTEM_MMC5,
|
||||
DIV_SYSTEM_N163,
|
||||
DIV_SYSTEM_OPN,
|
||||
DIV_SYSTEM_OPN_EXT,
|
||||
DIV_SYSTEM_PC98,
|
||||
DIV_SYSTEM_PC98_EXT,
|
||||
DIV_SYSTEM_YM2203,
|
||||
DIV_SYSTEM_YM2203_EXT,
|
||||
DIV_SYSTEM_YM2608,
|
||||
DIV_SYSTEM_YM2608_EXT,
|
||||
DIV_SYSTEM_OPL,
|
||||
DIV_SYSTEM_OPL2,
|
||||
DIV_SYSTEM_OPL3,
|
||||
|
|
@ -111,15 +111,20 @@ enum DivSystem {
|
|||
DIV_SYSTEM_NAMCO,
|
||||
DIV_SYSTEM_NAMCO_15XX,
|
||||
DIV_SYSTEM_NAMCO_CUS30,
|
||||
DIV_SYSTEM_YM2612_FRAC,
|
||||
DIV_SYSTEM_YM2612_FRAC_EXT,
|
||||
DIV_SYSTEM_YM2612_DUALPCM,
|
||||
DIV_SYSTEM_YM2612_DUALPCM_EXT,
|
||||
DIV_SYSTEM_MSM5232,
|
||||
DIV_SYSTEM_T6W28,
|
||||
DIV_SYSTEM_K007232,
|
||||
DIV_SYSTEM_GA20,
|
||||
DIV_SYSTEM_PCM_DAC,
|
||||
DIV_SYSTEM_PONG,
|
||||
DIV_SYSTEM_DUMMY
|
||||
DIV_SYSTEM_DUMMY,
|
||||
DIV_SYSTEM_YM2612_CSM,
|
||||
DIV_SYSTEM_YM2610_CSM,
|
||||
DIV_SYSTEM_YM2610B_CSM,
|
||||
DIV_SYSTEM_YM2203_CSM,
|
||||
DIV_SYSTEM_YM2608_CSM
|
||||
};
|
||||
|
||||
struct DivSubSong {
|
||||
|
|
|
|||
|
|
@ -1006,7 +1006,7 @@ void DivEngine::registerSystems() {
|
|||
}
|
||||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_OPN]=new DivSysDef(
|
||||
sysDefs[DIV_SYSTEM_YM2203]=new DivSysDef(
|
||||
"Yamaha YM2203 (OPN)", NULL, 0x8d, 0, 6, true, true, 0x151, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
|
||||
"cost-reduced version of the OPM with a different register layout and no stereo...\n...but it has a built-in AY-3-8910! (actually an YM2149)",
|
||||
{"FM 1", "FM 2", "FM 3", "PSG 1", "PSG 2", "PSG 3"},
|
||||
|
|
@ -1018,7 +1018,7 @@ void DivEngine::registerSystems() {
|
|||
fmOPNPostEffectHandlerMap
|
||||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_OPN_EXT]=new DivSysDef(
|
||||
sysDefs[DIV_SYSTEM_YM2203_EXT]=new DivSysDef(
|
||||
"Yamaha YM2203 (OPN) Extended Channel 3", NULL, 0xb6, 0, 9, true, true, 0x151, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
|
||||
"cost-reduced version of the OPM with a different register layout and no stereo...\n...but it has a built-in AY-3-8910! (actually an YM2149)\nthis one is in Extended Channel mode, which turns the third FM channel into four operators with independent notes/frequencies",
|
||||
{"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "PSG 1", "PSG 2", "PSG 3"},
|
||||
|
|
@ -1030,7 +1030,19 @@ void DivEngine::registerSystems() {
|
|||
fmOPNPostEffectHandlerMap
|
||||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_PC98]=new DivSysDef(
|
||||
sysDefs[DIV_SYSTEM_YM2203_CSM]=new DivSysDef(
|
||||
"Yamaha YM2203 (OPN) CSM", NULL, 0xc3, 0, 10, true, true, 0x151, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
|
||||
"cost-reduced version of the OPM with a different register layout and no stereo...\n...but it has a built-in AY-3-8910! (actually an YM2149)\nCSM blah blah",
|
||||
{"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "CSM Timer", "PSG 1", "PSG 2", "PSG 3"},
|
||||
{"F1", "F2", "O1", "O2", "O3", "O4", "CSM", "S1", "S2", "S3"},
|
||||
{DIV_CH_FM, DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_NOISE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE},
|
||||
{DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY},
|
||||
{},
|
||||
fmEffectHandlerMap,
|
||||
fmOPNPostEffectHandlerMap
|
||||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_YM2608]=new DivSysDef(
|
||||
"Yamaha YM2608 (OPNA)", NULL, 0x8e, 0, 16, true, true, 0x151, false, (1U<<DIV_SAMPLE_DEPTH_ADPCM_B)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
|
||||
"OPN but twice the FM channels, stereo makes a come-back and has rhythm and ADPCM channels.",
|
||||
{"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "Square 1", "Square 2", "Square 3", "Kick", "Snare", "Top", "HiHat", "Tom", "Rim", "ADPCM"},
|
||||
|
|
@ -1042,7 +1054,7 @@ void DivEngine::registerSystems() {
|
|||
fmOPNAPostEffectHandlerMap
|
||||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_PC98_EXT]=new DivSysDef(
|
||||
sysDefs[DIV_SYSTEM_YM2608_EXT]=new DivSysDef(
|
||||
"Yamaha YM2608 (OPNA) Extended Channel 3", NULL, 0xb7, 0, 19, true, true, 0x151, false, (1U<<DIV_SAMPLE_DEPTH_ADPCM_B)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
|
||||
"OPN but twice the FM channels, stereo makes a come-back and has rhythm and ADPCM channels.\nthis one is in Extended Channel mode, which turns the third FM channel into four operators with independent notes/frequencies",
|
||||
{"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "FM 4", "FM 5", "FM 6", "Square 1", "Square 2", "Square 3", "Kick", "Snare", "Top", "HiHat", "Tom", "Rim", "ADPCM"},
|
||||
|
|
@ -1054,6 +1066,18 @@ void DivEngine::registerSystems() {
|
|||
fmOPNAPostEffectHandlerMap
|
||||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_YM2608_CSM]=new DivSysDef(
|
||||
"Yamaha YM2608 (OPNA) CSM", NULL, 0xc4, 0, 20, true, true, 0x151, false, (1U<<DIV_SAMPLE_DEPTH_ADPCM_B)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
|
||||
"OPN but twice the FM channels, stereo makes a come-back and has rhythm and ADPCM channels.\nCSM blah blah",
|
||||
{"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "FM 4", "FM 5", "FM 6", "CSM Timer", "Square 1", "Square 2", "Square 3", "Kick", "Snare", "Top", "HiHat", "Tom", "Rim", "ADPCM"},
|
||||
{"F1", "F2", "O1", "O2", "O3", "O4", "F4", "F5", "F6", "CSM", "S1", "S2", "S3", "BD", "SD", "TP", "HH", "TM", "RM", "P"},
|
||||
{DIV_CH_FM, DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_PCM},
|
||||
{DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMB},
|
||||
{DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_AMIGA},
|
||||
fmEffectHandlerMap,
|
||||
fmOPNAPostEffectHandlerMap
|
||||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_OPL]=new DivSysDef(
|
||||
"Yamaha YM3526 (OPL)", NULL, 0x8f, 0, 9, true, false, 0x151, false, 0,
|
||||
"OPN, but what if you only had two operators, no stereo, no detune and a lower ADSR parameter range?",
|
||||
|
|
@ -1119,7 +1143,7 @@ void DivEngine::registerSystems() {
|
|||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_POKEY]=new DivSysDef(
|
||||
"POKEY", NULL, 0x94, 0, 4, false, true, 0, false, 0,
|
||||
"POKEY", NULL, 0x94, 0, 4, false, true, 0x161, false, 0,
|
||||
"TIA, but better and more flexible.\nused in the Atari 8-bit family of computers (400/800/XL/XE).",
|
||||
{"Channel 1", "Channel 2", "Channel 3", "Channel 4"},
|
||||
{"CH1", "CH2", "CH3", "CH4"},
|
||||
|
|
@ -1262,6 +1286,18 @@ void DivEngine::registerSystems() {
|
|||
fmOPN2PostEffectHandlerMap
|
||||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_YM2612_CSM]=new DivSysDef(
|
||||
"Yamaha YM2612 (OPN2) CSM", NULL, 0xc1, 0, 10, true, false, 0x150, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
|
||||
"this chip is mostly known for being in the Sega Genesis (but it also was on the FM Towns computer).\nthis one includes CSM mode control for special effects on Channel 3.",
|
||||
{"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "FM 4", "FM 5", "FM 6", "CSM Timer"},
|
||||
{"F1", "F2", "O1", "O2", "O3", "O4", "F4", "F5", "F6", "CSM"},
|
||||
{DIV_CH_FM, DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE},
|
||||
{DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM},
|
||||
{DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_AMIGA, DIV_INS_NULL},
|
||||
fmOPN2EffectHandlerMap,
|
||||
fmOPN2PostEffectHandlerMap
|
||||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_SCC]=new DivSysDef(
|
||||
"Konami SCC", NULL, 0xa1, 0, 5, false, true, 0x161, false, 0,
|
||||
"a wavetable chip made by Konami for use with the MSX.\nthe last channel shares its wavetable with the previous one though.",
|
||||
|
|
@ -1333,6 +1369,18 @@ void DivEngine::registerSystems() {
|
|||
fmOPNAPostEffectHandlerMap
|
||||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_YM2610_CSM]=new DivSysDef(
|
||||
"Yamaha YM2610 (OPNB) CSM", NULL, 0xc2, 0, 18, true, false, 0x151, false, (1U<<DIV_SAMPLE_DEPTH_ADPCM_A)|(1U<<DIV_SAMPLE_DEPTH_ADPCM_B)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
|
||||
"this chip was used in SNK's Neo Geo arcade board and video game console.\nit's like OPNA but the rhythm channels are ADPCM channels and two FM channels went missing.\nthis one includes CSM mode control for special effects on Channel 2.",
|
||||
{"FM 1", "FM 2 OP1", "FM 2 OP2", "FM 2 OP3", "FM 2 OP4", "FM 3", "FM 4", "CSM Timer", "PSG 1", "PSG 2", "PSG 3", "ADPCM-A 1", "ADPCM-A 2", "ADPCM-A 3", "ADPCM-A 4", "ADPCM-A 5", "ADPCM-A 6", "ADPCM-B"},
|
||||
{"F1", "O1", "O2", "O3", "O4", "F3", "F4", "CSM", "S1", "S2", "S3", "P1", "P2", "P3", "P4", "P5", "P6", "B"},
|
||||
{DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
||||
{DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMB},
|
||||
{DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA},
|
||||
fmEffectHandlerMap,
|
||||
fmOPNAPostEffectHandlerMap
|
||||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_OPLL_DRUMS]=new DivSysDef(
|
||||
"Yamaha YM2413 (OPLL) with drums", NULL, 0xa7, 0, 11, true, false, 0x150, false, 0,
|
||||
"the OPLL chips but with drums mode turned on.",
|
||||
|
|
@ -1410,6 +1458,18 @@ void DivEngine::registerSystems() {
|
|||
fmOPNAPostEffectHandlerMap
|
||||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_YM2610B_CSM]=new DivSysDef(
|
||||
"Yamaha YM2610B (OPNB2) CSM", NULL, 0xc5, 0, 20, true, false, 0x151, false, (1U<<DIV_SAMPLE_DEPTH_ADPCM_A)|(1U<<DIV_SAMPLE_DEPTH_ADPCM_B)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
|
||||
"so Taito asked Yamaha if they could get the two missing FM channels back, and Yamaha gladly provided them with this chip.\nCSM blah blah",
|
||||
{"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "FM 4", "FM 5", "FM 6", "CSM Timer", "PSG 1", "PSG 2", "PSG 3", "ADPCM-A 1", "ADPCM-A 2", "ADPCM-A 3", "ADPCM-A 4", "ADPCM-A 5", "ADPCM-A 6", "ADPCM-B"},
|
||||
{"F1", "F2", "O1", "O2", "O3", "O4", "F4", "F5", "F6", "CSM", "S1", "S2", "S3", "P1", "P2", "P3", "P4", "P5", "P6", "B"},
|
||||
{DIV_CH_FM, DIV_CH_FM, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
||||
{DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_FM, DIV_INS_AY, DIV_INS_AY, DIV_INS_AY, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMA, DIV_INS_ADPCMB},
|
||||
{DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_NULL, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA},
|
||||
fmEffectHandlerMap,
|
||||
fmOPNAPostEffectHandlerMap
|
||||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_SEGAPCM_COMPAT]=new DivSysDef(
|
||||
"SegaPCM (compatible 5-channel mode)", NULL, 0xa9, 0, 5, false, true, 0x151, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
|
||||
"this is the same thing as SegaPCM, but only exposes 5 of the channels for compatibility with DefleMask.",
|
||||
|
|
@ -1652,7 +1712,7 @@ void DivEngine::registerSystems() {
|
|||
}
|
||||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_YM2612_FRAC]=new DivSysDef(
|
||||
sysDefs[DIV_SYSTEM_YM2612_DUALPCM]=new DivSysDef(
|
||||
"Yamaha YM2612 (OPN2) with DualPCM", NULL, 0xbe, 0, 7, true, false, 0x150, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
|
||||
"this chip is mostly known for being in the Sega Genesis (but it also was on the FM Towns computer).\nthis system uses software mixing to provide two sample channels.",
|
||||
{"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6/PCM 1", "PCM 2"},
|
||||
|
|
@ -1664,7 +1724,7 @@ void DivEngine::registerSystems() {
|
|||
fmOPN2PostEffectHandlerMap
|
||||
);
|
||||
|
||||
sysDefs[DIV_SYSTEM_YM2612_FRAC_EXT]=new DivSysDef(
|
||||
sysDefs[DIV_SYSTEM_YM2612_DUALPCM_EXT]=new DivSysDef(
|
||||
"Yamaha YM2612 (OPN2) Extended Channel 3 with DualPCM and CSM", NULL, 0xbd, 0, 11, true, false, 0x150, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
|
||||
"this chip is mostly known for being in the Sega Genesis (but it also was on the FM Towns computer).\nthis system uses software mixing to provide two sample channels.\nthis one is in Extended Channel mode, which turns the third FM channel into four operators with independent notes/frequencies.",
|
||||
{"FM 1", "FM 2", "FM 3 OP1", "FM 3 OP2", "FM 3 OP3", "FM 3 OP4", "FM 4", "FM 5", "FM 6/PCM 1", "PCM 2", "CSM Timer"},
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
|||
switch (sys) {
|
||||
case DIV_SYSTEM_YM2612:
|
||||
case DIV_SYSTEM_YM2612_EXT:
|
||||
case DIV_SYSTEM_YM2612_FRAC:
|
||||
case DIV_SYSTEM_YM2612_FRAC_EXT:
|
||||
case DIV_SYSTEM_YM2612_DUALPCM:
|
||||
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
|
||||
for (int i=0; i<3; i++) { // set SL and RR to highest
|
||||
w->writeC(2|baseAddr1);
|
||||
w->writeC(0x80+i);
|
||||
|
|
@ -252,8 +252,8 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
|||
w->writeC(0);
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_OPN:
|
||||
case DIV_SYSTEM_OPN_EXT:
|
||||
case DIV_SYSTEM_YM2203:
|
||||
case DIV_SYSTEM_YM2203_EXT:
|
||||
for (int i=0; i<3; i++) { // set SL and RR to highest
|
||||
w->writeC(5|baseAddr1);
|
||||
w->writeC(0x80+i);
|
||||
|
|
@ -333,6 +333,13 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
|||
w->writeC(0);
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_POKEY:
|
||||
for (int i=0; i<9; i++) {
|
||||
w->writeC(0xbb);
|
||||
w->writeC(i|baseAddr2);
|
||||
w->writeC(0);
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_LYNX:
|
||||
w->writeC(0x4e);
|
||||
w->writeC(0x44);
|
||||
|
|
@ -566,8 +573,8 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
|||
switch (sys) {
|
||||
case DIV_SYSTEM_YM2612:
|
||||
case DIV_SYSTEM_YM2612_EXT:
|
||||
case DIV_SYSTEM_YM2612_FRAC:
|
||||
case DIV_SYSTEM_YM2612_FRAC_EXT:
|
||||
case DIV_SYSTEM_YM2612_DUALPCM:
|
||||
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
|
||||
switch (write.addr>>8) {
|
||||
case 0: // port 0
|
||||
w->writeC(2|baseAddr1);
|
||||
|
|
@ -659,14 +666,14 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_OPN:
|
||||
case DIV_SYSTEM_OPN_EXT:
|
||||
case DIV_SYSTEM_YM2203:
|
||||
case DIV_SYSTEM_YM2203_EXT:
|
||||
w->writeC(5|baseAddr1);
|
||||
w->writeC(write.addr&0xff);
|
||||
w->writeC(write.val);
|
||||
break;
|
||||
case DIV_SYSTEM_PC98:
|
||||
case DIV_SYSTEM_PC98_EXT:
|
||||
case DIV_SYSTEM_YM2608:
|
||||
case DIV_SYSTEM_YM2608_EXT:
|
||||
switch (write.addr>>8) {
|
||||
case 0: // port 0
|
||||
w->writeC(6|baseAddr1);
|
||||
|
|
@ -698,6 +705,11 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
|||
w->writeC(baseAddr2|(write.addr&0xff));
|
||||
w->writeC(write.val);
|
||||
break;
|
||||
case DIV_SYSTEM_POKEY:
|
||||
w->writeC(0xbb);
|
||||
w->writeC(baseAddr2|(write.addr&0x0f));
|
||||
w->writeC(write.val&0xff);
|
||||
break;
|
||||
case DIV_SYSTEM_LYNX:
|
||||
w->writeC(0x4e);
|
||||
w->writeC(write.addr&0xff);
|
||||
|
|
@ -1168,8 +1180,8 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
break;
|
||||
case DIV_SYSTEM_YM2612:
|
||||
case DIV_SYSTEM_YM2612_EXT:
|
||||
case DIV_SYSTEM_YM2612_FRAC:
|
||||
case DIV_SYSTEM_YM2612_FRAC_EXT:
|
||||
case DIV_SYSTEM_YM2612_DUALPCM:
|
||||
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
|
||||
if (!hasOPN2) {
|
||||
hasOPN2=disCont[i].dispatch->chipClock;
|
||||
willExport[i]=true;
|
||||
|
|
@ -1192,8 +1204,8 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
howManyChips++;
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_OPN:
|
||||
case DIV_SYSTEM_OPN_EXT:
|
||||
case DIV_SYSTEM_YM2203:
|
||||
case DIV_SYSTEM_YM2203_EXT:
|
||||
if (!hasOPN) {
|
||||
hasOPN=disCont[i].dispatch->chipClock;
|
||||
willExport[i]=true;
|
||||
|
|
@ -1205,8 +1217,8 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
howManyChips++;
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_PC98:
|
||||
case DIV_SYSTEM_PC98_EXT:
|
||||
case DIV_SYSTEM_YM2608:
|
||||
case DIV_SYSTEM_YM2608_EXT:
|
||||
if (!hasOPNA) {
|
||||
hasOPNA=disCont[i].dispatch->chipClock;
|
||||
willExport[i]=true;
|
||||
|
|
@ -1246,6 +1258,17 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
howManyChips++;
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_POKEY:
|
||||
if (!hasPOKEY) {
|
||||
hasPOKEY=disCont[i].dispatch->chipClock;
|
||||
willExport[i]=true;
|
||||
} else if (!(hasPOKEY&0x40000000)) {
|
||||
isSecond[i]=true;
|
||||
willExport[i]=true;
|
||||
hasPOKEY|=0x40000000;
|
||||
howManyChips++;
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_LYNX:
|
||||
if (!hasLynx) {
|
||||
hasLynx=disCont[i].dispatch->chipClock;
|
||||
|
|
@ -1825,8 +1848,8 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
switch (song.system[i]) {
|
||||
case DIV_SYSTEM_YM2612:
|
||||
case DIV_SYSTEM_YM2612_EXT:
|
||||
case DIV_SYSTEM_YM2612_FRAC:
|
||||
case DIV_SYSTEM_YM2612_FRAC_EXT:
|
||||
case DIV_SYSTEM_YM2612_DUALPCM:
|
||||
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
|
||||
w->writeC(0x90);
|
||||
w->writeC(streamID);
|
||||
w->writeC(0x02);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue