1
0
Fork 0

enable ems remapping during dma transfers from the pageframe

(fixes sound in several MicroProse games)


Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2512
This commit is contained in:
Sebastian Strohhäcker 2006-02-24 14:31:24 +00:00
parent 6472a2bbf3
commit da4e039021

View file

@ -27,13 +27,26 @@
DmaController *DmaControllers[2];
#define EMM_PAGEFRAME4K ((0xE000*16)/4096)
Bit32u ems_board_mapping[LINK_START];
static void UpdateEMSMapping(void) {
/* if EMS is not present, this will result in a 1:1 mapping */
Bitu i;
for (i=0;i<0x10;i++) {
ems_board_mapping[EMM_PAGEFRAME4K+i]=paging.firstmb[EMM_PAGEFRAME4K+i];
}
}
/* 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) /* cares for EMS pageframe etc. */
page = paging.firstmb[page];
/* care for EMS pageframe etc. */
if (page < EMM_PAGEFRAME4K) page = paging.firstmb[page];
else if (page < EMM_PAGEFRAME4K+0x10) page = ems_board_mapping[page];
else if (page < LINK_START) page = paging.firstmb[page];
*write++=phys_readb(page*4096 + (pt & 4095));
}
}
@ -43,8 +56,10 @@ 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) /* cares for EMS pageframe etc. */
page = paging.firstmb[page];
/* care for EMS pageframe etc. */
if (page < EMM_PAGEFRAME4K) page = paging.firstmb[page];
else if (page < EMM_PAGEFRAME4K+0x10) page = ems_board_mapping[page];
else if (page < LINK_START) page = paging.firstmb[page];
phys_writeb(page*4096 + (pt & 4095), *read++);
}
}
@ -81,14 +96,17 @@ static void DMA_Write_Port(Bitu port,Bitu val,Bitu iolen) {
} 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;
} else {
UpdateEMSMapping();
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;
}
}
}
@ -116,6 +134,7 @@ void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) {
switch (reg) {
/* set base address of DMA transfer (1st byte low part, 2nd byte high part) */
case 0x0:case 0x2:case 0x4:case 0x6:
UpdateEMSMapping();
chan=GetChannel(reg >> 1);
flipflop=!flipflop;
if (flipflop) {
@ -128,6 +147,7 @@ void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) {
break;
/* set DMA transfer count (1st byte low part, 2nd byte high part) */
case 0x1:case 0x3:case 0x5:case 0x7:
UpdateEMSMapping();
chan=GetChannel(reg >> 1);
flipflop=!flipflop;
if (flipflop) {
@ -144,10 +164,12 @@ void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) {
//TODO Warning?
break;
case 0xa: /* Mask Register */
if ((val & 0x4)==0) UpdateEMSMapping();
chan=GetChannel(val & 3);
chan->SetMask((val & 0x4)>0);
break;
case 0xb: /* Mode Register */
UpdateEMSMapping();
chan=GetChannel(val & 3);
chan->autoinit=(val & 0x10) > 0;
chan->increment=(val & 0x20) > 0;
@ -165,12 +187,14 @@ void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) {
flipflop=false;
break;
case 0xe: /* Clear Mask register */
UpdateEMSMapping();
for (i=0;i<4;i++) {
chan=GetChannel(i);
chan->SetMask(false);
}
break;
case 0xf: /* Multiple Mask register */
UpdateEMSMapping();
for (i=0;i<4;i++) {
chan=GetChannel(i);
chan->SetMask(val & 1);
@ -253,10 +277,12 @@ again:
currcnt=basecnt;
curraddr=baseaddr;
if (want) goto again;
UpdateEMSMapping();
} else {
curraddr+=left;
currcnt=0xffff;
masked=true;
UpdateEMSMapping();
DoCallBack(DMA_TRANSFEREND);
}
}
@ -282,10 +308,12 @@ again:
currcnt=basecnt;
curraddr=baseaddr;
if (want) goto again;
UpdateEMSMapping();
} else {
curraddr+=left;
currcnt=0xffff;
masked=true;
UpdateEMSMapping();
DoCallBack(DMA_TRANSFEREND);
}
}
@ -341,4 +369,8 @@ void DMA_Destroy(Section* sec){
void DMA_Init(Section* sec) {
test = new DMA(sec);
sec->AddDestroyFunction(&DMA_Destroy);
Bitu i;
for (i=0;i<LINK_START;i++) {
ems_board_mapping[i]=i;
}
}