/*******************************************************************/ /* Advanced Communication Board Developer Toolkit 1993 */ /* For use with Advanced Communication Boards */ /* DMA.C */ /* This file defines routines that interface to the 8237 DMA */ /* controller. */ /* Source file is DMA.c */ /* .OBJ File Linked to Program for DMA Transfers */ /*******************************************************************/ /*******************************************************************/ #include /*contains FP_SEG and FP_OFF macro*/ #include "dma.h" #ifdef _BORLAND #define OUT outportb #define IN inportb #define FAR far #else #define OUT _outp #define IN _inp #define FAR __far #endif #define RESET_DMA_FLIP_FLOP OUT(0x0c, 0); #define LOBYTE(w) ((unsigned char)(w)) #define HIBYTE(w) ((unsigned char)(((unsigned short)(w) >> 8) & 0xFF)) #define LOWORD(l) ((unsigned short)(unsigned long)(l)) #define HIWORD(l) ((unsigned short)((((unsigned long)(l)) >> 16) & 0xFFFF)) #define ptrToLong(ptr) ((((unsigned long)FP_SEG(ptr)) <<4) + FP_OFF(ptr)) /*******************************************************************/ /* SetPageRegister : */ /* Set the DMA Page Register with the correct value */ /* Parameters: wDMA - DMA selection constant from DMA.H */ /* wSEG1 - Segment of DMA Buffer */ /* wOFF1 - Offset of DMA Buffer */ /* Return: Nothing */ /*******************************************************************/ /* Note this is not include in the C module, please see the SetPageRegisterEx() routine. */ /*******************************************************************/ /* SetPageRegisterEx : */ /* Set the DMA Page Register with the correct value */ /* Parameters: wDMA - DMA selection constant from DMA.H */ /* fpBUFFER - Far Ptr to DMA Buffer */ /* Return: Nothing */ /*******************************************************************/ void SetPageRegisterEx(unsigned short wDMA,unsigned char FAR * fpBUFFER) { unsigned char Temp; unsigned long BUFF_LONG; BUFF_LONG = ptrToLong(fpBUFFER); RESET_DMA_FLIP_FLOP /*Reset DMA Flip Flop*/ Temp = (unsigned char)(BUFF_LONG & 0x000000ff); OUT(LOBYTE(wDMA) ,Temp); /* Low Address */ Temp = (unsigned char)((BUFF_LONG >> 8) & 0x000000ff); OUT(LOBYTE(wDMA) ,Temp); /* High Address */ Temp = (unsigned char)((BUFF_LONG >> 16) & 0x0000000f); /*mhb*/ OUT(HIBYTE(wDMA) ,Temp); /*Page Register*/ } /*******************************************************************/ /* SetTC : */ /* Set the DMA Terminal Count Register Contents */ /* Parameters: wDMA - DMA selection constant from DMA.H */ /* wTC - Terminal Count */ /* Return: Nothing */ /*******************************************************************/ void SetTC(unsigned short wDMA,unsigned short wTC) { RESET_DMA_FLIP_FLOP wDMA = (wDMA & 0x00ff) + 1; OUT(wDMA, LOBYTE(wTC)); OUT(wDMA, HIBYTE(wTC)); } /*******************************************************************/ /* GetTC : */ /* Get the DMA Terminal Count Register */ /* Parameters: wDMA - DMA selection constant from DMA.H */ /* Return: DMA Terminal Count for selected DMA channel */ /*******************************************************************/ unsigned short GetTC(unsigned short wDMA) { unsigned short wTemp1, wTemp2; RESET_DMA_FLIP_FLOP wDMA = (wDMA & 0x00ff) + 1; wTemp1 = IN(wDMA); /*Get Count - Low Byte*/ wTemp2 = IN(wDMA); /*Get Count - High Byte*/ wTemp1 = wTemp1 & 0x00ff; /* Clear off high byte*/ wTemp2 = wTemp2 << 8; /* Shift to high byte to make a word*/ /*mhb*/ wTemp2 = wTemp2 & 0xff00; /* Clear off low byte*/ return( wTemp1 | wTemp2); } /*******************************************************************/ /* MaskDMA : */ /* Set the Mask Register */ /* Parameters: bMASK - D0-D3 = DMA1-DMA3 */ /* Return: Nothing */ /*******************************************************************/ void MaskDMA(unsigned char bMASK1) { OUT( 0x0f, bMASK1); /*DMA Mask Reg is at I/O address 0x0f*/ } /*******************************************************************/ /* SetDMAMode : */ /* Set the DMA Mode Register */ /* Parameters: bDMA - DMA selection constant from DMA.H */ /* Return: Nothing */ /*******************************************************************/ void SetDMAMode(unsigned char bDMA) { OUT( 0x0b, bDMA); /* DMA Mode Reg is at I/O address 0x0b*/ } /*******************************************************************/ /* SingleMaskDMA : */ /* Set the DMA Single Mask Register */ /* Parameters: bMASK1 - DMA selection constant from DMA.H */ /* Return: Nothing */ /*******************************************************************/ void SingleMaskDMA(unsigned char bMASK1) { OUT(0x0a, bMASK1); /*DMA Single Mask Reg is at I/O address 0x0a*/ } /*******************************************************************/ /* CheckDMAPage : */ /* Check for buffer on 64K boundary */ /* Parameters: wTC - DMA Terminal Count */ /* wSEG1 - segment of buffer */ /* wOFF1 - offset of buffer */ /* Return: Zero if OK otherwise error */ /*******************************************************************/ /* NOTE: This routine is not include in the C module. See CheckDMAPageEx*/ /*******************************************************************/ /* CheckDMAPageEx : */ /* Check for buffer on 64K boundary */ /* Parameters: wTC - DMA Terminal Count */ /* fpBUFFER - Far Ptr to DMA buffer */ /* Return: Zero if OK otherwise error */ /*******************************************************************/ int CheckDMAPageEx(unsigned short wTC, unsigned char FAR * fpBUFFER) { unsigned long Temp1, Temp2; Temp1 = (unsigned char)((ptrToLong(fpBUFFER) >> 16) & 0x0000000f); Temp2 = (unsigned char)(((ptrToLong(fpBUFFER)+wTC) >> 16) & 0x0000000f); return(Temp1 - Temp2); } /*******************************************************************/