VDMAD_Lock_DMA_Region

include vdmad.inc

mov esi, OFFSET32 DMA_Region
mov ecx, RegionSize
mov dl, Alignment
VxDcall VDMAD_Lock_DMA_Region
jc ErrorHandler
 

Attempts to lock a region of memory for a DMA transfer. Uses EAX, ECX, EDX, and flags

1 DMA_Not_Contiguous: Region not contiguous.
2 DMA_Not_Aligned: Region crossed physical alignment boundary.
3 DMA_Lock_Failed: Unable to lock pages.

DMA_Region
Address of the DMA region.
RegionSize
Number of bytes in the DMA region.
Alignment
Region alignment. This parameter can be one of the following values:
1 Region must be aligned on 64K page boundary.
2 Region must be aligned on 128K page boundary.

The service first verifies that the region is mapped to contiguous pages of physical memory, then it determines whether the region results in a DMA bank (page) wrap.

Typically, each channel has a base address register and a page address register. The base address register is incremented after each byte or word is transferred. If the increment of this 16-bit register results in the roll over from 0FFFFh to 0, then the transfer wraps to the start of the DMA bank because the page register is not updated. Normally MS-DOS watches for this condition and adjusts Interrupt 13h parameters to split transfers to avoid this wrap, but MS-DOS does not account for the difference between linear and physical addresses with Windows, so VDMAD checks again to prevent wrap from occurring.

If these checks pass, the service calls the memory manager to lock the physical pages.

This service does not check to see if the region is within some physical maximum constraint. If the region can be locked, then it locks the memory, and it is up to the caller to check to see if the physical region is acceptable. If the region is not acceptable, then the caller should unlock the region and perform a buffered DMA transfer.

This service must be called before a DMA transfer is started, that is, before the physical state is set for a channel and before it is unmasked.