Add opl3gold option to oplmode setting. With this option the AdLib Gold music can be selected in Dune. Only FM music without effects (reverb, stereo enhancement, surround sound, etc.) is supported; and FM volume control, used in the CD-ROM version of Dune, does work.
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3936
This commit is contained in:
parent
0c979d54a5
commit
babb297c60
5 changed files with 86 additions and 3 deletions
|
@ -24,7 +24,7 @@
|
|||
|
||||
class Section;
|
||||
enum OPL_Mode {
|
||||
OPL_none,OPL_cms,OPL_opl2,OPL_dualopl2,OPL_opl3
|
||||
OPL_none,OPL_cms,OPL_opl2,OPL_dualopl2,OPL_opl3,OPL_opl3gold
|
||||
};
|
||||
#define CAPTURE_WAVE 0x01
|
||||
#define CAPTURE_OPL 0x02
|
||||
|
|
|
@ -537,7 +537,7 @@ void DOSBOX_Init(void) {
|
|||
Pbool = secprop->Add_bool("sbmixer",Property::Changeable::WhenIdle,true);
|
||||
Pbool->Set_help("Allow the soundblaster mixer to modify the DOSBox mixer.");
|
||||
|
||||
const char* oplmodes[]={ "auto", "cms", "opl2", "dualopl2", "opl3", "none", 0};
|
||||
const char* oplmodes[]={ "auto", "cms", "opl2", "dualopl2", "opl3", "opl3gold", "none", 0};
|
||||
Pstring = secprop->Add_string("oplmode",Property::Changeable::WhenIdle,"auto");
|
||||
Pstring->Set_values(oplmodes);
|
||||
Pstring->Set_help("Type of OPL emulation. On 'auto' the mode is determined by sblaster type. All OPL modes are Adlib-compatible, except for 'cms'.");
|
||||
|
|
|
@ -440,6 +440,36 @@ void Module::DualWrite( Bit8u index, Bit8u reg, Bit8u val ) {
|
|||
CacheWrite( fullReg, val );
|
||||
}
|
||||
|
||||
void Module::CtrlWrite( Bit8u val ) {
|
||||
switch ( ctrl.index ) {
|
||||
case 0x09: /* Left FM Volume */
|
||||
ctrl.lvol = val;
|
||||
goto setvol;
|
||||
case 0x0a: /* Right FM Volume */
|
||||
ctrl.rvol = val;
|
||||
setvol:
|
||||
if ( ctrl.mixer ) {
|
||||
//Dune cdrom uses 32 volume steps in an apparent mistake, should be 128
|
||||
mixerChan->SetVolume( (float)(ctrl.lvol&0x1f)/31.0f, (float)(ctrl.rvol&0x1f)/31.0f );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Bitu Module::CtrlRead( void ) {
|
||||
switch ( ctrl.index ) {
|
||||
case 0x00: /* Board Options */
|
||||
return 0x70; //No options installed
|
||||
case 0x09: /* Left FM Volume */
|
||||
return ctrl.lvol;
|
||||
case 0x0a: /* Right FM Volume */
|
||||
return ctrl.rvol;
|
||||
case 0x15: /* Audio Relocation */
|
||||
return 0x388 >> 3; //Cryo installer detection
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
void Module::PortWrite( Bitu port, Bitu val, Bitu iolen ) {
|
||||
//Keep track of last write time
|
||||
|
@ -450,6 +480,14 @@ void Module::PortWrite( Bitu port, Bitu val, Bitu iolen ) {
|
|||
}
|
||||
if ( port&1 ) {
|
||||
switch ( mode ) {
|
||||
case MODE_OPL3GOLD:
|
||||
if ( port == 0x38b ) {
|
||||
if ( ctrl.active ) {
|
||||
CtrlWrite( val );
|
||||
break;
|
||||
}
|
||||
}
|
||||
//Fall-through if not handled by control chip
|
||||
case MODE_OPL2:
|
||||
case MODE_OPL3:
|
||||
if ( !chip[0].Write( reg.normal, val ) ) {
|
||||
|
@ -476,6 +514,20 @@ void Module::PortWrite( Bitu port, Bitu val, Bitu iolen ) {
|
|||
case MODE_OPL2:
|
||||
reg.normal = handler->WriteAddr( port, val ) & 0xff;
|
||||
break;
|
||||
case MODE_OPL3GOLD:
|
||||
if ( port == 0x38a ) {
|
||||
if ( val == 0xff ) {
|
||||
ctrl.active = true;
|
||||
break;
|
||||
} else if ( val == 0xfe ) {
|
||||
ctrl.active = false;
|
||||
break;
|
||||
} else if ( ctrl.active ) {
|
||||
ctrl.index = val & 0xff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//Fall-through if not handled by control chip
|
||||
case MODE_OPL3:
|
||||
reg.normal = handler->WriteAddr( port, val ) & 0x1ff;
|
||||
break;
|
||||
|
@ -504,6 +556,15 @@ Bitu Module::PortRead( Bitu port, Bitu iolen ) {
|
|||
} else {
|
||||
return 0xff;
|
||||
}
|
||||
case MODE_OPL3GOLD:
|
||||
if ( ctrl.active ) {
|
||||
if ( port == 0x38a ) {
|
||||
return 0; //Control status, not busy
|
||||
} else if ( port == 0x38b ) {
|
||||
return CtrlRead();
|
||||
}
|
||||
}
|
||||
//Fall-through if not handled by control chip
|
||||
case MODE_OPL3:
|
||||
//We allocated 4 ports, so just return -1 for the higher ones
|
||||
if ( !(port & 3 ) ) {
|
||||
|
@ -527,6 +588,7 @@ void Module::Init( Mode m ) {
|
|||
mode = m;
|
||||
switch ( mode ) {
|
||||
case MODE_OPL3:
|
||||
case MODE_OPL3GOLD:
|
||||
case MODE_OPL2:
|
||||
break;
|
||||
case MODE_DUALOPL2:
|
||||
|
@ -627,6 +689,10 @@ Module::Module( Section* configuration ) : Module_base(configuration) {
|
|||
reg.dual[0] = 0;
|
||||
reg.dual[1] = 0;
|
||||
reg.normal = 0;
|
||||
ctrl.active = false;
|
||||
ctrl.index = 0;
|
||||
ctrl.lvol = 0xff;
|
||||
ctrl.rvol = 0xff;
|
||||
handler = 0;
|
||||
capture = 0;
|
||||
|
||||
|
@ -637,6 +703,7 @@ Module::Module( Section* configuration ) : Module_base(configuration) {
|
|||
if ( rate < 8000 )
|
||||
rate = 8000;
|
||||
std::string oplemu( section->Get_string( "oplemu" ) );
|
||||
ctrl.mixer = section->Get_bool("sbmixer");
|
||||
|
||||
mixerChan = mixerObject.Install(OPL_CallBack,rate,"FM");
|
||||
mixerChan->SetScale( 2.0 );
|
||||
|
@ -664,6 +731,9 @@ Module::Module( Section* configuration ) : Module_base(configuration) {
|
|||
case OPL_opl3:
|
||||
Init( Adlib::MODE_OPL3 );
|
||||
break;
|
||||
case OPL_opl3gold:
|
||||
Init( Adlib::MODE_OPL3GOLD );
|
||||
break;
|
||||
}
|
||||
//0x388 range
|
||||
WriteHandler[0].Install(0x388,OPL_Write,IO_MB, 4 );
|
||||
|
|
|
@ -90,7 +90,8 @@ struct Chip {
|
|||
typedef enum {
|
||||
MODE_OPL2,
|
||||
MODE_DUALOPL2,
|
||||
MODE_OPL3
|
||||
MODE_OPL3,
|
||||
MODE_OPL3GOLD
|
||||
} Mode;
|
||||
|
||||
class Handler {
|
||||
|
@ -125,8 +126,17 @@ class Module: public Module_base {
|
|||
Bit32u normal;
|
||||
Bit8u dual[2];
|
||||
} reg;
|
||||
struct {
|
||||
bool active;
|
||||
Bit8u index;
|
||||
Bit8u lvol;
|
||||
Bit8u rvol;
|
||||
bool mixer;
|
||||
} ctrl;
|
||||
void CacheWrite( Bit32u reg, Bit8u val );
|
||||
void DualWrite( Bit8u index, Bit8u reg, Bit8u val );
|
||||
void CtrlWrite( Bit8u val );
|
||||
Bitu CtrlRead( void );
|
||||
public:
|
||||
static OPL_Mode oplmode;
|
||||
MixerChannel* mixerChan;
|
||||
|
|
|
@ -1533,6 +1533,7 @@ private:
|
|||
else if (!strcasecmp(omode,"opl2")) opl_mode=OPL_opl2;
|
||||
else if (!strcasecmp(omode,"dualopl2")) opl_mode=OPL_dualopl2;
|
||||
else if (!strcasecmp(omode,"opl3")) opl_mode=OPL_opl3;
|
||||
else if (!strcasecmp(omode,"opl3gold")) opl_mode=OPL_opl3gold;
|
||||
/* Else assume auto */
|
||||
else {
|
||||
switch (type) {
|
||||
|
@ -1588,6 +1589,7 @@ public:
|
|||
// fall-through
|
||||
case OPL_dualopl2:
|
||||
case OPL_opl3:
|
||||
case OPL_opl3gold:
|
||||
OPL_Init(section,oplmode);
|
||||
break;
|
||||
}
|
||||
|
@ -1645,6 +1647,7 @@ public:
|
|||
// fall-through
|
||||
case OPL_dualopl2:
|
||||
case OPL_opl3:
|
||||
case OPL_opl3gold:
|
||||
OPL_ShutDown(m_configuration);
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue