Make the soundblaster really reinitializable. Fixes bug 1241149
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2342
This commit is contained in:
parent
5f47d64ea7
commit
420a5a7fd0
4 changed files with 95 additions and 52 deletions
|
@ -26,8 +26,10 @@ enum OPL_Mode {
|
|||
OPL_none,OPL_cms,OPL_opl2,OPL_dualopl2,OPL_opl3
|
||||
};
|
||||
|
||||
void OPL_Init(Section* sec,Bitu base,OPL_Mode mode,Bitu rate);
|
||||
void CMS_Init(Section* sec,Bitu base,Bitu rate);
|
||||
void OPL_Init(Section* sec,OPL_Mode mode);
|
||||
void CMS_Init(Section* sec);
|
||||
void OPL_ShutDown(Section* sec);
|
||||
void CMS_ShutDown(Section* sec);
|
||||
extern Bit8u adlib_commandreg;
|
||||
FILE * OpenCaptureFile(const char * type,const char * ext);
|
||||
|
||||
|
|
|
@ -312,37 +312,61 @@ static void OPL_SaveRawEvent(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static void OPL_Stop(Section* sec) {
|
||||
if (opl.raw.handle) OPL_SaveRawEvent();
|
||||
}
|
||||
class OPL: public Module_base {
|
||||
private:
|
||||
IO_ReadHandleObject ReadHandler[3];
|
||||
IO_WriteHandleObject WriteHandler[3];
|
||||
MixerObject MixerChan;
|
||||
public:
|
||||
static OPL_Mode oplmode;
|
||||
|
||||
void OPL_Init(Section* sec,Bitu base,OPL_Mode oplmode,Bitu rate) {
|
||||
Section_prop * section=static_cast<Section_prop *>(sec);
|
||||
if (OPL2::YM3812Init(2,OPL2_INTERNAL_FREQ,rate)) {
|
||||
E_Exit("Can't create OPL2 Emulator");
|
||||
};
|
||||
OPL2::YM3812SetTimerHandler(0,OPL2::TimerHandler,0);
|
||||
OPL2::YM3812SetTimerHandler(1,OPL2::TimerHandler,256);
|
||||
if (THEOPL3::YMF262Init(1,OPL3_INTERNAL_FREQ,rate)) {
|
||||
E_Exit("Can't create OPL3 Emulator");
|
||||
};
|
||||
THEOPL3::YMF262SetTimerHandler(0,THEOPL3::TimerHandler,0);
|
||||
IO_RegisterWriteHandler(0x388,OPL_Write,IO_MB,4);
|
||||
IO_RegisterReadHandler(0x388,OPL_Read,IO_MB,4);
|
||||
if (oplmode>=OPL_dualopl2) {
|
||||
IO_RegisterWriteHandler(base,OPL_Write,IO_MB,4);
|
||||
IO_RegisterReadHandler(base,OPL_Read,IO_MB,4);
|
||||
OPL(Section* configuration):Module_base(configuration) {
|
||||
Section_prop * section=static_cast<Section_prop *>(configuration);
|
||||
Bitu base = section->Get_hex("base");
|
||||
Bitu rate = section->Get_int("oplrate");
|
||||
if (OPL2::YM3812Init(2,OPL2_INTERNAL_FREQ,rate)) {
|
||||
E_Exit("Can't create OPL2 Emulator");
|
||||
};
|
||||
OPL2::YM3812SetTimerHandler(0,OPL2::TimerHandler,0);
|
||||
OPL2::YM3812SetTimerHandler(1,OPL2::TimerHandler,256);
|
||||
if (THEOPL3::YMF262Init(1,OPL3_INTERNAL_FREQ,rate)) {
|
||||
E_Exit("Can't create OPL3 Emulator");
|
||||
};
|
||||
THEOPL3::YMF262SetTimerHandler(0,THEOPL3::TimerHandler,0);
|
||||
WriteHandler[0].Install(0x388,OPL_Write,IO_MB,4);
|
||||
ReadHandler[0].Install(0x388,OPL_Read,IO_MB,4);
|
||||
if (oplmode>=OPL_dualopl2) {
|
||||
WriteHandler[1].Install(base,OPL_Write,IO_MB,4);
|
||||
ReadHandler[1].Install(base,OPL_Read,IO_MB,4);
|
||||
}
|
||||
|
||||
WriteHandler[2].Install(base+8,OPL_Write,IO_MB,2);
|
||||
ReadHandler[2].Install(base+8,OPL_Read,IO_MB,2);
|
||||
|
||||
opl.active=false;
|
||||
opl.last_used=0;
|
||||
opl.mode=oplmode;
|
||||
memset(&opl.raw,0,sizeof(opl.raw));
|
||||
opl.chan=MixerChan.Install(OPL_CallBack,rate,"FM");
|
||||
MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL");
|
||||
}
|
||||
~OPL() {
|
||||
if (opl.raw.handle) OPL_SaveRawEvent();
|
||||
OPL2::YM3812Shutdown();
|
||||
THEOPL3::YMF262Shutdown();
|
||||
}
|
||||
|
||||
IO_RegisterWriteHandler(base+8,OPL_Write,IO_MB,2);
|
||||
IO_RegisterReadHandler(base+8,OPL_Read,IO_MB,2);
|
||||
|
||||
opl.active=false;
|
||||
opl.last_used=0;
|
||||
opl.mode=oplmode;
|
||||
memset(&opl.raw,0,sizeof(opl.raw));
|
||||
opl.chan=MIXER_AddChannel(OPL_CallBack,rate,"FM");
|
||||
MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL");
|
||||
sec->AddDestroyFunction(&OPL_Stop);
|
||||
};
|
||||
|
||||
static OPL* test;
|
||||
|
||||
//Initialize static members
|
||||
OPL_Mode OPL::oplmode=OPL_none;
|
||||
|
||||
void OPL_Init(Section* sec,OPL_Mode oplmode) {
|
||||
OPL::oplmode = oplmode;
|
||||
test = new OPL(sec);
|
||||
}
|
||||
|
||||
void OPL_ShutDown(Section* sec){
|
||||
delete test;
|
||||
}
|
||||
|
|
|
@ -420,20 +420,39 @@ static void write_cms(Bitu port,Bitu val,Bitu iolen) {
|
|||
}
|
||||
|
||||
|
||||
void CMS_Init(Section* sec,Bitu base,Bitu rate) {
|
||||
Section_prop * section=static_cast<Section_prop *>(sec);
|
||||
sample_rate=rate;
|
||||
class CMS:public Module_base {
|
||||
private:
|
||||
IO_WriteHandleObject WriteHandler;
|
||||
MixerObject MixerChan;
|
||||
|
||||
IO_RegisterWriteHandler(base,write_cms,IO_MB,4);
|
||||
public:
|
||||
CMS(Section* configuration):Module_base(configuration) {
|
||||
Section_prop * section=static_cast<Section_prop *>(configuration);
|
||||
Bitu sample_rate = section->Get_int("oplrate");
|
||||
Bitu base = section->Get_hex("base");
|
||||
WriteHandler.Install(base,write_cms,IO_MB,4);
|
||||
|
||||
/* Register the Mixer CallBack */
|
||||
|
||||
cms_chan=MIXER_AddChannel(CMS_CallBack,rate,"CMS");
|
||||
last_command=PIC_Ticks;
|
||||
/* Register the Mixer CallBack */
|
||||
cms_chan = MixerChan.Install(CMS_CallBack,sample_rate,"CMS");
|
||||
|
||||
for (int s=0;s<2;s++) {
|
||||
struct SAA1099 *saa = &saa1099[s];
|
||||
memset(saa, 0, sizeof(struct SAA1099));
|
||||
last_command=PIC_Ticks;
|
||||
|
||||
for (int s=0;s<2;s++) {
|
||||
struct SAA1099 *saa = &saa1099[s];
|
||||
memset(saa, 0, sizeof(struct SAA1099));
|
||||
}
|
||||
}
|
||||
}
|
||||
~CMS() {
|
||||
cms_chan->Enable(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static CMS* test;
|
||||
|
||||
void CMS_Init(Section* sec) {
|
||||
test = new CMS(sec);
|
||||
}
|
||||
void CMS_ShutDown(Section* sec) {
|
||||
delete test;
|
||||
}
|
||||
|
|
|
@ -1132,13 +1132,13 @@ public:
|
|||
break;
|
||||
case OPL_cms:
|
||||
WriteHandler[0].Install(0x388,adlib_gusforward,IO_MB);
|
||||
CMS_Init(section,sb.hw.base,oplrate);
|
||||
CMS_Init(section);
|
||||
break;
|
||||
case OPL_opl2:
|
||||
CMS_Init(section,sb.hw.base,oplrate);
|
||||
CMS_Init(section);
|
||||
case OPL_dualopl2:
|
||||
case OPL_opl3:
|
||||
OPL_Init(section,sb.hw.base,opl_mode,oplrate);
|
||||
OPL_Init(section,opl_mode);
|
||||
break;
|
||||
}
|
||||
if (sb.type==SBT_NONE) return;
|
||||
|
@ -1174,13 +1174,13 @@ public:
|
|||
break;
|
||||
case OPL_cms:
|
||||
|
||||
//TODO CMS_Init(section,sb.hw.base,oplrate);
|
||||
CMS_ShutDown(m_configuration);
|
||||
break;
|
||||
case OPL_opl2:
|
||||
//TODO CMS_Init(section,sb.hw.base,oplrate);
|
||||
CMS_ShutDown(m_configuration);
|
||||
case OPL_dualopl2:
|
||||
case OPL_opl3:
|
||||
//TODO OPL_Init(section,sb.hw.base,opl_mode,oplrate);
|
||||
OPL_ShutDown(m_configuration);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1190,8 +1190,6 @@ public:
|
|||
}; //End of SBLASTER class
|
||||
|
||||
|
||||
|
||||
|
||||
static SBLASTER* test;
|
||||
void SBLASTER_ShutDown(Section* sec) {
|
||||
delete test;
|
||||
|
|
Loading…
Add table
Reference in a new issue