;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Advanced Communication Board Developer Toolkit ;; ;; (c)Copyright 1993-1995, Sealevel Systems Incorporated ;; ;; ;; ;; For use with Advanced Communication Boards ;; ;; DMA.ASM ;; ;; This file defines routines that interface to the 8237 DMA ;; ;; controller. ;; ;; Source file is DMA.ASM ;; ;; .OBJ File Linked to Program for DMA Transfers ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TITLE DMA ifdef LMOD .MODEL LARGE elseifdef MMOD .MODEL MEDIUM elseifdef TMOD .MODEL TINY else .MODEL SMALL endif ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; MACROS ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pause MACRO ; I/O recovery time jmp short $+2 ;This purges the CPU prefetch cue, which allows jmp short $+2 ; for enough delay for most bus speeds speeds. jmp short $+2 ; ENDM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INCLUDE DMA.INC .DATA .CODE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 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 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetPageRegister PROC C PUBLIC USES AX BX CX DX, wDMA:WORD, wSEG1:WORD, wOFF1:WORD call RESET_DMA_FF ;Reset DMA Flip Flop mov ax, wSEG1 mov bx, 10h ;shift left one hex digit mul bx mov bx, wOFF1 mov cx, wDMA call SET_PAGE_REG ret SetPageRegister ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 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 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetPageRegisterEx PROC C PUBLIC USES AX BX CX DX ES, wDMA:WORD, fpBUFFER:DWORD call RESET_DMA_FF ;Reset DMA Flip Flop les bx, fpBUFFER push bx mov ax, es mov bx,10h mul bx pop bx mov cx, wDMA call SET_PAGE_REG ret SetPageRegisterEx ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SET_PAGE_REG : Internal.NEAR ;; ;; Set the DMA Page Register with the correct value ;; ;; Return: Nothing ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SET_PAGE_REG PROC NEAR add ax, bx ;Lower 16 Bits - HI-BYTE in ah, LO-BYTE in al adc dl, 0 ;Upper 4 Bits - DMA Page in DL push dx ;Save it xor dx, dx mov bx, cx mov dl, bl out dx, al ;Send Low Byte pause mov al, ah ;Restore High Byte out dx, al ;Send High Byte pause pop dx ;Restore Upper 4 Bits of Address mov al, dl xor dx, dx mov dl, bh ;Page Register out dx, al ;Write to Page Reg pause ret SET_PAGE_REG ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; RESET_DMA_FF : INTERNAL.NEAR ;; ;; Resets the DMA Controller Internal Flip Flop ;; ;; Parameters: Nothing ;; ;; Return: Nothing ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RESET_DMA_FF PROC NEAR push ax ;Reset Internal DMA Flip/Flop mov al, 0 out 0ch, al pause pop ax ret RESET_DMA_FF ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SetTC : ;; ;; Set the DMA Terminal Count Register Contents ;; ;; Parameters: wDMA - DMA selection constant from DMA.H ;; ;; wTC - Terminal Count ;; ;; Return: Nothing ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetTC PROC C PUBLIC USES AX DX, wDMA:WORD, wTC:WORD call RESET_DMA_FF ;Reset DMA Flip Flop mov dx, wDMA add dl, 1 mov dh, 00 mov ax, wTC out dx, al pause mov al, ah out dx, al pause ret SetTC ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; GetTC : ;; ;; Get the DMA Terminal Count Register ;; ;; Parameters: wDMA - DMA selection constant from DMA.H ;; ;; Return: DMA Terminal Count for selected DMA channel ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GetTC PROC C PUBLIC USES BX DX, wDMA:WORD call RESET_DMA_FF ;Reset DMA Flip Flop mov dx, wDMA mov dh, 0 add dl, 1 in al, dx ;Get Count - Low Byte pause mov bl, al ;Save it mov bh, 0 in al, dx ;Get Count - High Byte pause mov ah, al mov al, 0 or ax, bx ;RET AX ret GetTC ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; MaskDMA : ;; ;; Set the Mask Register ;; ;; Parameters: bMASK - D0-D3 = DMA1-DMA3 ;; ;; Return: Nothing ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MaskDMA PROC C PUBLIC USES AX, bMASK1:BYTE mov al, bMASK1 ;DMA Mask All Registers out 0fh, al ;Value Passed in al pause ret MaskDMA ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SetDMAMode : ;; ;; Set the DMA Mode Register ;; ;; Parameters: bDMA - DMA selection constant from DMA.H ;; ;; Return: Nothing ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetDMAMode PROC C PUBLIC USES AX, bDMA:BYTE mov al, bDMA ;DMA Set Mode Register out 0Bh, al ;Value Passed in AL pause ret SetDMAMode ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SingleMaskDMA : ;; ;; Set the DMA Single Mask Register ;; ;; Parameters: bMASK1 - DMA selection constant from DMA.H ;; ;; Return: Nothing ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SingleMaskDMA PROC C PUBLIC USES AX, bMASK1:BYTE mov al, bMASK1 ;DMA Single Mask Register out 0Ah, al ;Value Passed in AL pause ret SingleMaskDMA ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 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 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CheckDMAPage PROC C PUBLIC USES BX DX, wTC:WORD, wSEG1:WORD, wOFF1:WORD mov ax, wSEG1 mov bx, 10h ;shift left one hex digit mul bx ;upper 4 bits to dx mov bx, wOFF1 add ax, bx ;Lower 16 Bits - HI-BYTE in ah, LO-BYTE in al adc dl, 0 ;Upper 4 Bits - DMA Page in DL push dx ;Save it mov ax, wSEG1 mov bx, 10h ;shift left one hex digit mul bx ;upper 4 bits to dx mov bx, wOFF1 add bx, wTC ;Ending Offset of DMA Buffer add ax, bx ;Lower 16 Bits - HI-BYTE in ah, LO-BYTE in al adc dl, 0 ;Upper 4 Bits - DMA Page in DL mov ax, dx ;Save Ending Page Address pop dx ;Restore Starting Page Address sub ax, dx ;are they the same Page Address jz @f ;jump if they are the same ret ;return diff (1) @@: xor ax, ax ret CheckDMAPage ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; CheckDMAPageEx : ;; ;; Check for buffer on 64K boundary ;; ;; Parameters: wTC - DMA Terminal Count ;; ;; fpBUFFER - Far Ptr to DMA buffer ;; ;; Return: Zero if OK otherwise error ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CheckDMAPageEx PROC C PUBLIC USES BX ES, wTC:WORD, fpBUFFER:DWORD les bx, fpBUFFER ;Load far pointer Seg:offset INVOKE CheckDMAPage, wTC, ES, BX ret CheckDMAPageEx ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END