⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dmautil.c

📁 rt采集卡dos下dm6430驱动源代码
💻 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 + -