1
0
Fork 0

CMS/Gameblaster: add sbtype=gb, fix base addresses other than 220h, fix lack of sound when starting from autoexec, add autodetection (Thanks robertmo and Cloudschatze)

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3523
This commit is contained in:
Ralf Grillenberger 2010-01-06 19:40:45 +00:00
parent 1d7e48c0dc
commit bf5257415d
3 changed files with 75 additions and 33 deletions

View file

@ -480,10 +480,10 @@ void DOSBOX_Init(void) {
secprop=control->AddSection_prop("sblaster",&SBLASTER_Init,true);//done
const char* sbtypes[] = { "sb1", "sb2", "sbpro1", "sbpro2", "sb16", "none", 0 };
const char* sbtypes[] = { "sb1", "sb2", "sbpro1", "sbpro2", "sb16", "gb", "none", 0 };
Pstring = secprop->Add_string("sbtype",Property::Changeable::WhenIdle,"sb16");
Pstring->Set_values(sbtypes);
Pstring->Set_help("Type of sblaster to emulate.");
Pstring->Set_help("Type of Soundblaster to emulate. gb is Gameblaster.");
Phex = secprop->Add_hex("sbbase",Property::Changeable::WhenIdle,0x220);
Phex->Set_values(ios);

View file

@ -22,6 +22,7 @@
#include "mem.h"
#include "hardware.h"
#include "setup.h"
#include "support.h"
#include "pic.h"
#include <cstring>
#include <math.h>
@ -139,6 +140,7 @@ static Bit16s * cms_buf_point[4] = {
cms_buffer[0][0],cms_buffer[0][1],cms_buffer[1][0],cms_buffer[1][1] };
static Bitu last_command;
static Bitu base_port;
static void saa1099_envelope(int chip, int ch)
@ -286,6 +288,16 @@ static void saa1099_update(int chip, INT16 **buffer, int length)
static void saa1099_write_port_w( int chip, int offset, int data )
{
struct SAA1099 *saa = &saa1099[chip];
if(offset == 1) {
// address port
saa->selected_reg = data & 0x1f;
if (saa->selected_reg == 0x18 || saa->selected_reg == 0x19) {
/* clock the envelope channels */
if (saa->env_clock[0]) saa1099_envelope(chip,0);
if (saa->env_clock[1]) saa1099_envelope(chip,1);
}
return;
}
int reg = saa->selected_reg;
int ch;
@ -364,37 +376,26 @@ static void saa1099_write_port_w( int chip, int offset, int data )
}
}
static void write_cms(Bitu port,Bitu val,Bitu iolen) {
if (last_command + 1000 < PIC_Ticks) if(cms_chan) cms_chan->Enable(true);
static void write_cms(Bitu port, Bitu val, Bitu /* iolen */) {
if(cms_chan && (!cms_chan->enabled)) cms_chan->Enable(true);
last_command = PIC_Ticks;
switch (port) {
case 0x0220:
switch (port-base_port) {
case 0:
saa1099_write_port_w(0,0,val);
break;
case 1:
saa1099_write_port_w(0,1,val);
break;
case 0x221:
saa1099[0].selected_reg = val & 0x1f;
if (saa1099[0].selected_reg == 0x18 || saa1099[0].selected_reg == 0x19) {
/* clock the envelope channels */
if (saa1099[0].env_clock[0]) saa1099_envelope(0,0);
if (saa1099[0].env_clock[1]) saa1099_envelope(0,1);
}
case 2:
saa1099_write_port_w(1,0,val);
break;
case 0x0222:
case 3:
saa1099_write_port_w(1,1,val);
break;
case 0x223:
saa1099[1].selected_reg = val & 0x1f;
if (saa1099[1].selected_reg == 0x18 || saa1099[1].selected_reg == 0x19) {
/* clock the envelope channels */
if (saa1099[1].env_clock[0]) saa1099_envelope(1,0);
if (saa1099[1].env_clock[1]) saa1099_envelope(1,1);
}
break;
}
}
static void CMS_CallBack(Bitu len) {
static void CMS_CallBack(Bitu len) {
if (len > CMS_BUFFER_SIZE) return;
saa1099_update(0, &cms_buf_point[0], (int)len);
@ -421,10 +422,38 @@ static void write_cms(Bitu port,Bitu val,Bitu iolen) {
if (last_command + 10000 < PIC_Ticks) if(cms_chan) cms_chan->Enable(false);
}
// The Gameblaster detection
static Bit8u cms_detect_register = 0xff;
static void write_cms_detect(Bitu port, Bitu val, Bitu /* iolen */) {
switch(port-base_port) {
case 0x6:
case 0x7:
cms_detect_register = val;
break;
}
}
static Bitu read_cms_detect(Bitu port, Bitu /* iolen */) {
Bit8u retval = 0xff;
switch(port-base_port) {
case 0x4:
retval = 0x7f;
break;
case 0xa:
case 0xb:
retval = cms_detect_register;
break;
}
return retval;
}
class CMS:public Module_base {
private:
IO_WriteHandleObject WriteHandler;
IO_WriteHandleObject DetWriteHandler;
IO_ReadHandleObject DetReadHandler;
MixerObject MixerChan;
public:
@ -432,8 +461,16 @@ public:
Section_prop * section = static_cast<Section_prop *>(configuration);
Bitu sample_rate_temp = section->Get_int("oplrate");
sample_rate = static_cast<double>(sample_rate_temp);
Bitu base = section->Get_hex("sbbase");
WriteHandler.Install(base,write_cms,IO_MB,4);
base_port = section->Get_hex("sbbase");
WriteHandler.Install(base_port, write_cms, IO_MB,4);
// A standalone Gameblaster has a magic chip on it which is
// sometimes used for detection.
const char * sbtype=section->Get_string("sbtype");
if (!strcasecmp(sbtype,"gb")) {
DetWriteHandler.Install(base_port+4,write_cms_detect,IO_MB,12);
DetReadHandler.Install(base_port,read_cms_detect,IO_MB,16);
}
/* Register the Mixer CallBack */
cms_chan = MixerChan.Install(CMS_CallBack,sample_rate_temp,"CMS");

View file

@ -63,7 +63,7 @@ bool MIDI_Available(void);
#define SB_SH_MASK ((1 << SB_SH)-1)
enum {DSP_S_RESET,DSP_S_RESET_WAIT,DSP_S_NORMAL,DSP_S_HIGHSPEED};
enum SB_TYPES {SBT_NONE=0,SBT_1=1,SBT_PRO1=2,SBT_2=3,SBT_PRO2=4,SBT_16=6};
enum SB_TYPES {SBT_NONE=0,SBT_1=1,SBT_PRO1=2,SBT_2=3,SBT_PRO2=4,SBT_16=6,SBT_GB=7};
enum SB_IRQS {SB_IRQ_8,SB_IRQ_16,SB_IRQ_MPU};
enum DSP_MODES {
@ -1478,6 +1478,7 @@ private:
else if (!strcasecmp(sbtype,"sbpro1")) type=SBT_PRO1;
else if (!strcasecmp(sbtype,"sbpro2")) type=SBT_PRO2;
else if (!strcasecmp(sbtype,"sb16")) type=SBT_16;
else if (!strcasecmp(sbtype,"gb")) type=SBT_GB;
else if (!strcasecmp(sbtype,"none")) type=SBT_NONE;
else type=SBT_16;
@ -1495,7 +1496,9 @@ private:
/* Else assume auto */
else {
switch (type) {
case SBT_NONE:opl_mode=OPL_none;break;
case SBT_NONE:
case SBT_GB:
opl_mode=OPL_none;break;
case SBT_1:opl_mode=OPL_opl2;break;
case SBT_2:opl_mode=OPL_opl2;break;
case SBT_PRO1:opl_mode=OPL_dualopl2;break;
@ -1524,23 +1527,25 @@ public:
OPL_Mode opl_mode = OPL_none;
Find_Type_And_Opl(section,sb.type,opl_mode);
bool do_cms = (sb.type==SBT_GB)? true:false;
switch (opl_mode) {
case OPL_none:
WriteHandler[0].Install(0x388,adlib_gusforward,IO_MB);
break;
case OPL_cms:
WriteHandler[0].Install(0x388,adlib_gusforward,IO_MB);
CMS_Init(section);
do_cms = true;
break;
case OPL_opl2:
CMS_Init(section);
do_cms = true;
case OPL_dualopl2:
case OPL_opl3:
OPL_Init(section,opl_mode);
break;
}
if (sb.type==SBT_NONE) return;
if (do_cms) CMS_Init(section);
if (sb.type==SBT_NONE || sb.type==SBT_GB) return;
sb.chan=MixerChan.Install(&SBLASTER_CallBack,22050,"SB");
sb.dsp.state=DSP_S_NORMAL;
@ -1603,7 +1608,7 @@ public:
break;
}
if (sb.type==SBT_NONE) return;
if (sb.type==SBT_NONE || sb.type==SBT_GB) return;
DSP_Reset();//Stop everything
}
}; //End of SBLASTER class