Tvůrce webu je i pro tebe! Postav třeba web. Bez grafika. Bez kodéra. Hned.
wz

Obsah / Ovladače / DMA / Funkce interface ovladače řadiče DMA

Zdrojový kód: DRIVERS\SYSTEM\DMA.ASM


Funkce interface ovladače řadiče DMA


DMADev:		DEVICEDMA 0,DEV_STATIC,1,0,0,DMA_CHANNELS,DMADev

DMADevRes1:	DEVRESOURCE DMADevRes2,DMADevRes0,DMA_CASCADE,DMA_CASCADE, \
		 DEVRES_DMA,DEVRES_STATIC,DMADevRes1Name
DMADevRes2:	DEVRESOURCE DMADevRes3,DMADevRes1,DMA1_BASE,DMA1_BASE+15, \
		 DEVRES_PORT,DEVRES_STATIC,DMADevRes2Name
DMADevRes3:	DEVRESOURCE DMADevResN,DMADevRes2,DMA_PAGE_BASE, \
		 DMA_PAGE_BASE+15,DEVRES_PORT,DEVRES_STATIC,DMADevRes3Name
DMADevResN:	DEVRESOURCE DMADevRes0,DMADevRes3,DMA2_BASE,DMA2_BASE+31, \
		 DEVRES_PORT,DEVRES_STATIC,DMADevResNName

DMADevName:	CTEXTDATA 'dma'
DMADevShort:	CTEXTDATA 'DMA 8237A'

DMADevFull:	LANGTEXTSTR DMADevFullEN,LANG_ENGLISH,SUBLANG_DEFAULT,2
 		LANGTEXTSTR DMADevFullCZ,LANG_CZECH,  SUBLANG_DEFAULT,0

DMADevFullEN:	CTEXTDATA 'Direct memory access (DMA) controller 8237A'
DMADevFullCZ:	CTEXTDATA 0c5h,98h,'adi',0c4h,8dh,' p',0c5h,99h,0c3h,0adh,\
			'm',0c3h,0a9h,'ho p',0c5h,99h,0c3h,0adh,'stupu do pam',\
			0c4h,9bh,'ti (DMA) 8237A'

DMADevInt:	dd	DEV_GEN_ID
		dd	DEV_DMA_ID
		dd	DEV_NUL_ID

DMADevRes1Name:	CTEXTDATA 'cascade'
DMADevRes2Name:	CTEXTDATA 'ctrl#1'
DMADevRes3Name:	CTEXTDATA 'pageregs'
DMADevResNName:	CTEXTDATA 'ctrl#2'

DMADevice:	dd	DMADev			; current DMA device descriptor

%define		DMADevVendor  DefaultVendor

DMADev je struktura popisovače standardního ovladače řadiče DMA. V proměnné DMADevice je uložen ukazatel na aktuální ovladač řadiče DMA - při instalaci nového ovladače je tento ukazatel přepsán novým ukazatelem.


; -----------------------------------------------------------------------------
;                           Install DMA device
; -----------------------------------------------------------------------------
; OUTPUT:	CY = error
; -----------------------------------------------------------------------------

; ------------- Push registers

DMAInstall:	push	ebx		; push EBX
		push	ecx		; push ECX

; ------------- Register DMA device

		mov	ebx,DMADev	; EBX <- device descriptor
		xor	ecx,ecx		; ECX <- 0, no parent device
		call	DevRegister	; register device

; ------------- Pop registers

		pop	ecx		; pop ECX
		pop	ebx		; pop EBX
		ret

Funkce DMAInstall nainstaluje standardní ovladač řadiče DMA - zaregistruje ovladač do systému. V případě chyby je navrácen příznak chyby CY.


; -----------------------------------------------------------------------------
;                           Uninstall DMA device
; -----------------------------------------------------------------------------
; OUTPUT:	CY = error
; -----------------------------------------------------------------------------

