From f22e8d50410b5f44c0a453ccf89a60a06d5ebe31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Wed, 16 Nov 2005 20:27:40 +0000 Subject: [PATCH] add possibility to close dma controllers; remove second dma controller when tandy sound is enabled and machine=vga Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2377 --- include/dma.h | 49 +++++--- src/dosbox.cpp | 4 +- src/hardware/dma.cpp | 231 ++++++++++++++++++++--------------- src/hardware/gus.cpp | 8 +- src/hardware/sblaster.cpp | 39 +++--- src/hardware/tandy_sound.cpp | 18 ++- 6 files changed, 207 insertions(+), 142 deletions(-) diff --git a/include/dma.h b/include/dma.h index fb72a2ea..84ec9a7a 100644 --- a/include/dma.h +++ b/include/dma.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dma.h,v 1.14 2005-03-24 10:18:45 qbix79 Exp $ */ +/* $Id: dma.h,v 1.15 2005-11-16 20:27:39 c2woody Exp $ */ #ifndef DOSBOX_DMA_H #define DOSBOX_DMA_H @@ -31,19 +31,6 @@ enum DMAEvent { class DmaChannel; typedef void (* DMA_CallBack)(DmaChannel * chan,DMAEvent event); -class DmaController { -public: - bool flipflop; - Bit8u ctrlnum; - Bit8u chanbase; -public: - DmaController(Bit8u num) { - flipflop = false; - ctrlnum = num; - chanbase = num * 4; - } -}; - class DmaChannel { public: Bit32u pagebase; @@ -85,7 +72,37 @@ public: Bitu Write(Bitu size, Bit8u * buffer); }; -extern DmaChannel *DmaChannels[8]; -extern DmaController *DmaControllers[2]; +class DmaController { +private: + Bit8u ctrlnum; + bool flipflop; + DmaChannel *DmaChannels[4]; +public: + IO_ReadHandleObject DMA_ReadHandler[0x11]; + IO_WriteHandleObject DMA_WriteHandler[0x11]; + DmaController(Bit8u num) { + flipflop = false; + ctrlnum = num; /* first or second DMA controller */ + for(Bit8u i=0;i<4;i++) { + DmaChannels[i] = new DmaChannel(i+ctrlnum*4,ctrlnum==1); + } + } + ~DmaController(void) { + for(Bit8u i=0;i<4;i++) { + delete DmaChannels[i]; + } + } + DmaChannel * GetChannel(Bit8u chan) { + if (chan<4) return DmaChannels[chan]; + else return NULL; + } + void WriteControllerReg(Bitu reg,Bitu val,Bitu len); + Bitu ReadControllerReg(Bitu reg,Bitu len); +}; + +DmaChannel * GetDMAChannel(Bit8u chan); + +void CloseSecondDMAController(void); +bool SecondDMAControllerAvailable(void); #endif diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 8192e805..28da68d6 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.89 2005-11-10 18:05:10 c2woody Exp $ */ +/* $Id: dosbox.cpp,v 1.90 2005-11-16 20:27:39 c2woody Exp $ */ #include #include @@ -341,7 +341,7 @@ void DOSBOX_Init(void) { MSG_Add("SPEAKER_CONFIGFILE_HELP", "pcspeaker -- Enable PC-Speaker emulation.\n" "pcrate -- Sample rate of the PC-Speaker sound generation.\n" - "tandy -- Enable Tandy Sound System emulation (false,true,auto).\n" + "tandy -- Enable Tandy Sound System emulation (off,on,auto).\n" " For auto Tandysound emulation is present only if machine is set to tandy.\n" "tandyrate -- Sample rate of the Tandy 3-Voice generation.\n" "disney -- Enable Disney Sound Source emulation.\n" diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 43be4cd8..988f0a30 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -25,37 +25,100 @@ #include "paging.h" #include "setup.h" -DmaChannel *DmaChannels[8]; DmaController *DmaControllers[2]; +/* read a block from physical memory */ static void DMA_BlockRead(PhysPt pt,void * data,Bitu size) { Bit8u * write=(Bit8u *) data; for ( ; size ; size--, pt++) { Bitu page = pt >> 12; - if (page < LINK_START) + if (page < LINK_START) /* cares for EMS pageframe etc. */ page = paging.firstmb[page]; *write++=phys_readb(page*4096 + (pt & 4095)); } } +/* write a block into physical memory */ static void DMA_BlockWrite(PhysPt pt,void * data,Bitu size) { Bit8u * read=(Bit8u *) data; for ( ; size ; size--, pt++) { Bitu page = pt >> 12; - if (page < LINK_START) + if (page < LINK_START) /* cares for EMS pageframe etc. */ page = paging.firstmb[page]; phys_writeb(page*4096 + (pt & 4095), *read++); } } -static void DMA_WriteControllerReg(DmaController * cont,Bitu reg,Bitu val,Bitu len) { +DmaChannel * GetDMAChannel(Bit8u chan) { + if (chan<4) { + /* channel on first DMA controller */ + if (DmaControllers[0]) return DmaControllers[0]->GetChannel(chan); + } else if (chan<8) { + /* channel on second DMA controller */ + if (DmaControllers[1]) return DmaControllers[1]->GetChannel(chan-4); + } + return NULL; +} + +/* remove the second DMA controller (ports are removed automatically) */ +void CloseSecondDMAController(void) { + if (DmaControllers[1]) { + delete DmaControllers[1]; + DmaControllers[1]=NULL; + } +} + +/* check availability of second DMA controller, needed for SB16 */ +bool SecondDMAControllerAvailable(void) { + if (DmaControllers[1]) return true; + else return false; +} + +static void DMA_Write_Port(Bitu port,Bitu val,Bitu iolen) { + if (port<0x10) { + /* write to the first DMA controller (channels 0-3) */ + DmaControllers[0]->WriteControllerReg(port,val,1); + } else if (port>=0xc0 && port <=0xdf) { + /* write to the second DMA controller (channels 4-7) */ + DmaControllers[1]->WriteControllerReg((port-0xc0) >> 1,val,1); + } else switch (port) { + /* write DMA page register */ + case 0x81:GetDMAChannel(2)->SetPage(val);break; + case 0x82:GetDMAChannel(3)->SetPage(val);break; + case 0x83:GetDMAChannel(1)->SetPage(val);break; + case 0x89:GetDMAChannel(6)->SetPage(val);break; + case 0x8a:GetDMAChannel(7)->SetPage(val);break; + case 0x8b:GetDMAChannel(5)->SetPage(val);break; + } +} + +static Bitu DMA_Read_Port(Bitu port,Bitu iolen) { + if (port<0x10) { + /* read from the first DMA controller (channels 0-3) */ + return DmaControllers[0]->ReadControllerReg(port,iolen); + } else if (port>=0xc0 && port <=0xdf) { + /* read from the second DMA controller (channels 4-7) */ + return DmaControllers[1]->ReadControllerReg((port-0xc0) >> 1,iolen); + } else switch (port) { + /* read DMA page register */ + case 0x81:return GetDMAChannel(2)->pagenum; + case 0x82:return GetDMAChannel(3)->pagenum; + case 0x83:return GetDMAChannel(1)->pagenum; + case 0x89:return GetDMAChannel(6)->pagenum; + case 0x8a:return GetDMAChannel(7)->pagenum; + case 0x8b:return GetDMAChannel(5)->pagenum; + } + return 0; +} + +void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) { DmaChannel * chan;Bitu i; - Bitu base=cont->chanbase; switch (reg) { + /* set base address of DMA transfer (1st byte low part, 2nd byte high part) */ case 0x0:case 0x2:case 0x4:case 0x6: - chan=DmaChannels[base+(reg >> 1)]; - cont->flipflop=!cont->flipflop; - if (cont->flipflop) { + chan=GetChannel(reg >> 1); + flipflop=!flipflop; + if (flipflop) { chan->baseaddr=(chan->baseaddr&0xff00)|val; chan->curraddr=(chan->curraddr&0xff00)|val; } else { @@ -63,10 +126,11 @@ static void DMA_WriteControllerReg(DmaController * cont,Bitu reg,Bitu val,Bitu l chan->curraddr=(chan->curraddr&0x00ff)|(val << 8); } break; + /* set DMA transfer count (1st byte low part, 2nd byte high part) */ case 0x1:case 0x3:case 0x5:case 0x7: - chan=DmaChannels[base+(reg >> 1)]; - cont->flipflop=!cont->flipflop; - if (cont->flipflop) { + chan=GetChannel(reg >> 1); + flipflop=!flipflop; + if (flipflop) { chan->basecnt=(chan->basecnt&0xff00)|val; chan->currcnt=(chan->currcnt&0xff00)|val; } else { @@ -80,63 +144,67 @@ static void DMA_WriteControllerReg(DmaController * cont,Bitu reg,Bitu val,Bitu l //TODO Warning? break; case 0xa: /* Mask Register */ - chan=DmaChannels[base+(val & 3 )]; + chan=GetChannel(val & 3); chan->SetMask((val & 0x4)>0); break; case 0xb: /* Mode Register */ - chan=DmaChannels[base+(val & 3 )]; + chan=GetChannel(val & 3); chan->autoinit=(val & 0x10) > 0; chan->increment=(val & 0x20) > 0; //TODO Maybe other bits? break; case 0xc: /* Clear Flip/Flip */ - cont->flipflop=false; + flipflop=false; break; case 0xd: /* Master Clear/Reset */ for (i=0;i<4;i++) { - DmaChannels[base+i]->SetMask(true); - DmaChannels[base+i]->tcount=false; + chan=GetChannel(i); + chan->SetMask(true); + chan->tcount=false; } - cont->flipflop=false; + flipflop=false; break; case 0xe: /* Clear Mask register */ for (i=0;i<4;i++) { - DmaChannels[base+i]->SetMask(false); + chan=GetChannel(i); + chan->SetMask(false); } break; case 0xf: /* Multiple Mask register */ for (i=0;i<4;i++) { - DmaChannels[base+i]->SetMask(val & 1); + chan=GetChannel(i); + chan->SetMask(val & 1); val>>=1; } break; } } -static Bitu DMA_ReadControllerReg(DmaController * cont,Bitu reg,Bitu len) { +Bitu DmaController::ReadControllerReg(Bitu reg,Bitu len) { DmaChannel * chan;Bitu i,ret; - Bitu base=cont->chanbase; switch (reg) { + /* read base address of DMA transfer (1st byte low part, 2nd byte high part) */ case 0x0:case 0x2:case 0x4:case 0x6: - chan=DmaChannels[base+(reg >> 1)]; - cont->flipflop=!cont->flipflop; - if (cont->flipflop) { + chan=GetChannel(reg >> 1); + flipflop=!flipflop; + if (flipflop) { return chan->curraddr & 0xff; } else { return (chan->curraddr >> 8) & 0xff; } + /* read DMA transfer count (1st byte low part, 2nd byte high part) */ case 0x1:case 0x3:case 0x5:case 0x7: - chan=DmaChannels[base+(reg >> 1)]; - cont->flipflop=!cont->flipflop; - if (cont->flipflop) { + chan=GetChannel(reg >> 1); + flipflop=!flipflop; + if (flipflop) { return chan->currcnt & 0xff; } else { return (chan->currcnt >> 8) & 0xff; } - case 0x8: + case 0x8: /* Status Register */ ret=0; for (i=0;i<4;i++) { - chan=DmaChannels[base+i]; + chan=GetChannel(i); if (chan->tcount) ret|=1 << i; chan->tcount=false; if (chan->callback) ret|=1 << (i+4); @@ -149,53 +217,21 @@ static Bitu DMA_ReadControllerReg(DmaController * cont,Bitu reg,Bitu len) { return 0xffffffff; } - -static void DMA_Write_Port(Bitu port,Bitu val,Bitu iolen) { - if (port<0x10) { - DMA_WriteControllerReg(DmaControllers[0],port,val,1); - } else if (port>=0xc0 && port <=0xdf) { - DMA_WriteControllerReg(DmaControllers[1],(port-0xc0) >> 1,val,1); - } else switch (port) { - case 0x81:DmaChannels[2]->SetPage(val);break; - case 0x82:DmaChannels[3]->SetPage(val);break; - case 0x83:DmaChannels[1]->SetPage(val);break; - case 0x89:DmaChannels[6]->SetPage(val);break; - case 0x8a:DmaChannels[7]->SetPage(val);break; - case 0x8b:DmaChannels[5]->SetPage(val);break; - } -} - -static Bitu DMA_Read_Port(Bitu port,Bitu iolen) { - if (port<0x10) { - return DMA_ReadControllerReg(DmaControllers[0],port,iolen); - } else if (port>=0xc0 && port <=0xdf) { - return DMA_ReadControllerReg(DmaControllers[1],(port-0xc0) >> 1,iolen); - } else switch (port) { - case 0x81:return DmaChannels[2]->pagenum; - case 0x82:return DmaChannels[3]->pagenum; - case 0x83:return DmaChannels[1]->pagenum; - case 0x89:return DmaChannels[6]->pagenum; - case 0x8a:return DmaChannels[7]->pagenum; - case 0x8b:return DmaChannels[5]->pagenum; - } - return 0; -} - DmaChannel::DmaChannel(Bit8u num, bool dma16) { - masked = true; - callback = NULL; - if(num == 4) return; - channum = num; - DMA16 = dma16 ? 0x1 : 0x0; - pagenum = 0; - pagebase = 0; - baseaddr = 0; - curraddr = 0; - basecnt = 0; - currcnt = 0; - increment = true; - autoinit = false; - tcount = false; + masked = true; + callback = NULL; + if(num == 4) return; + channum = num; + DMA16 = dma16 ? 0x1 : 0x0; + pagenum = 0; + pagebase = 0; + baseaddr = 0; + curraddr = 0; + basecnt = 0; + currcnt = 0; + increment = true; + autoinit = false; + tcount = false; } Bitu DmaChannel::Read(Bitu want, Bit8u * buffer) { @@ -226,6 +262,7 @@ again: } return done; } + Bitu DmaChannel::Write(Bitu want, Bit8u * buffer) { Bitu done=0; again: @@ -256,40 +293,42 @@ again: } class DMA:public Module_base{ -private: - IO_ReadHandleObject ReadHandler[0x22]; - IO_WriteHandleObject WriteHandler[0x22]; public: DMA(Section* configuration):Module_base(configuration){ Bitu i; DmaControllers[0] = new DmaController(0); - DmaControllers[1] = new DmaController(1); + if (machine==MCH_VGA) DmaControllers[1] = new DmaController(1); - for(i=0;i<8;i++) { - DmaChannels[i] = new DmaChannel(i,i>=4); - } - for (i=0;i<0x10;i++) { Bitu mask=IO_MB; if (i<8) mask|=IO_MW; - WriteHandler[i].Install(i,DMA_Write_Port,mask); - ReadHandler[i].Install(i,DMA_Read_Port,mask); + /* install handler for first DMA controller ports */ + DmaControllers[0]->DMA_WriteHandler[i].Install(i,DMA_Write_Port,mask); + DmaControllers[0]->DMA_ReadHandler[i].Install(i,DMA_Read_Port,mask); if (machine==MCH_VGA) { - WriteHandler[0x10+i].Install(0xc0+i*2,DMA_Write_Port,mask); - ReadHandler[0x10+i].Install(0xc0+i*2,DMA_Read_Port,mask); + /* install handler for second DMA controller ports */ + DmaControllers[1]->DMA_WriteHandler[i].Install(0xc0+i*2,DMA_Write_Port,mask); + DmaControllers[1]->DMA_ReadHandler[i].Install(0xc0+i*2,DMA_Read_Port,mask); } } - WriteHandler[0x20].Install(0x81,DMA_Write_Port,IO_MB,3); - WriteHandler[0x21].Install(0x89,DMA_Write_Port,IO_MB,3); - - ReadHandler[0x20].Install(0x81,DMA_Read_Port,IO_MB,3); - ReadHandler[0x21].Install(0x89,DMA_Read_Port,IO_MB,3); + /* install handlers for ports 0x81-0x83 (on the first DMA controller) */ + DmaControllers[0]->DMA_WriteHandler[0x10].Install(0x81,DMA_Write_Port,IO_MB,3); + DmaControllers[0]->DMA_ReadHandler[0x10].Install(0x81,DMA_Read_Port,IO_MB,3); + + if (machine==MCH_VGA) { + /* install handlers for ports 0x81-0x83 (on the second DMA controller) */ + DmaControllers[1]->DMA_WriteHandler[0x10].Install(0x89,DMA_Write_Port,IO_MB,3); + DmaControllers[1]->DMA_ReadHandler[0x10].Install(0x89,DMA_Read_Port,IO_MB,3); + } } ~DMA(){ - delete DmaControllers[0]; - delete DmaControllers[1]; - for(Bitu i=0;i<8;i++) { - delete DmaChannels[i]; + if (DmaControllers[0]) { + delete DmaControllers[0]; + DmaControllers[0]=NULL; + } + if (DmaControllers[1]) { + delete DmaControllers[1]; + DmaControllers[1]=NULL; } } }; diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 895a5f0f..abe48b7b 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -83,8 +83,8 @@ struct GFGus { } timers[2]; Bit32u rate; Bit16u portbase; - Bit16u dma1; - Bit16u dma2; + Bit8u dma1; + Bit8u dma2; Bit16u irq1; Bit16u irq2; @@ -568,7 +568,7 @@ static void ExecuteGlobRegister(void) { break; case 0x41: // Dma control register myGUS.DMAControl = (Bit8u)(myGUS.gRegData>>8); - DmaChannels[myGUS.dma1]->Register_Callback( + GetDMAChannel(myGUS.dma1)->Register_Callback( (myGUS.DMAControl & 0x1) ? GUS_DMA_Callback : 0); break; case 0x42: // Gravis DRAM DMA address register @@ -597,7 +597,7 @@ static void ExecuteGlobRegister(void) { break; case 0x49: // DMA sampling control register myGUS.SampControl = (Bit8u)(myGUS.gRegData>>8); - DmaChannels[myGUS.dma1]->Register_Callback( + GetDMAChannel(myGUS.dma1)->Register_Callback( (myGUS.SampControl & 0x1) ? GUS_DMA_Callback : 0); break; case 0x4c: // GUS reset register diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index a154dfd9..24900da7 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -518,7 +518,7 @@ static void DSP_RaiseIRQEvent(Bitu val) { SB_RaiseIRQ(SB_IRQ_8); } -static void DSP_DoDMATranfser(DMA_MODES mode,Bitu freq,bool stereo) { +static void DSP_DoDMATransfer(DMA_MODES mode,Bitu freq,bool stereo) { char * type; sb.mode=MODE_DMA_MASKED; sb.chan->FillUp(); @@ -576,8 +576,8 @@ static void DSP_DoDMATranfser(DMA_MODES mode,Bitu freq,bool stereo) { static void DSP_PrepareDMA_Old(DMA_MODES mode,bool autoinit) { sb.dma.autoinit=autoinit; if (!autoinit) sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); - sb.dma.chan=DmaChannels[sb.hw.dma8]; - DSP_DoDMATranfser(mode,sb.freq / (sb.mixer.stereo ? 2 : 1),sb.mixer.stereo); + sb.dma.chan=GetDMAChannel(sb.hw.dma8); + DSP_DoDMATransfer(mode,sb.freq / (sb.mixer.stereo ? 2 : 1),sb.mixer.stereo); } static void DSP_PrepareDMA_New(DMA_MODES mode,Bitu length,bool autoinit,bool stereo) { @@ -585,14 +585,14 @@ static void DSP_PrepareDMA_New(DMA_MODES mode,Bitu length,bool autoinit,bool ste sb.dma.total=length; sb.dma.autoinit=autoinit; if (mode==DSP_DMA_16) { - if (sb.hw.dma16!=0xff) sb.dma.chan=DmaChannels[sb.hw.dma16]; + if (sb.hw.dma16!=0xff) sb.dma.chan=GetDMAChannel(sb.hw.dma16); else { - sb.dma.chan=DmaChannels[sb.hw.dma8]; + sb.dma.chan=GetDMAChannel(sb.hw.dma8); mode=DSP_DMA_16_ALIASED; freq/=2; } - } else sb.dma.chan=DmaChannels[sb.hw.dma8]; - DSP_DoDMATranfser(mode,freq,stereo); + } else sb.dma.chan=GetDMAChannel(sb.hw.dma8); + DSP_DoDMATransfer(mode,freq,stereo); } @@ -650,19 +650,21 @@ static void DSP_DoReset(Bit8u val) { static void DSP_E2_DMA_CallBack(DmaChannel * chan, DMAEvent event) { if (event==DMA_UNMASKED) { Bit8u val=sb.e2.value; - DmaChannels[sb.hw.dma8]->Register_Callback(0); - DmaChannels[sb.hw.dma8]->Write(1,&val); + DmaChannel * chan=GetDMAChannel(sb.hw.dma8); + chan->Register_Callback(0); + chan->Write(1,&val); } } static void DSP_ADC_CallBack(DmaChannel * chan, DMAEvent event) { if (event!=DMA_UNMASKED) return; Bit8u val=128; + DmaChannel * ch=GetDMAChannel(sb.hw.dma8); while (sb.dma.left--) { - DmaChannels[sb.hw.dma8]->Write(1,&val); + ch->Write(1,&val); } SB_RaiseIRQ(SB_IRQ_8); - DmaChannels[sb.hw.dma8]->Register_Callback(0); + ch->Register_Callback(0); } Bitu DEBUG_EnableDebugger(void); @@ -684,7 +686,7 @@ static void DSP_DoCommand(void) { case 0x24: /* Singe Cycle 8-Bit DMA ADC */ sb.dma.left=sb.dma.total=1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8); LOG(LOG_SB,LOG_ERROR)("DSP:Faked ADC for %d bytes",sb.dma.total); - DmaChannels[sb.hw.dma8]->Register_Callback(DSP_ADC_CallBack); + GetDMAChannel(sb.hw.dma8)->Register_Callback(DSP_ADC_CallBack); break; case 0x14: /* Singe Cycle 8-Bit DMA DAC */ case 0x91: /* Singe Cycle 8-Bit DMA High speed DAC */ @@ -794,7 +796,7 @@ static void DSP_DoCommand(void) { if ((sb.dsp.in.data[0] >> i) & 0x01) sb.e2.value += E2_incr_table[sb.e2.count % 4][i]; sb.e2.value += E2_incr_table[sb.e2.count % 4][8]; sb.e2.count++; - DmaChannels[sb.hw.dma8]->Register_Callback(DSP_E2_DMA_CallBack); + GetDMAChannel(sb.hw.dma8)->Register_Callback(DSP_E2_DMA_CallBack); } break; case 0xe3: /* DSP Copyright */ @@ -1105,12 +1107,14 @@ private: else if (!strcasecmp(sbtype,"sb16")) type=SBT_16; else if (!strcasecmp(sbtype,"none")) type=SBT_NONE; else type=SBT_16; - - if (machine!=MCH_VGA && type==SBT_16) type=SBT_PRO2; - + + if (type==SBT_16) { + if ((machine!=MCH_VGA) || !SecondDMAControllerAvailable()) type=SBT_PRO2; + } + /* OPL/CMS Init */ const char * omode=config->Get_string("oplmode"); - if (!strcasecmp(omode,"none")) opl_mode=OPL_none; + if (!strcasecmp(omode,"none")) opl_mode=OPL_none; else if (!strcasecmp(omode,"cms")) opl_mode=OPL_cms; else if (!strcasecmp(omode,"opl2")) opl_mode=OPL_opl2; else if (!strcasecmp(omode,"dualopl2")) opl_mode=OPL_dualopl2; @@ -1186,7 +1190,6 @@ public: } ~SBLASTER() { - Bitu i; Section_prop * section=static_cast(m_configuration); OPL_Mode opl_mode; Find_Type_And_Opl(section,sb.type,opl_mode); diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index abcdc996..33ffd8e1 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -27,6 +27,7 @@ #include "mem.h" #include "setup.h" #include "pic.h" +#include "dma.h" #define DAC_CLOCK 3570000 #define MAX_OUTPUT 0x7fff @@ -308,7 +309,7 @@ static void SN76496_set_gain(int gain) class TANDYSOUND: public Module_base { private: - IO_WriteHandleObject WriteHandler[2]; + IO_WriteHandleObject WriteHandler[3]; MixerObject MixerChan; public: TANDYSOUND(Section* configuration):Module_base(configuration){ @@ -318,16 +319,21 @@ public: if (machine==MCH_TANDY) { /* enable tandy sound if tandy=true/auto */ if ((strcmp(section->Get_string("tandy"),"true")!=0) && + (strcmp(section->Get_string("tandy"),"on")!=0) && (strcmp(section->Get_string("tandy"),"auto")!=0)) return; } else { /* only enable tandy sound if tandy=true */ - if (strcmp(section->Get_string("tandy"),"true")!=0) return; + if ((strcmp(section->Get_string("tandy"),"true")!=0) && + (strcmp(section->Get_string("tandy"),"on")!=0)) return; + + /* ports from second DMA controller conflict with tandy ports */ + CloseSecondDMAController(); + + WriteHandler[2].Install(0x1e0,SN76496Write,IO_MB,2); } - if (machine==MCH_TANDY) { - WriteHandler[0].Install(0xc0,SN76496Write,IO_MB,2); - WriteHandler[1].Install(0xc4,TandyDACWrite,IO_MB,4); - } else WriteHandler[0].Install(0x1e0,SN76496Write,IO_MB,2); + WriteHandler[0].Install(0xc0,SN76496Write,IO_MB,2); + WriteHandler[1].Install(0xc4,TandyDACWrite,IO_MB,4); Bit32u sample_rate = section->Get_int("tandyrate");