From 420a5a7fd03408de4ac0b910e0ec7336d8be22f1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Sun, 9 Oct 2005 15:33:07 +0000 Subject: [PATCH] Make the soundblaster really reinitializable. Fixes bug 1241149 Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2342 --- include/hardware.h | 6 ++- src/hardware/adlib.cpp | 84 +++++++++++++++++++++++------------- src/hardware/gameblaster.cpp | 43 ++++++++++++------ src/hardware/sblaster.cpp | 14 +++--- 4 files changed, 95 insertions(+), 52 deletions(-) diff --git a/include/hardware.h b/include/hardware.h index 5b5079b8..0c89fa5e 100644 --- a/include/hardware.h +++ b/include/hardware.h @@ -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); diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index c1246f86..7ab235ca 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -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(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(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; +} diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index f061a351..2df5fa77 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -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(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(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; +} diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index 6e124d55..bc8a1816 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -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;