Various corrections and fixes
Fix SN PSG pitch corrections Revive YM2612 from dead Add Game Gear stereo function finally Add OPN/A prescaler config
This commit is contained in:
parent
0c1a8bc001
commit
25af023dc6
|
@ -593,6 +593,13 @@ void DivPlatformAY8910::poke(std::vector<DivRegWrite>& wlist) {
|
||||||
for (DivRegWrite& i: wlist) immWrite(i.addr,i.val);
|
for (DivRegWrite& i: wlist) immWrite(i.addr,i.val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DivPlatformAY8910::setExtClockDiv(unsigned int eclk, unsigned char ediv) {
|
||||||
|
if (extMode) {
|
||||||
|
extClock=eclk;
|
||||||
|
extDiv=ediv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DivPlatformAY8910::setFlags(unsigned int flags) {
|
void DivPlatformAY8910::setFlags(unsigned int flags) {
|
||||||
if (extMode) {
|
if (extMode) {
|
||||||
chipClock=extClock;
|
chipClock=extClock;
|
||||||
|
|
|
@ -91,6 +91,7 @@ class DivPlatformAY8910: public DivDispatch {
|
||||||
friend void putDispatchChan(void*,int,int);
|
friend void putDispatchChan(void*,int,int);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void setExtClockDiv(unsigned int eclk=COLOR_NTSC, unsigned char ediv=8);
|
||||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||||
int dispatch(DivCommand c);
|
int dispatch(DivCommand c);
|
||||||
void* getChanState(int chan);
|
void* getChanState(int chan);
|
||||||
|
|
|
@ -26,16 +26,16 @@
|
||||||
|
|
||||||
class DivPlatformOPM: public DivPlatformFMBase {
|
class DivPlatformOPM: public DivPlatformFMBase {
|
||||||
protected:
|
protected:
|
||||||
const unsigned char ADDR_MULT_DT=0x40;
|
const unsigned short ADDR_MULT_DT=0x40;
|
||||||
const unsigned char ADDR_TL=0x60;
|
const unsigned short ADDR_TL=0x60;
|
||||||
const unsigned char ADDR_RS_AR=0x80;
|
const unsigned short ADDR_RS_AR=0x80;
|
||||||
const unsigned char ADDR_AM_DR=0xa0;
|
const unsigned short ADDR_AM_DR=0xa0;
|
||||||
const unsigned char ADDR_DT2_D2R=0xc0;
|
const unsigned short ADDR_DT2_D2R=0xc0;
|
||||||
const unsigned char ADDR_SL_RR=0xe0;
|
const unsigned short ADDR_SL_RR=0xe0;
|
||||||
const unsigned char ADDR_NOTE=0x28;
|
const unsigned short ADDR_NOTE=0x28;
|
||||||
const unsigned char ADDR_KF=0x30;
|
const unsigned short ADDR_KF=0x30;
|
||||||
const unsigned char ADDR_FMS_AMS=0x38;
|
const unsigned short ADDR_FMS_AMS=0x38;
|
||||||
const unsigned char ADDR_LR_FB_ALG=0x20;
|
const unsigned short ADDR_LR_FB_ALG=0x20;
|
||||||
|
|
||||||
const unsigned short opOffs[4]={
|
const unsigned short opOffs[4]={
|
||||||
0x00, 0x08, 0x10, 0x18
|
0x00, 0x08, 0x10, 0x18
|
||||||
|
|
|
@ -85,27 +85,27 @@
|
||||||
|
|
||||||
class DivPlatformOPN: public DivPlatformFMBase {
|
class DivPlatformOPN: public DivPlatformFMBase {
|
||||||
protected:
|
protected:
|
||||||
const unsigned char ADDR_MULT_DT=0x30;
|
const unsigned short ADDR_MULT_DT=0x30;
|
||||||
const unsigned char ADDR_TL=0x40;
|
const unsigned short ADDR_TL=0x40;
|
||||||
const unsigned char ADDR_RS_AR=0x50;
|
const unsigned short ADDR_RS_AR=0x50;
|
||||||
const unsigned char ADDR_AM_DR=0x60;
|
const unsigned short ADDR_AM_DR=0x60;
|
||||||
const unsigned char ADDR_DT2_D2R=0x70;
|
const unsigned short ADDR_DT2_D2R=0x70;
|
||||||
const unsigned char ADDR_SL_RR=0x80;
|
const unsigned short ADDR_SL_RR=0x80;
|
||||||
const unsigned char ADDR_SSG=0x90;
|
const unsigned short ADDR_SSG=0x90;
|
||||||
const unsigned char ADDR_FREQ=0xa0;
|
const unsigned short ADDR_FREQ=0xa0;
|
||||||
const unsigned char ADDR_FREQH=0xa4;
|
const unsigned short ADDR_FREQH=0xa4;
|
||||||
const unsigned char ADDR_FB_ALG=0xb0;
|
const unsigned short ADDR_FB_ALG=0xb0;
|
||||||
const unsigned char ADDR_LRAF=0xb4;
|
const unsigned short ADDR_LRAF=0xb4;
|
||||||
|
|
||||||
const unsigned short opOffs[4]={
|
const unsigned short opOffs[4]={
|
||||||
0x00, 0x04, 0x08, 0x0c
|
0x00, 0x04, 0x08, 0x0c
|
||||||
};
|
};
|
||||||
|
|
||||||
double fmFreqBase;
|
double fmFreqBase;
|
||||||
double fmDivBase;
|
unsigned int fmDivBase;
|
||||||
unsigned char ayDiv;
|
unsigned int ayDiv;
|
||||||
|
|
||||||
DivPlatformOPN(double f=9440540.0, double d=72, unsigned char a=32):
|
DivPlatformOPN(double f=9440540.0, unsigned int d=72, unsigned int a=32):
|
||||||
DivPlatformFMBase(),
|
DivPlatformFMBase(),
|
||||||
fmFreqBase(f),
|
fmFreqBase(f),
|
||||||
fmDivBase(d),
|
fmDivBase(d),
|
||||||
|
|
|
@ -99,13 +99,6 @@ class DivPlatformGenesis: public DivPlatformOPN {
|
||||||
Channel chan[10];
|
Channel chan[10];
|
||||||
DivDispatchOscBuffer* oscBuf[10];
|
DivDispatchOscBuffer* oscBuf[10];
|
||||||
bool isMuted[10];
|
bool isMuted[10];
|
||||||
struct QueuedWrite {
|
|
||||||
unsigned short addr;
|
|
||||||
unsigned char val;
|
|
||||||
bool addrOrVal;
|
|
||||||
QueuedWrite(unsigned short a, unsigned char v): addr(a), val(v), addrOrVal(false) {}
|
|
||||||
};
|
|
||||||
std::deque<QueuedWrite> writes;
|
|
||||||
ym3438_t fm;
|
ym3438_t fm;
|
||||||
|
|
||||||
ymfm::ym2612* fm_ymfm;
|
ymfm::ym2612* fm_ymfm;
|
||||||
|
|
|
@ -35,7 +35,7 @@ const char* regCheatSheetGG[]={
|
||||||
};
|
};
|
||||||
|
|
||||||
const char** DivPlatformSMS::getRegisterSheet() {
|
const char** DivPlatformSMS::getRegisterSheet() {
|
||||||
return isStereo()?regCheatSheetGG:regCheatSheetSN;
|
return stereo?regCheatSheetGG:regCheatSheetSN;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* DivPlatformSMS::getEffectName(unsigned char effect) {
|
const char* DivPlatformSMS::getEffectName(unsigned char effect) {
|
||||||
|
@ -74,7 +74,7 @@ void DivPlatformSMS::acquire_nuked(short* bufL, short* bufR, size_t start, size_
|
||||||
o=YMPSG_GetOutput(&sn_nuked);
|
o=YMPSG_GetOutput(&sn_nuked);
|
||||||
if (o<-32768) o=-32768;
|
if (o<-32768) o=-32768;
|
||||||
if (o>32767) o=32767;
|
if (o>32767) o=32767;
|
||||||
bufL[h]=o;
|
bufL[h]=bufR[h]=o;
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
if (isMuted[i]) {
|
if (isMuted[i]) {
|
||||||
oscBuf[i]->data[oscBuf[i]->needle++]=0;
|
oscBuf[i]->data[oscBuf[i]->needle++]=0;
|
||||||
|
@ -86,13 +86,6 @@ void DivPlatformSMS::acquire_nuked(short* bufL, short* bufR, size_t start, size_
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformSMS::acquire_mame(short* bufL, short* bufR, size_t start, size_t len) {
|
void DivPlatformSMS::acquire_mame(short* bufL, short* bufR, size_t start, size_t len) {
|
||||||
if (snBufLen<len) {
|
|
||||||
snBufLen=len;
|
|
||||||
for (int i=0; i<2; i++) {
|
|
||||||
delete[] snBuf[i];
|
|
||||||
snBuf[i]=new short[snBufLen];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (!writes.empty()) {
|
while (!writes.empty()) {
|
||||||
QueuedWrite w=writes.front();
|
QueuedWrite w=writes.front();
|
||||||
if (stereo && (w.addr&1))
|
if (stereo && (w.addr&1))
|
||||||
|
@ -101,10 +94,10 @@ void DivPlatformSMS::acquire_mame(short* bufL, short* bufR, size_t start, size_t
|
||||||
sn->write(w.val);
|
sn->write(w.val);
|
||||||
writes.pop();
|
writes.pop();
|
||||||
}
|
}
|
||||||
for (size_t h=0; h<len; h++) {
|
for (size_t h=start; h<start+len; h++) {
|
||||||
short* outs[2]={
|
short* outs[2]={
|
||||||
&snBuf[0][h],
|
&bufL[h],
|
||||||
&snBuf[1][h],
|
&bufR[h]
|
||||||
};
|
};
|
||||||
sn->sound_stream_update(outs,1);
|
sn->sound_stream_update(outs,1);
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
|
@ -115,17 +108,6 @@ void DivPlatformSMS::acquire_mame(short* bufL, short* bufR, size_t start, size_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stereo) {
|
|
||||||
for (size_t i=0; i<len; i++) {
|
|
||||||
bufL[i+start]=snBuf[0][i];
|
|
||||||
bufR[i+start]=snBuf[1][i];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (size_t i=0; i<len; i++) {
|
|
||||||
bufL[i+start]=snBuf[0][i];
|
|
||||||
bufR[i+start]=bufL[i+start];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformSMS::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
void DivPlatformSMS::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||||
|
@ -138,7 +120,7 @@ void DivPlatformSMS::acquire(short* bufL, short* bufR, size_t start, size_t len)
|
||||||
|
|
||||||
void DivPlatformSMS::tick(bool sysTick) {
|
void DivPlatformSMS::tick(bool sysTick) {
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
int CHIP_DIVIDER=64;
|
int CHIP_DIVIDER=toneDivider;
|
||||||
if (i==3) CHIP_DIVIDER=noiseDivider;
|
if (i==3) CHIP_DIVIDER=noiseDivider;
|
||||||
chan[i].std.next();
|
chan[i].std.next();
|
||||||
if (chan[i].std.vol.had) {
|
if (chan[i].std.vol.had) {
|
||||||
|
@ -185,10 +167,10 @@ void DivPlatformSMS::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isStereo()) {
|
if (stereo) {
|
||||||
if (chan[i].std.panL.had) {
|
if (chan[i].std.panL.had) {
|
||||||
lastPan&=~(0x11<<i);
|
lastPan&=~(0x11<<i);
|
||||||
lastPan|=((chan[i].std.panL.val&1)<<(i+4))|(((chan[i].std.panL.val>>1)&1)<<i);
|
lastPan|=((chan[i].std.panL.val&1)<<i)|(((chan[i].std.panL.val>>1)&1)<<(i+4));
|
||||||
rWrite(1,lastPan);
|
rWrite(1,lastPan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,7 +186,7 @@ void DivPlatformSMS::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
for (int i=0; i<3; i++) {
|
for (int i=0; i<3; i++) {
|
||||||
if (chan[i].freqChanged) {
|
if (chan[i].freqChanged) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2,chipClock,64);
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2,chipClock,toneDivider);
|
||||||
if (chan[i].freq>1023) chan[i].freq=1023;
|
if (chan[i].freq>1023) chan[i].freq=1023;
|
||||||
if (chan[i].freq<8) chan[i].freq=1;
|
if (chan[i].freq<8) chan[i].freq=1;
|
||||||
//if (chan[i].actualNote>0x5d) chan[i].freq=0x01;
|
//if (chan[i].actualNote>0x5d) chan[i].freq=0x01;
|
||||||
|
@ -263,7 +245,7 @@ void DivPlatformSMS::tick(bool sysTick) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformSMS::dispatch(DivCommand c) {
|
int DivPlatformSMS::dispatch(DivCommand c) {
|
||||||
int CHIP_DIVIDER=64;
|
int CHIP_DIVIDER=toneDivider;
|
||||||
if (c.chan==3) CHIP_DIVIDER=noiseDivider;
|
if (c.chan==3) CHIP_DIVIDER=noiseDivider;
|
||||||
switch (c.cmd) {
|
switch (c.cmd) {
|
||||||
case DIV_CMD_NOTE_ON:
|
case DIV_CMD_NOTE_ON:
|
||||||
|
@ -340,11 +322,12 @@ int DivPlatformSMS::dispatch(DivCommand c) {
|
||||||
updateSNMode=true;
|
updateSNMode=true;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PANNING: {
|
case DIV_CMD_PANNING: {
|
||||||
if (isStereo()) {
|
if (stereo) {
|
||||||
|
if (c.chan>3) c.chan=3;
|
||||||
lastPan&=~(0x11<<c.chan);
|
lastPan&=~(0x11<<c.chan);
|
||||||
int pan=0;
|
int pan=0;
|
||||||
if (c.value>0) pan|=0x01;
|
if (c.value>0) pan|=0x10;
|
||||||
if (c.value2>0) pan|=0x10;
|
if (c.value2>0) pan|=0x01;
|
||||||
if (pan==0) pan=0x11;
|
if (pan==0) pan=0x11;
|
||||||
lastPan|=pan<<c.chan;
|
lastPan|=pan<<c.chan;
|
||||||
rWrite(1,lastPan);
|
rWrite(1,lastPan);
|
||||||
|
@ -420,13 +403,13 @@ void DivPlatformSMS::reset() {
|
||||||
updateSNMode=false;
|
updateSNMode=false;
|
||||||
oldValue=0xff;
|
oldValue=0xff;
|
||||||
lastPan=0xff;
|
lastPan=0xff;
|
||||||
if (isStereo()) {
|
if (stereo) {
|
||||||
rWrite(1,0xff);
|
rWrite(1,0xff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DivPlatformSMS::isStereo() {
|
bool DivPlatformSMS::isStereo() {
|
||||||
return (!nuked) && stereo;
|
return stereo;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DivPlatformSMS::keyOffAffectsArp(int ch) {
|
bool DivPlatformSMS::keyOffAffectsArp(int ch) {
|
||||||
|
@ -482,6 +465,7 @@ void DivPlatformSMS::setFlags(unsigned int flags) {
|
||||||
}
|
}
|
||||||
resetPhase=!(flags&16);
|
resetPhase=!(flags&16);
|
||||||
divider=16;
|
divider=16;
|
||||||
|
toneDivider=64;
|
||||||
noiseDivider=64;
|
noiseDivider=64;
|
||||||
if (sn!=NULL) delete sn;
|
if (sn!=NULL) delete sn;
|
||||||
switch (flags&0xcc) {
|
switch (flags&0xcc) {
|
||||||
|
@ -494,13 +478,11 @@ void DivPlatformSMS::setFlags(unsigned int flags) {
|
||||||
case 0x04: // TI SN76489
|
case 0x04: // TI SN76489
|
||||||
sn=new sn76489_device();
|
sn=new sn76489_device();
|
||||||
isRealSN=true;
|
isRealSN=true;
|
||||||
noiseDivider=60;
|
|
||||||
stereo=false;
|
stereo=false;
|
||||||
break;
|
break;
|
||||||
case 0x08: // TI+Atari
|
case 0x08: // TI+Atari
|
||||||
sn=new sn76496_base_device(0x4000, 0x0f35, 0x01, 0x02, true, false, 8, false, true);
|
sn=new sn76496_base_device(0x4000, 0x0f35, 0x01, 0x02, true, false, 8, false, true);
|
||||||
isRealSN=true;
|
isRealSN=true;
|
||||||
noiseDivider=60;
|
|
||||||
stereo=false;
|
stereo=false;
|
||||||
break;
|
break;
|
||||||
case 0x0c: // Game Gear (not fully emulated yet!)
|
case 0x0c: // Game Gear (not fully emulated yet!)
|
||||||
|
@ -511,40 +493,38 @@ void DivPlatformSMS::setFlags(unsigned int flags) {
|
||||||
case 0x40: // TI SN76489A
|
case 0x40: // TI SN76489A
|
||||||
sn=new sn76489a_device();
|
sn=new sn76489a_device();
|
||||||
isRealSN=false; // TODO
|
isRealSN=false; // TODO
|
||||||
noiseDivider=68;
|
|
||||||
stereo=false;
|
stereo=false;
|
||||||
break;
|
break;
|
||||||
case 0x44: // TI SN76496
|
case 0x44: // TI SN76496
|
||||||
sn=new sn76496_device();
|
sn=new sn76496_device();
|
||||||
isRealSN=false; // TODO
|
isRealSN=false; // TODO
|
||||||
noiseDivider=68;
|
|
||||||
stereo=false;
|
stereo=false;
|
||||||
break;
|
break;
|
||||||
case 0x48: // NCR 8496
|
case 0x48: // NCR 8496
|
||||||
sn=new ncr8496_device();
|
sn=new ncr8496_device();
|
||||||
isRealSN=false;
|
isRealSN=false;
|
||||||
noiseDivider=64;
|
|
||||||
stereo=false;
|
stereo=false;
|
||||||
break;
|
break;
|
||||||
case 0x4c: // Tandy PSSJ 3-voice sound
|
case 0x4c: // Tandy PSSJ 3-voice sound
|
||||||
sn=new pssj3_device();
|
sn=new pssj3_device();
|
||||||
isRealSN=false;
|
isRealSN=false;
|
||||||
noiseDivider=64;
|
|
||||||
stereo=false;
|
stereo=false;
|
||||||
break;
|
break;
|
||||||
case 0x80: // TI SN94624
|
case 0x80: // TI SN94624
|
||||||
sn=new sn94624_device();
|
sn=new sn94624_device();
|
||||||
isRealSN=true;
|
isRealSN=true;
|
||||||
noiseDivider=60;
|
|
||||||
stereo=false;
|
stereo=false;
|
||||||
divider=2;
|
divider=2;
|
||||||
|
toneDivider=8;
|
||||||
|
noiseDivider=8;
|
||||||
break;
|
break;
|
||||||
case 0x84: // TI SN76494
|
case 0x84: // TI SN76494
|
||||||
sn=new sn76494_device();
|
sn=new sn76494_device();
|
||||||
isRealSN=false; // TODO
|
isRealSN=false; // TODO
|
||||||
noiseDivider=68;
|
|
||||||
stereo=false;
|
stereo=false;
|
||||||
divider=2;
|
divider=2;
|
||||||
|
toneDivider=8;
|
||||||
|
noiseDivider=8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rate=chipClock/divider;
|
rate=chipClock/divider;
|
||||||
|
@ -570,8 +550,6 @@ int DivPlatformSMS::init(DivEngine* p, int channels, int sugRate, unsigned int f
|
||||||
}
|
}
|
||||||
sn=NULL;
|
sn=NULL;
|
||||||
setFlags(flags);
|
setFlags(flags);
|
||||||
snBufLen=65536;
|
|
||||||
for (int i=0; i<2; i++) snBuf[i]=new short[snBufLen];
|
|
||||||
reset();
|
reset();
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
@ -580,9 +558,6 @@ void DivPlatformSMS::quit() {
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
delete oscBuf[i];
|
delete oscBuf[i];
|
||||||
}
|
}
|
||||||
for (int i=0; i<2; i++) {
|
|
||||||
delete[] snBuf[i];
|
|
||||||
}
|
|
||||||
if (sn!=NULL) delete sn;
|
if (sn!=NULL) delete sn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,11 +59,10 @@ class DivPlatformSMS: public DivDispatch {
|
||||||
DivDispatchOscBuffer* oscBuf[4];
|
DivDispatchOscBuffer* oscBuf[4];
|
||||||
bool isMuted[4];
|
bool isMuted[4];
|
||||||
unsigned char lastPan;
|
unsigned char lastPan;
|
||||||
short* snBuf[2];
|
|
||||||
size_t snBufLen;
|
|
||||||
unsigned char oldValue;
|
unsigned char oldValue;
|
||||||
unsigned char snNoiseMode;
|
unsigned char snNoiseMode;
|
||||||
int divider=16;
|
int divider=16;
|
||||||
|
int toneDivider=64;
|
||||||
int noiseDivider=64;
|
int noiseDivider=64;
|
||||||
bool updateSNMode;
|
bool updateSNMode;
|
||||||
bool resetPhase;
|
bool resetPhase;
|
||||||
|
|
|
@ -412,6 +412,6 @@ void sn76496_base_device::sound_stream_update(short** outputs, int outLen)
|
||||||
|
|
||||||
outputs[0][sampindex]=out;
|
outputs[0][sampindex]=out;
|
||||||
if (m_stereo && (outputs[1] != nullptr))
|
if (m_stereo && (outputs[1] != nullptr))
|
||||||
outputs[1][sampindex]=out;
|
outputs[1][sampindex]=out2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -981,6 +981,10 @@ void DivPlatformYM2203::reset() {
|
||||||
|
|
||||||
extMode=false;
|
extMode=false;
|
||||||
|
|
||||||
|
// set prescaler
|
||||||
|
immWrite(0x2d,0xff);
|
||||||
|
immWrite(prescale,0xff);
|
||||||
|
|
||||||
ay->reset();
|
ay->reset();
|
||||||
ay->getRegisterWrites().clear();
|
ay->getRegisterWrites().clear();
|
||||||
ay->flushWrites();
|
ay->flushWrites();
|
||||||
|
@ -1013,7 +1017,8 @@ void DivPlatformYM2203::setSkipRegisterWrites(bool value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformYM2203::setFlags(unsigned int flags) {
|
void DivPlatformYM2203::setFlags(unsigned int flags) {
|
||||||
switch (flags&0x3f) {
|
// Clock flags
|
||||||
|
switch (flags&0x1f) {
|
||||||
default:
|
default:
|
||||||
case 0x00:
|
case 0x00:
|
||||||
chipClock=COLOR_NTSC;
|
chipClock=COLOR_NTSC;
|
||||||
|
@ -1034,10 +1039,36 @@ void DivPlatformYM2203::setFlags(unsigned int flags) {
|
||||||
chipClock=3000000.0/2.0;
|
chipClock=3000000.0/2.0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Prescaler flags
|
||||||
|
switch ((flags>>5)&0x3) {
|
||||||
|
default:
|
||||||
|
case 0x00: // /6
|
||||||
|
prescale=0x2d;
|
||||||
|
fmFreqBase=4720270.0,
|
||||||
|
fmDivBase=36,
|
||||||
|
ayDiv=16;
|
||||||
|
break;
|
||||||
|
case 0x01: // /3
|
||||||
|
prescale=0x2e;
|
||||||
|
fmFreqBase=4720270.0/2.0,
|
||||||
|
fmDivBase=18,
|
||||||
|
ayDiv=8;
|
||||||
|
break;
|
||||||
|
case 0x02: // /2
|
||||||
|
prescale=0x2f;
|
||||||
|
fmFreqBase=4720270.0/3.0,
|
||||||
|
fmDivBase=12,
|
||||||
|
ayDiv=4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
rate=fm->sample_rate(chipClock);
|
rate=fm->sample_rate(chipClock);
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
oscBuf[i]->rate=rate;
|
oscBuf[i]->rate=rate;
|
||||||
}
|
}
|
||||||
|
immWrite(0x2d,0xff);
|
||||||
|
immWrite(prescale,0xff);
|
||||||
|
ay->setExtClockDiv(chipClock,ayDiv);
|
||||||
|
ay->setFlags(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformYM2203::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
int DivPlatformYM2203::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||||
|
@ -1050,11 +1081,11 @@ int DivPlatformYM2203::init(DivEngine* p, int channels, int sugRate, unsigned in
|
||||||
}
|
}
|
||||||
fm=new ymfm::ym2203(iface);
|
fm=new ymfm::ym2203(iface);
|
||||||
fm->set_fidelity(ymfm::OPN_FIDELITY_MIN);
|
fm->set_fidelity(ymfm::OPN_FIDELITY_MIN);
|
||||||
setFlags(flags);
|
|
||||||
// YM2149, 2MHz
|
// YM2149, 2MHz
|
||||||
ay=new DivPlatformAY8910(true,chipClock,ayDiv);
|
ay=new DivPlatformAY8910(true,chipClock,ayDiv);
|
||||||
ay->init(p,3,sugRate,16);
|
ay->init(p,3,sugRate,16);
|
||||||
ay->toggleRegisterDump(true);
|
ay->toggleRegisterDump(true);
|
||||||
|
setFlags(flags);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
return 6;
|
return 6;
|
||||||
|
|
|
@ -90,6 +90,7 @@ class DivPlatformYM2203: public DivPlatformOPN {
|
||||||
unsigned char sampleBank;
|
unsigned char sampleBank;
|
||||||
|
|
||||||
bool extMode;
|
bool extMode;
|
||||||
|
unsigned char prescale;
|
||||||
|
|
||||||
friend void putDispatchChan(void*,int,int);
|
friend void putDispatchChan(void*,int,int);
|
||||||
|
|
||||||
|
@ -118,7 +119,8 @@ class DivPlatformYM2203: public DivPlatformOPN {
|
||||||
int init(DivEngine* parent, int channels, int sugRate, unsigned int flags);
|
int init(DivEngine* parent, int channels, int sugRate, unsigned int flags);
|
||||||
void quit();
|
void quit();
|
||||||
DivPlatformYM2203():
|
DivPlatformYM2203():
|
||||||
DivPlatformOPN(4720270.0, 36, 16) {}
|
DivPlatformOPN(4720270.0, 36, 16),
|
||||||
|
prescale(0x2d) {}
|
||||||
~DivPlatformYM2203();
|
~DivPlatformYM2203();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1325,6 +1325,10 @@ void DivPlatformYM2608::reset() {
|
||||||
// enable 6 channel mode
|
// enable 6 channel mode
|
||||||
immWrite(0x29,0x80);
|
immWrite(0x29,0x80);
|
||||||
|
|
||||||
|
// set prescaler
|
||||||
|
immWrite(0x2d,0xff);
|
||||||
|
immWrite(prescale,0xff);
|
||||||
|
|
||||||
ay->reset();
|
ay->reset();
|
||||||
ay->getRegisterWrites().clear();
|
ay->getRegisterWrites().clear();
|
||||||
ay->flushWrites();
|
ay->flushWrites();
|
||||||
|
@ -1395,7 +1399,8 @@ void DivPlatformYM2608::renderSamples() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformYM2608::setFlags(unsigned int flags) {
|
void DivPlatformYM2608::setFlags(unsigned int flags) {
|
||||||
switch (flags&0x3f) {
|
// Clock flags
|
||||||
|
switch (flags&0x1f) {
|
||||||
default:
|
default:
|
||||||
case 0x00:
|
case 0x00:
|
||||||
chipClock=8000000.0;
|
chipClock=8000000.0;
|
||||||
|
@ -1404,10 +1409,36 @@ void DivPlatformYM2608::setFlags(unsigned int flags) {
|
||||||
chipClock=38400*13*16; // 31948800/4
|
chipClock=38400*13*16; // 31948800/4
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Prescaler flags
|
||||||
|
switch ((flags>>5)&0x3) {
|
||||||
|
default:
|
||||||
|
case 0x00: // /6
|
||||||
|
prescale=0x2d;
|
||||||
|
fmFreqBase=9440540.0,
|
||||||
|
fmDivBase=72,
|
||||||
|
ayDiv=32;
|
||||||
|
break;
|
||||||
|
case 0x01: // /3
|
||||||
|
prescale=0x2e;
|
||||||
|
fmFreqBase=9440540.0/2.0,
|
||||||
|
fmDivBase=36,
|
||||||
|
ayDiv=16;
|
||||||
|
break;
|
||||||
|
case 0x02: // /2
|
||||||
|
prescale=0x2f;
|
||||||
|
fmFreqBase=9440540.0/3.0,
|
||||||
|
fmDivBase=24,
|
||||||
|
ayDiv=8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
rate=fm->sample_rate(chipClock);
|
rate=fm->sample_rate(chipClock);
|
||||||
for (int i=0; i<16; i++) {
|
for (int i=0; i<16; i++) {
|
||||||
oscBuf[i]->rate=rate;
|
oscBuf[i]->rate=rate;
|
||||||
}
|
}
|
||||||
|
immWrite(0x2d,0xff);
|
||||||
|
immWrite(prescale,0xff);
|
||||||
|
ay->setExtClockDiv(chipClock,ayDiv);
|
||||||
|
ay->setFlags(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformYM2608::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
int DivPlatformYM2608::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||||
|
@ -1423,11 +1454,12 @@ int DivPlatformYM2608::init(DivEngine* p, int channels, int sugRate, unsigned in
|
||||||
oscBuf[i]=new DivDispatchOscBuffer;
|
oscBuf[i]=new DivDispatchOscBuffer;
|
||||||
}
|
}
|
||||||
fm=new ymfm::ym2608(iface);
|
fm=new ymfm::ym2608(iface);
|
||||||
setFlags(flags);
|
fm->set_fidelity(ymfm::OPN_FIDELITY_MIN);
|
||||||
// YM2149, 2MHz
|
// YM2149, 2MHz
|
||||||
ay=new DivPlatformAY8910(true,chipClock,32);
|
ay=new DivPlatformAY8910(true,chipClock,ayDiv);
|
||||||
ay->init(p,3,sugRate,16);
|
ay->init(p,3,sugRate,16);
|
||||||
ay->toggleRegisterDump(true);
|
ay->toggleRegisterDump(true);
|
||||||
|
setFlags(flags);
|
||||||
reset();
|
reset();
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,8 +101,7 @@ class DivPlatformYM2608: public DivPlatformOPN {
|
||||||
unsigned char writeRSSOff, writeRSSOn;
|
unsigned char writeRSSOff, writeRSSOn;
|
||||||
|
|
||||||
bool extMode;
|
bool extMode;
|
||||||
double fmFreqBase;
|
unsigned char prescale;
|
||||||
unsigned char ayDiv;
|
|
||||||
|
|
||||||
double NOTE_OPNB(int ch, int note);
|
double NOTE_OPNB(int ch, int note);
|
||||||
double NOTE_ADPCMB(int note);
|
double NOTE_ADPCMB(int note);
|
||||||
|
@ -137,7 +136,8 @@ class DivPlatformYM2608: public DivPlatformOPN {
|
||||||
int init(DivEngine* parent, int channels, int sugRate, unsigned int flags);
|
int init(DivEngine* parent, int channels, int sugRate, unsigned int flags);
|
||||||
void quit();
|
void quit();
|
||||||
DivPlatformYM2608():
|
DivPlatformYM2608():
|
||||||
DivPlatformOPN(9440540.0, 72, 32) {}
|
DivPlatformOPN(9440540.0, 72, 32),
|
||||||
|
prescale(0x2d) {}
|
||||||
~DivPlatformYM2608();
|
~DivPlatformYM2608();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -357,7 +357,7 @@ struct DivSong {
|
||||||
// - 3: 3MHz
|
// - 3: 3MHz
|
||||||
// - 4: 3.9936MHz (PC-88, PC-98)
|
// - 4: 3.9936MHz (PC-88, PC-98)
|
||||||
// - 5: 1.5MHz
|
// - 5: 1.5MHz
|
||||||
// - bit 5-6: output rate (TODO)
|
// - bit 5-6: output rate
|
||||||
// - 0: FM: clock / 72, SSG: clock / 16
|
// - 0: FM: clock / 72, SSG: clock / 16
|
||||||
// - 1: FM: clock / 36, SSG: clock / 8
|
// - 1: FM: clock / 36, SSG: clock / 8
|
||||||
// - 2: FM: clock / 24, SSG: clock / 4
|
// - 2: FM: clock / 24, SSG: clock / 4
|
||||||
|
@ -365,7 +365,7 @@ struct DivSong {
|
||||||
// - bit 0-4: clock rate
|
// - bit 0-4: clock rate
|
||||||
// - 0: 8MHz
|
// - 0: 8MHz
|
||||||
// - 1: 7.987MHz (PC-88, PC-98)
|
// - 1: 7.987MHz (PC-88, PC-98)
|
||||||
// - bit 5-6: output rate (TODO)
|
// - bit 5-6: output rate
|
||||||
// - 0: FM: clock / 144, SSG: clock / 32
|
// - 0: FM: clock / 144, SSG: clock / 32
|
||||||
// - 1: FM: clock / 72, SSG: clock / 16
|
// - 1: FM: clock / 72, SSG: clock / 16
|
||||||
// - 2: FM: clock / 48, SSG: clock / 8
|
// - 2: FM: clock / 48, SSG: clock / 8
|
||||||
|
|
|
@ -56,13 +56,13 @@ void FurnaceGUI::initSystemPresets() {
|
||||||
));
|
));
|
||||||
cat.systems.push_back(FurnaceGUISysDef(
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
"Yamaha YM2608 (OPNA)", {
|
"Yamaha YM2608 (OPNA)", {
|
||||||
DIV_SYSTEM_PC98, 64, 0, 3,
|
DIV_SYSTEM_PC98, 64, 0, 0,
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
cat.systems.push_back(FurnaceGUISysDef(
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
"Yamaha YM2608 (extended channel 3)", {
|
"Yamaha YM2608 (extended channel 3)", {
|
||||||
DIV_SYSTEM_PC98_EXT, 64, 0, 3,
|
DIV_SYSTEM_PC98_EXT, 64, 0, 0,
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
@ -258,6 +258,18 @@ void FurnaceGUI::initSystemPresets() {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
|
"TI SN94624", {
|
||||||
|
DIV_SYSTEM_SMS, 64, 0, 0x80,
|
||||||
|
0
|
||||||
|
}
|
||||||
|
));
|
||||||
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
|
"TI SN76494", {
|
||||||
|
DIV_SYSTEM_SMS, 64, 0, 0x84,
|
||||||
|
0
|
||||||
|
}
|
||||||
|
));
|
||||||
cat.systems.push_back(FurnaceGUISysDef(
|
cat.systems.push_back(FurnaceGUISysDef(
|
||||||
"AY-3-8910", {
|
"AY-3-8910", {
|
||||||
DIV_SYSTEM_AY8910, 64, 0, 0,
|
DIV_SYSTEM_AY8910, 64, 0, 0,
|
||||||
|
|
|
@ -397,8 +397,7 @@ void FurnaceGUI::drawSysConf(int chan, DivSystem type, unsigned int& flags, bool
|
||||||
if (ImGui::RadioButton("1.5MHz",(flags&31)==5)) {
|
if (ImGui::RadioButton("1.5MHz",(flags&31)==5)) {
|
||||||
copyOfFlags=(flags&(~31))|5;
|
copyOfFlags=(flags&(~31))|5;
|
||||||
}
|
}
|
||||||
/*
|
ImGui::Text("Output rate:");
|
||||||
ImGui::Text("Output rate: (DOES NOT WORK YET!)");
|
|
||||||
if (ImGui::RadioButton("FM: clock / 72, SSG: clock / 16",(flags&96)==0)) {
|
if (ImGui::RadioButton("FM: clock / 72, SSG: clock / 16",(flags&96)==0)) {
|
||||||
copyOfFlags=(flags&(~96))|0;
|
copyOfFlags=(flags&(~96))|0;
|
||||||
}
|
}
|
||||||
|
@ -408,7 +407,6 @@ void FurnaceGUI::drawSysConf(int chan, DivSystem type, unsigned int& flags, bool
|
||||||
if (ImGui::RadioButton("FM: clock / 24, SSG: clock / 4",(flags&96)==64)) {
|
if (ImGui::RadioButton("FM: clock / 24, SSG: clock / 4",(flags&96)==64)) {
|
||||||
copyOfFlags=(flags&(~96))|64;
|
copyOfFlags=(flags&(~96))|64;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_SYSTEM_PC98:
|
case DIV_SYSTEM_PC98:
|
||||||
|
@ -420,8 +418,7 @@ void FurnaceGUI::drawSysConf(int chan, DivSystem type, unsigned int& flags, bool
|
||||||
if (ImGui::RadioButton("7.987MHz (PC-88/PC-98)",(flags&31)==1)) {
|
if (ImGui::RadioButton("7.987MHz (PC-88/PC-98)",(flags&31)==1)) {
|
||||||
copyOfFlags=(flags&(~31))|1;
|
copyOfFlags=(flags&(~31))|1;
|
||||||
}
|
}
|
||||||
/*
|
ImGui::Text("Output rate:");
|
||||||
ImGui::Text("Output rate: (DOES NOT WORK YET!)");
|
|
||||||
if (ImGui::RadioButton("FM: clock / 144, SSG: clock / 32",(flags&96)==0)) {
|
if (ImGui::RadioButton("FM: clock / 144, SSG: clock / 32",(flags&96)==0)) {
|
||||||
copyOfFlags=(flags&(~96))|0;
|
copyOfFlags=(flags&(~96))|0;
|
||||||
}
|
}
|
||||||
|
@ -431,7 +428,6 @@ void FurnaceGUI::drawSysConf(int chan, DivSystem type, unsigned int& flags, bool
|
||||||
if (ImGui::RadioButton("FM: clock / 48, SSG: clock / 8",(flags&96)==64)) {
|
if (ImGui::RadioButton("FM: clock / 48, SSG: clock / 8",(flags&96)==64)) {
|
||||||
copyOfFlags=(flags&(~96))|64;
|
copyOfFlags=(flags&(~96))|64;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_SYSTEM_RF5C68: {
|
case DIV_SYSTEM_RF5C68: {
|
||||||
|
|
Loading…
Reference in a new issue