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