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
This commit is contained in:
parent
07be3858f1
commit
f22e8d5041
6 changed files with 207 additions and 142 deletions
|
@ -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
|
||||
|
|
|
@ -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 <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Section_prop *>(m_configuration);
|
||||
OPL_Mode opl_mode;
|
||||
Find_Type_And_Opl(section,sb.type,opl_mode);
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Add table
Reference in a new issue