1
0
Fork 0

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:
Peter Veenstra 2005-10-09 15:33:07 +00:00
parent 5f47d64ea7
commit 420a5a7fd0
4 changed files with 95 additions and 52 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;