; ------------- Push registers

DMAUninstall:	push	ebx		; push EBX

; ------------- Unregister DMA device

		mov	ebx,DMADev	; EBX <- device descriptor
		call	DevUnregister	; unregister device

; ------------- Pop registers

		pop	ebx		; pop EBX
		ret

Funkce DMAUninstall odinstaluje standardní ovladač řadiče DMA - odregistruje ovladač ze systému. V případě chyby je navrácen příznak chyby CY. Funkce nezajistí instalaci náhradního ovladače řadiče DMA.


; -----------------------------------------------------------------------------
;                   Driver function: Initialize DMA device
; -----------------------------------------------------------------------------
; INPUT:	EBX = device descriptor DEVDMA
; OUTPUT:	CY = error
; -----------------------------------------------------------------------------

; ------------- Push registers

DMADevInit:	push	eax		; push EAX
		push	edx		; push EDX

; ------------- Clear mask

		mov	dword [ebx+DEVDMA_Used],~(B0+B1+B2+B3+B5+B6+B7) ; mask
		mov	dword [ebx+DEVDMA_Running],0 ; running channels

; ------------- Send master clear to DMA controllers

		out	DMA1_RESET,al	; send master clear to controller 1
		out	DMA2_RESET,al	; send master clear to controller 2

; ------------- Clear DMA channel flip-flop

		out	DMA1_CLRFF,al	; clear DMA channel flip-flop on ctrl 1
		out	DMA2_CLRFF,al	; clear DMA channel flip-flop on ctrl 2

; ------------- Initialize channel address and count registers of controller 1

		xor	edx,edx		; DX <- 0, base port od controller 1
		mov	al,0ffh		; EAX <- 0ffh
DMADevInit2:	out	dx,al		; initialize one register LOW
		jmp	short DMADevInit3 ; short delay
DMADevInit3:	out	dx,al		; initialize one register HIGH		
		inc	edx		; increase port
		cmp	dl,DMA1_BASE+8	; all registers done?
		jne	DMADevInit2	; initialize next register

; ------------- Initialize channel address and count registers of controller 2

		mov	dl,DMA2_BASE	; DX <- base port of controller 2
DMADevInit4:	out	dx,al		; initialize one register LOW
		jmp	short DMADevInit5 ; short delay
DMADevInit5:	out	dx,al		; initialize one register HIGH		
		inc	edx		; increase port
		inc	edx		; increase port
		cmp	dl,DMA2_BASE+2*8 ; all registers done?
		jne	DMADevInit4	; initialize next register

; ------------- Set DMA command
; DACK sense low, DREQ sense high, late write, fixed priority, normal timing,
; controller enable, channel 0 address hold disable, memory-to-memory disable

		inc	eax		; AL <- 0
		out	DMA1_CMD,al	; set command to controller 1
		out	DMA2_CMD,al	; set command to controller 2

; ------------- Set mode of all DMA channels
; single mode, address increment, autoinitialization disable, verify transfer

		mov	al,DMAMODE_CASCADE ; AL <- cascade mode of channel 4
		out	DMA2_MODE,al	; set mode of channel 4
		mov	al,DMAMODE_VERIFY ; AL <- mode of channel 0
		out	DMA1_MODE,al	; set mode of channel 0
		inc	eax		; AL <- mode of channel 1 and 5
		out	DMA1_MODE,al	; set mode of channel 1
		out	DMA2_MODE,al	; set mode of channel 5
		inc	eax		; AL <- mode of channel 2 and 6
		out	DMA1_MODE,al	; set mode of channel 2
		out	DMA2_MODE,al	; set mode of channel 6
		inc	eax		; AL <- mode of channel 3 and 7
		out	DMA1_MODE,al	; set mode of channel 3
		out	DMA2_MODE,al	; set mode of channel 7

; ------------- Set mask of channels (disable all channels except channel 4)

		mov	al,B0+B1+B2+B3	; set mask of channels 0 to 3
		out	DMA1_AMASK,al	; disable all channels
		mov	al,B1+B2+B3	; set mask of channels 5 to 7
		out	DMA2_AMASK,al	; disable all channels except channel 4

; ------------- Initialize page registers (except DMA refresh page register)

		mov	al,0		; AL <- 0
		mov	dl,DMA_PAGE_BASE+1 ; DL <- start DMA page register
DMADevInit6:	out	dx,al		; clear one register
		inc	edx		; increase register address
		cmp	dl,DMA_PAGE_BASE+15 ; last DMA page register?
		jne	DMADevInit6	; initialize next register

; ------------- Pop registers

		clc			; clear error flag
		pop	edx		; pop EDX
		pop	eax		; pop EAX
		ret

Funkce DMADevInit inicializuje ovladač řadiče DMA, jehož popisovač je funkci předán v registru EBX. V případě chyby navrátí funkce příznak chyby CY.

Funkce na začátku inicializuje masku volných DMA kanálů a masku běžících kanálů. Vyšle resetovací signál na oba řadiče a resetuje flip-flop příznak. Inicializují se registry adresy a čítače prvního řadiče na hodnotu 0ffh a poté stejně tak druhého řadiče. Vyšle se inicializační povel na oba řadiče (AL = 0) a všechny DMA kanály se nastaví na mód verifikace, pouze DMA4 se nastaví na kaskádový mód. Nastavením masky se všechny kanály zakážou (kromě DMA4). Stránkové registry kanálů se vynulují.


; -----------------------------------------------------------------------------
;                   Driver function: Deinitialize DMA device
; -----------------------------------------------------------------------------
; INPUT:	EBX = device descriptor DEVDMA
; OUTPUT:	CY = error
; -----------------------------------------------------------------------------

; ------------- Push registers

DMADevDeinit:	push	eax		; push EAX

; ------------- Stop DMA transfers

		xor	eax,eax		; EAX <- 0
DMADevDeInit2:	call	DMADevStop	; stop DMA transfer
		inc	eax		; increase channel number
		cmp	al,DMA_CHANNELS	; is it valid DMA channel?
		jb	DMADevDeInit2	; stop next DMA channel

; ------------- Pop registers

		clc			; clear error flag
		pop	eax		; pop EAX
		ret

Funkce DMADevDeinit deinicializuje ovladač řadiče DMA, jehož popisovač je funkci předán v registru EBX. V případě chyby navrátí funkce příznak chyby CY. Funkce zajistí zastavení probíhajících přenosů všech DMA kanálů.


; -----------------------------------------------------------------------------
;                    Driver function: Get DMA channel info
; -----------------------------------------------------------------------------
; INPUT:	EAX = DMA channel number
;		EBX = device descriptor DEVDMA
; OUTPUT:	ECX = number of channels
;		EDX = flags (see Channel info flags), 0=invalid channel
;		CY = invalid channel number (ECX is valid)
; -----------------------------------------------------------------------------

; ------------- Check DMA channel number

DMADevInfo:	mov	ecx,DMA_CHANNELS ; ECX <- number of DMA channels
		xor	edx,edx		; EDX <- 0, invalid channel
		cmp	eax,ecx		; check DMA channel number
		cmc			; set error flag
		jc	DMADevInfo8	; invalid channel number

; ------------- Prepare channel flags

		mov	dl,DMAINFO_CH4_7 ; channels 4..7
		cmp	al,4		; channel 4..7 ?
		jae	DMADevInfo2	; channel 4..7
		mov	dl,DMAINFO_CH0_3 ; otherwise channel 0..3

; ------------- Check if channel is in use

DMADevInfo2:	bt	dword [ebx+DEVDMA_Used],eax ; check if channel is used
		jnc	DMADevInfo4	; channel is not used
		or	dl,DMAINFO_USED	; set used flag

; ------------- Check if channel is running (it clears error flag NC)

DMADevInfo4:	bt	dword [ebx+DEVDMA_Running],eax ; is channel running?
		jnc	DMADevInfo8	; channel is not running
		or	dl,DMAINFO_RUNNING ; set running flag
DMADevInfo8:	ret

Funkce DMADevInfo poskytne informace o kanálu DMA, jehož číslo je funkci předáno v registru EAX. Registr EBX obsahuje na vstupu popisovač zařízení. Na výstupu z funkce je navrácen v registru ECX počet kanálů DMA a v registru EDX příznaky (nebo jejich kombinace) s těmito hodnotami: DMAINFO_VALID kanál je platný, DMAINFO_USED kanál je používán (vlastněn), DMAINFO_RUNNING na kanálu probíhá přenos dat, DMAINFO_8BIT kanál je 8-bitový (jinak 16-bitový), DMAINFO_BOUND blok dat nesmí překročit hranici 64 KB (jinak 128 KB), DMAINFO_ALIGN adresa musí být zarovnána na slovo, DMAINFO_16M limitace na nižších 16 MB paměti. V případě neplatného čísla DMA kanálu navrátí funkce příznak CY a obsah registru EDX je nulový. Počet kanálů navrácený v registru ECX je i v případě chyby platný. Funkce vyžaduje uzamknutí pomocí rychlého zámku.


; -----------------------------------------------------------------------------
;                     Driver function: Allocate DMA channel
; -----------------------------------------------------------------------------
; INPUT:	EAX = channel number
;		EBX = device descriptor DEVDMA
; OUTPUT:	CY = cannot allocate, channel already used
; -----------------------------------------------------------------------------

; ------------- Check channel number

DMADevAlloc:	cmp	eax,DMA_CHANNELS ; check channel number
		cmc			; set error flag if invalid channel
		jc	DMADevAlloc2	; invalid channel number

; ------------- Allocate channel

		bts	[ebx+DEVDMA_Used],eax ; set channel flag (CY = used)
DMADevAlloc2:	ret

Funkce DMADevAlloc slouží k alokaci (přivlastnění) DMA kanálu. Na vstupu funkce obsahuje registr EAX číslo kanálu DMA, který má být alokován. Registr EBX obsahuje popisovač zařízení. V případě chyby (kanál je již alokován nebo zadáno neplatné číslo kanálu) navrátí funkce příznak chyby CY. Funkce vyžaduje uzamknutí pomocí rychlého zámku (pro správnou funkci funkce to není nutné, používá atomickou operaci, ale z důvodu kompatibility do budoucna je to doporučeno).


; -----------------------------------------------------------------------------
;                     Driver function: Free DMA channel
; -----------------------------------------------------------------------------
; INPUT:	EAX = channel number
;		EBX = device descriptor DEVDMA
; OUTPUT:	CY = invalid channel number or it is already free or reserved
;			or it is still running (call DMADevStop first)
; -----------------------------------------------------------------------------

; ------------- Check channel number

DMADevFree:	cmp	eax,DMA_CHANNELS ; check channel number
		jae	DMADevFree8	; invalid channel number

; ------------- Reserved channel

		cmp	al,DMA_CASCADE	; cascade channel is reserved
		je	DMADevFree8	; channel is reserved

; ------------- Check if channel is running

		bt	dword [ebx+DEVDMA_Running],eax ; is channel running?
		jc	DMADevFree9	; channel is still running

; ------------- Free DMA channel (and check if it is used)

		btr	dword [ebx+DEVDMA_Used],eax ; reset usage bit
DMADevFree8:	cmc			; set error flag if it was not used
DMADevFree9:	ret

Funkce DMADevFree slouží k dealokaci (uvolnění) DMA kanálu. Na vstupu funkce obsahuje registr EAX číslo kanálu DMA, který má být uvolněn. Registr EBX obsahuje popisovač zařízení. V případě chyby (kanál není alokován nebo zadáno neplatné číslo kanálu nebo probíhá přenos dat) navrátí funkce příznak chyby CY. Není kontrolováno, zda kanál uvolňuje stejný vlastník, který si zažádal o jeho alokaci. Funkce vyžaduje uzamknutí pomocí rychlého zámku.


; -----------------------------------------------------------------------------
;                      Driver function: Start DMA transfer
; -----------------------------------------------------------------------------
; INPUT:	EAX = channel number
;		EBX = device descriptor DEVDMA
;		ECX = number of bytes (must be in range 2 to 64K, word aligned)
;		EDX = system address (word aligned)
;		ESI = DMA direction (DMADIR_READ, DMADIR_WRITE, DMADIR_VERIFY)
; OUTPUT:	CY = invalid argument (or channel is already running)
; NOTES:	Function translates system address to physical address.
;		Block cannot cross 64K boundary, size and address must be word
;			aligned, size can be max. 64 KB and transfered block 
;			must be in lower 16MB of physical RAM.
; -----------------------------------------------------------------------------

; ------------- Push registers

DMADevStart:	push	edx		; push EDX

; ------------- Check channel number

		cmp	eax,DMA_CHANNELS ; check channel number
		jae	DMADevStart8	; invalid channel number
		cmp	al,DMA_CASCADE	; cascade channel is reserved
		je	DMADevStart8	; channel is reserved

; ------------- Check if channel is used

		bt	dword [ebx+DEVDMA_Used],eax ; is channel used?
		jnc	DMADevStart8	; channel is not used

; ------------- Check number of bytes

		cmp	ecx,10000h	; maximal number of bytes
		ja	DMADevStart8	; size is out of range
		test	cl,1		; is size aligned?
		jnz	DMADevStart8	; size is not aligned
		jecxz	DMADevStart8	; size is 0

; ------------- Check DMA direction

		cmp	esi,DMADIR_NUM	; check maximal DMA direction
		jae	DMADevStart8	; invalid DMA direction

; ------------- Check address (and translate to physical memory)

		sub	edx,SYSTEM_ADDR ; translate to physical address
		jc	DMADevStart8	; invalid DMA address
		cmp	edx,DMAMAXMEM	; maximal DMA address
		jae	DMADevStart8	; invalid DMA address
		test	dl,1		; check if address is aligned
		jnz	DMADevStart8	; address is not word aligned

; ------------- Check 64K boundary

		push	ecx		; push ECX
		push	edx		; push EDX
		dec	ecx		; ECX <- last byte of size
		add	dx,cx		; check boundary
		pop	edx		; pop EDX
		pop	ecx		; pop ECX
		jc	DMADevStart8	; invalid boundary

; ------------- Check if channel is running and set running flag

		bts	dword [ebx+DEVDMA_Running],eax ; set running flag
		jc	DMADevStart8	; channel is already running

; ------------- Set DMA mode (in EDX)

		push	ebx		; push EBX
		mov	bl,[DMAModeTab+esi] ; BL <- DMA mode
		call	DMADevSetMode	; set DMA mode
		pop	ebx		; pop EBX

; ------------- Clear DMA channel flip-flop

		call	DMADevClearFF	; clear DMA channel flip-flop

; ------------- Set transfer address (in EDX)

		call	DMADevSetAddr	; set DMA address

; ------------- Set transfer size (in ECX)

		call	DMADevSetSize	; set transfer size

; ------------- Start DMA transfer

		call	DMADevEnable	; start DMA transfer

; ------------- OK

		pop	edx		; pop EDX
		clc			; clear error flag
		ret

; ------------- ERROR

DMADevStart8:	pop	edx		; pop EDX
DMADevStart9:	stc			; set error flag
		ret

; ------------- DMA modes

DMAModeTab:	db	DMAMODE_READ	; 0: DMADIR_READ
		db	DMAMODE_WRITE	; 1: DMADIR_WRITE
		db	DMAMODE_VERIFY	; 2: DMADIR_VERIFY

Funkce DMADevStart odstartuje DMA přenos dat. Na vstupu funkce obsahuje registr EAX číslo kanálu DMA, na kterém má být přenos odstartován. Registr EBX obsahuje popisovač zařízení. V registru ECX je nastaven počet bajtů k přenosu, v registru EDX adresa paměti v systému (tedy ne fyzické paměti) a v registru ESI je příznak směru přenosu: DMADIR_READ čtení ze zařízení, DMADIR_WRITE zápis na zařízení a DMADIR_VERIFY je verifikace dat ze zařízení. Současná verze ovladače má následující omezení: blok dat nesmí překrýt hranici adres 64 KB, maximální velikost bloku 64 KB, minimální velikost bloku 2 B, velikost musí být zarovnaná na slovo, adresa musí být zarovnaná na slovo a lze používat pouze nižších 16 MB fyzické paměti (blok získaný pomocí funkce DMAMemAlloc). V případě neplatného zadání některého z argumentů navrátí funkce příznak chyby CY. Funkce vyžaduje uzamknutí pomocí rychlého zámku.

Funkce nejdříve ověří platnost zadání parametrů: číslo kanálu (není povolen DMA4, který je rezervován pro kaskádové propojení řadičů), zda je kanál alokován, kontrola velikosti bloku dat (max. 64 KB, min. 2 B, musí být zarovnán na slovo), kontrola směru přenosu, kontrola adresy (rozsah SYSTEM_ADDR až SYSTEM_ADDR+DMAMAXMEM, adresa zarovnaná na slovo). Ověří se, zda blok dat nepřekryje hranici adres 64 KB. Nakonec se ověří, zda na kanálu neprobíhá nějaký přenos a současně se příznak probíhajícího přenosu nastaví.

Pomocí funkce DMADevSetMode se nastaví mód DMA (podle tabulky DMAModeTab). Resetuje se flip-flop příznak a nastaví se adresa dat k přenosu a velikost dat k přenosu. Nakonec se přenos dat odstartuje povolením DMA kanálu.


; -----------------------------------------------------------------------------
;                     Driver function: Stop DMA transfer
; -----------------------------------------------------------------------------
; INPUT:	EAX = channel number
;		EBX = device descriptor DEVDMA
; OUTPUT:	CY = invalid channel number or channel is not running
; -----------------------------------------------------------------------------

; ------------- Check channel number

DMADevStop:	cmp	eax,DMA_CHANNELS ; check channel number
		jae	short DMADevStart9 ; invalid channel number
		cmp	al,DMA_CASCADE	; cascade channel is reserved
		je	short DMADevStart9 ; channel is reserved

; ------------- Check if channel is used

		bt	dword [ebx+DEVDMA_Used],eax ; is channel used?
		jnc	short DMADevStart9 ; channel is not used

; ------------- Check if channel is running

		btr	dword [ebx+DEVDMA_Running],eax ; is channel running?
		jnc	short DMADevStart9 ; channel is not running

; ------------- Stop DMA transfer

		call	DMADevDisable	; stop DMA transfer
		clc			; clear error flag
		ret

Funkce DMADevStop zastaví DMA přenos dat. Na vstupu funkce obsahuje registr EAX číslo kanálu DMA, na kterém má být přenos zastaven. Registr EBX obsahuje popisovač zařízení. V případě neplatného čísla kanálu nebo pokud přenos nebrobíhá navrátí funkce příznak chyby CY. Funkce vyžaduje uzamknutí pomocí rychlého zámku.


; -----------------------------------------------------------------------------
;               Driver function: Get remaining transfer size
; -----------------------------------------------------------------------------
; INPUT:	EAX = channel number
;		EBX = device descriptor DEVDMA
; OUTPUT:	CY = invalid channel number or channel is not running
;		ECX = remaining bytes (0 on error)
;		If called before the channel has been used, it may return 1
;		(or 2 on DMA5..DMA7).
; -----------------------------------------------------------------------------

; ------------- Check channel number

DMADevRemain:	cmp	eax,DMA_CHANNELS ; check channel number
		jae	DMADevRemain8	; invalid channel number
		cmp	al,DMA_CASCADE	; cascade channel is reserved
		je	DMADevRemain8	; channel is reserved

; ------------- Check if channel is used

		bt	dword [ebx+DEVDMA_Used],eax ; is channel used?
		jnc	DMADevRemain8	; channel is not used

; ------------- Check if channel is running

		btr	dword [ebx+DEVDMA_Running],eax ; is channel running?
		jnc	DMADevRemain8	; channel is not running

; ------------- Clear DMA channel flip-flop

		call	DMADevClearFF	; clear DMA channel flip-flop

; ------------- Get remaining transfer size

		call	DMADevGetSize	; get remaining size
		clc			; clear error flag
		ret

; ------------- ERROR

DMADevRemain8:	xor	ecx,ecx		; ECX <- 0 no data left
		stc			; set error flag
		ret

Funkce DMADevRemain zjistí zbývající počet bajtů k přenosu. Na vstupu funkce obsahuje registr EAX číslo kanálu DMA, ze kterého je potřeba zjistit počet zbylých dat. Registr EBX obsahuje popisovač zařízení. Na výstupu funkce je v registru ECX navrácen počet zbývajících bajtů k přenosu. Hodnota 0 indikuje ukončení přenosu. Při prvním volání (pokud kanál nebyl dosud inicializován) může být navrácena hodnota 1 (nebo 2 pro DMA5..DMA7). V případě neplatného čísla kanálu nebo pokud přenos nebrobíhá navrátí funkce příznak chyby CY a registr ECX je vynulován. Funkce vyžaduje uzamknutí pomocí rychlého zámku.


; -----------------------------------------------------------------------------
;               Driver function: Check if transfer is still running
; -----------------------------------------------------------------------------
; INPUT:	EAX = channel number
;		EBX = device descriptor DEVDMA
; OUTPUT:	CY = invalid channel number or channel is not running
;		If called before the channel has been used, it may return NC.
;		It is faster than DMADevRemain.
; -----------------------------------------------------------------------------

; ------------- Check channel number

DMADevCheck:	cmp	eax,DMA_CHANNELS ; check channel number
		jae	DMADevRemain9	; invalid channel number
		cmp	al,DMA_CASCADE	; cascade channel is reserved
		je	DMADevRemain9	; channel is reserved

; ------------- Check if channel is used

		bt	dword [ebx+DEVDMA_Used],eax ; is channel used?
		jnc	DMADevRemain9	; channel is not used

; ------------- Check if channel is running

		bt	dword [ebx+DEVDMA_Running],eax ; is channel running?
		jnc	DMADevRemain9	; channel is not running

; ------------- Check if channel is still running

		jmp	DMADevRunning	; check if channel is still running

Funkce DMADevCheck zjistí, zda dosud probíhá přenos dat na DMA kanálu. Na vstupu funkce obsahuje registr EAX číslo kanálu DMA, u kterého má být probíhající přenos dat zjištěn. Registr EBX obsahuje popisovač zařízení. Na výstupu funkce je navrácen příznak CY v případě, že je zadán neplatný kanál nebo kanál není přidělen nebo pokud přenos dat neprobíhá. Při prvním volání (pokud kanál nebyl dosud inicializován) může být navrácen příznak probíhajícího přenosu (NC). Funkce se používá jako rychlejší varianta ke zjištění přenosu dat než DMADevRemain. Funkce vyžaduje uzamknutí pomocí rychlého zámku.


Obsah / Ovladače / DMA / Funkce interface ovladače řadiče DMA