📄 dmautil.c
字号:
/***************************************************************************
FILE NAME: DMAUTIL.C
FILE DESCRIPTION:
This file is a part of DM6430 driver. It contains functions that
implement DMA on DM6430 board.
PROJECT NAME: Part of DM6430 DOS Driver
DRIVER VERSION: 1.1
COMPILER: Borland C++ 3.1
TARGET: Real-Mode DOS
Copyright 2003 RTD Embedded Technologies
***************************************************************************/
#include <alloc.h>
#include <dos.h>
#include <conio.h>
int far* allocdmabuffer(unsigned long buffersize, unsigned int DMAChannel, unsigned int *DMAPage, unsigned int *DMAPageOffset){
int far *dmabufferptr;
int far *TestBuffer[10];
unsigned long LinearAddress, PageOffset;
int i,j;
i = 0;
TestBuffer[0] = (int far*)farmalloc(buffersize);
if (TestBuffer[0] == NULL){
// cprintf("Error Not enough memory\r\n");
// cprintf("%ld Bytes available\r\n",coreleft());
return(NULL);
}
// Compute liner address: 16 * Segment + Offset.
LinearAddress = 16L * (long) FP_SEG(TestBuffer[0]) + FP_OFF(TestBuffer[0]);
// Check to see if TestBuffer straddles a 64k Page boundary
if ( (LinearAddress/0x10000L) != (LinearAddress + buffersize)/0x10000L) {
// DMA buffer straddles a 64k PAGE boundary.
farfree(TestBuffer[0]);
PageOffset = LinearAddress % 0x10000L;
dmabufferptr = NULL;
// Loop until find a buffer that does not cross a page boundry.
while (dmabufferptr == NULL){
// Allocate a buffer to move to next page.
TestBuffer[i] = (int far*)farmalloc(0x10000L - PageOffset);
// If TestBuffer is NULL out of memory
if (TestBuffer[i] == NULL){
// cprintf("Error Allocating DMA buffer out of memory\r\n");
// cprintf("%ld Bytes available\r\n",coreleft());
// Free all Test buffers made.
for (j = 0; j <= i;j++){
farfree(TestBuffer[j]);
}
return(NULL); // return Null
} // end if
// Allocate DMA buffer
dmabufferptr = (int far*)farmalloc(buffersize);
// If Dmabufferptr = NULL out of memory
if (dmabufferptr == NULL){
// cprintf("Error Allocating DMA buffer out of memory.\r\n");
// cprintf("%ld Bytes available\r\n",coreleft());
// Free all TestBuffers
for (j = 0; j<=i;j++){
farfree(TestBuffer[j]);
}
return(NULL);
}
// Check if DMA buffer cross a page boundry.
LinearAddress = 16L * (long) FP_SEG(dmabufferptr) + FP_OFF(dmabufferptr);
if ( (LinearAddress/0x10000L) != (LinearAddress + buffersize)/0x10000L) {
//DMA buffer straddles a 64k page
farfree(dmabufferptr);
dmabufferptr = NULL;
i++;
}
} // end while
// Free all TestBuffers
for (j = 0; j <= i; j++){
farfree(TestBuffer[j]);
}
} else {
// DMA buffer OK
dmabufferptr = TestBuffer[0];
} // end if
if (DMAChannel > 3){ // AT Controller
*DMAPage = (unsigned int)((LinearAddress / 0x10000L) & 0xFE);
*DMAPageOffset = (unsigned int)((LinearAddress >>1) % 0x10000L);
} else { // XT Controller
*DMAPage = LinearAddress/0x10000L;
*DMAPageOffset = LinearAddress % 0x10000L;
}
return(dmabufferptr);
} // allocdmabuffer
void freedmabuffer(int far* dmabuffer){
farfree(dmabuffer);
} // freedmabuffer
void SetDMAController(int DMAChannel,int Mode,unsigned int page,
unsigned int page_offset, unsigned long NumberofBytes){
unsigned DMAAddress,DMACount,DMAPageReg;
unsigned MaskRegister,ModeRegister,FlipFlopRegister;
unsigned char lsb,msb;
unsigned long TransferCount;
// Set AT or XT DMA Registers
if (DMAChannel > 3){ // AT Controller
MaskRegister = 0XD4;
ModeRegister = 0XD6;
FlipFlopRegister = 0XD8;
TransferCount = (NumberofBytes / 2 )-1;
} else {
MaskRegister = 0X0A; // XT Controller
ModeRegister = 0X0B;
FlipFlopRegister = 0X0C;
TransferCount = NumberofBytes - 1;
}
// Set up DMA Controller
switch (DMAChannel) {
case 1 : DMAPageReg = 0x83;
DMAAddress = 0x02;
DMACount = 0x03;
break;
case 3 : DMAPageReg = 0x82;
DMAAddress = 0x06;
DMACount = 0x07;
break;
case 5 : DMAPageReg = 0x8B;
DMAAddress = 0xC4;
DMACount = 0xC6;
DMAChannel = DMAChannel - 4;
break;
case 6 : DMAPageReg = 0x89;
DMAAddress = 0xC8;
DMACount = 0xCA;
DMAChannel = DMAChannel - 4;
break;
case 7 : DMAPageReg = 0x8A;
DMAAddress = 0xCC;
DMACount = 0xCE;
DMAChannel = DMAChannel - 4;
break;
} //switch
outportb(MaskRegister, (4 | DMAChannel)); //DISABLE DMA CHANNEL MASK
outportb(ModeRegister, (DMAChannel |Mode)); //SET DMA MODE
outportb(FlipFlopRegister,0); //Clear DMA Byte Flip-Flop
outportb(DMAPageReg, page); //SET DMA MEMORY PAGE
lsb = page_offset % 256; // Set Page Offset
msb = page_offset /256;
outportb(DMAAddress,lsb);
outportb(DMAAddress,msb);
lsb = TransferCount % 256; // Write Number of Transfers
msb = TransferCount /256;
outportb(DMACount,lsb);
outportb(DMACount,msb);
} // SetDMAController
void EnableDMA(int DMAChannel){
// Set Mask Register
if (DMAChannel > 3) {
outportb(0xD4,DMAChannel-4); // AT Controller
} else {
outportb(0x0A,DMAChannel); // XT Controller
}
} // EnableDMA
void DisableDMA(int DMAChannel){
// Set Mask Register
if (DMAChannel > 3) {
outportb(0xD4,4 | (DMAChannel-4)); // AT Controller
} else {
outportb(0x0A,4 | DMAChannel); // XT Controller
}
} // DisableDMA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -