ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ INTRO TO DMA by Draeden of VLA ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ DMA means Direct Memory Access. You probably already know where and why you use it, so I'll skip right down to the dirty stuff. This all should speak for it's self, so... Enjoy. Draeden /VLA ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ To do a DMA transfer, you need to know a few things: 1) Address of the memory to access 2) Length of data to read/write This can all be put into a structure: STRUC DMAInfo Page db ? Offset dw ? Length dw ? ENDS Page is the highest 4 bits of the absolute 20 bit address of the memory location. Note that DMA transfers CANNOT cross 64k page boundries. The Length is actually LENGTH-1; sending in a 0 will move 1 byte, sending a 0FFFFh will move 64k. ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; IN: DX:AX = segment/offset address of memory area ; ;OUT: DH = Page (0-F) (DL is destroyed) ; AX = Offset ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PROC MakePage push bx mov bl,dh shr bl,4 ;isolate upper 4 bits of segment shl dx,4 ;make segment into ABS address add ax,dx ;add the offset and put it in AX adc bl,0 ;complete the addition mov dh,bl ;put the PAGE where it goes pop bx ; DH:AX is now the PAGE:OFFSET address ret ENDP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Programming DMA channels 0 thru 3 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ There are 3 ports that are DMA channel specific: 1) The Page register 2) The DMA count (length) register 3) The memory address (offset register) They are as follows: DMACH PAGE ADDRESS LENGTH 0 87h 0 1 1 83h 2 3 2 81h 4 5 3 82h 6 7 And now some general registers: DMA Mask Register: 0Ah ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ bit 7 - 3 = 0 Reserved bit 2 = 0 clear mask = 1 set mask bits 1 - 0 = 00 Select channel 0 = 01 select channel 1 = 10 select channel 2 = 11 select channel 3 USE: You must set the mask of the channel before you can reprogram it. DMA Mode Register: 0Bh ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ bit 7 - 6 = 00 Demand mode = 01 Signal mode = 10 Block mode = 11 Cascade mode bit 5 - 4 = 0 Reserved bit 3 - 2 = 00 Verify operation = 01 Write operation = 10 Read operation = 11 Reserved bits 1 - 0 = 00 Select channel 0 = 01 select channel 1 = 10 select channel 2 = 11 select channel 3 USE: Tell the DMAC what to do. Common modes are: 48h (Read operation, Signal mode) Used to read data from host memory and send to whomever polls it. 44h (Write operation, Signal mode) Used to write data taken from a device to memory. DMA clear byte ptr: 0Ch ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ USE: Send a zero to reset the internal ptrs WHAT TO DO: ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 1) Set the Mask bit for the channel mov al,4 add al,[DMA_Channel] out 0ah,al 2) Clear Byte Ptr sub al,al out 0Ch,al 3) Set the DMA transfer mode mov al,48h ;MODE output (read) add al,[DMA_Channel] out 0Bh,al 4) Set the memory ADDRESS and LENGTH ; AX = offset ; CX = Length ;[DMA_Base] = port # of memory address mov dx,[DMA_Base] out dx,al ;send lower byte address mov al,ah out dx,al ;send high byte address inc dl ;point to Count port mov al,cl out dx,al ;send low byte length mov al,ch out dx,al ;send high byte length 5) Set the DMA page ; AL = Page mov dx,[Dma_Page] out dx,al ; write the Page 6) Clear DMA mask bit mov al,[byte DMA_Channel] out 0Ah,al ; port 0Ah, DMA-1 mask reg bit 7) Program the other device that is going to use the DMA output/input ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; This routine programs the DMAC for channels 0-3 ; ; IN: [DMA_Channel], [DMAbaseAdd], [DMApageReg] must be setup ; [DAMBaseAdd] = Memory Address port ; ; dh = mode ; ax = address ; cx = length ; dl = page ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PROC Prog_DMA03 NEAR push bx mov bx,ax mov al,4 add al,[DMA_Channel] out 0Ah,al ; mask reg bit sub al,al out 0Ch,al ; clr byte ptr mov al,dh add al,[DMA_Channel] out 0Bh,al ; set mode reg push dx mov dx,[DMAbaseAdd] mov al,bl out dx,al ; set base address low mov al,bh out dx,al ; set base address high inc dx ;point to length mov al,cl out dx,al ; set length low mov al,ch out dx,al ; set length high pop dx mov al,dl mov dx,[DmaPageReg] out dx,al ; set DMA page reg mov al,[DMA_Channel] out 0Ah,al ; unmask (activate) dma channel pop bx ret ENDP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Programming DMA channels 4 thru 7 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Again, there are 3 ports that are DMA channel specific: 1) The Page register 2) The DMA count (length) register 3) The memory address (offset register They are as follows: DMACH PAGE ADDRESS LENGTH 4 8Fh C0h C2h 5 8Bh C4h C6h 6 89h C8h CAh 7 8Ah CCh CEh And now some general registers: DMA Mask Register: 0D4h ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ bit 7 - 3 = 0 Reserved bit 2 = 0 clear mask = 1 set mask bits 1 - 0 = 00 Select channel 4 = 01 select channel 5 = 10 select channel 6 = 11 select channel 7 USE: You must set the mask of the channel before you can reprogram it. DMA Mode Register: 0D6h ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ bit 7 - 6 = 00 Demand mode = 01 Signal mode = 10 Block mode = 11 Cascade mode bit 5 - 4 = 0 Reserved bit 3 - 2 = 00 Verify operation = 01 Write operation = 10 Read operation = 11 Reserved bits 1 - 0 = 00 Select channel 4 = 01 select channel 5 = 10 select channel 6 = 11 select channel 7 USE: Tell the DMAC what to do. Common modes are: 48h (Read operation, Signal mode) Used to read data from host memory and send to whomever polls it. 44h (Write operation, Signal mode) Used to write data taken from a device to memory. DMA clear byte ptr: 0D8h ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ USE: Send a zero to reset the internal ptrs WHAT TO DO: (exactly the same thing, just different io PORTs) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 1) Set the Mask bit for the channel mov al,[DMA_Channel] ;because the DMA's are 4-7, bit #3 out 0D4h,al ; is already set 2) Clear Byte Ptr sub al,al out 0D8h,al 3) Set the DMA transfer mode mov al,[DMA_Channel] sub al,4 or al,48h ;MODE output (read) out 0D6h,al 4) Set the memory ADDRESS and LENGTH ; AX = offset ; CX = Length ;[DMA_Base] = port # of memory address mov dx,[DMA_Base] out dx,al ;send lower byte address mov al,ah out dx,al ;send high byte address add dl,2 ;point to Count port (seperated by 2) mov al,cl out dx,al ;send low byte length mov al,ch out dx,al ;send high byte length 5) Set the DMA page ; AL = Page mov dx,[Dma_Page] out dx,al ; write the Page 6) Clear DMA mask bit mov al,[byte DMA_Channel] and al,00000011b out 0d4h,al ; port 0Ah, DMA-1 mask reg bit 7) Program the other device that is going to use the DMA output/input ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; This routine programs the DMAC for channels 4-7 ; ; IN: [DMA_Channel], [DMAbaseAdd], [DMApageReg] must be setup ; [DAMBaseAdd] = Memory Address port ; ; dh = mode ; ax = address ; cx = length ; dl = page ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PROC Prog_DMA47 NEAR push bx mov bx,ax mov al,[DMA_Channel] out 0D4h,al ; mask reg bit sub al,al out 0D8h,al ; clr byte ptr mov al,[DMA_Channel] sub al,4 add al,dh out 0D6h,al ; set mode reg push dx mov dx,[DMAbaseAdd] mov al,bl out dx,al ; set base address low mov al,bh out dx,al ; set base address high add dl,2 ;point to length mov al,cl out dx,al ; set length low mov al,ch out dx,al ; set length high pop dx mov al,dl mov dx,[DmaPageReg] out dx,al ; set DMA page reg mov al,[DMA_Channel] and al,00000011b out 0D4h,al ; unmask (activate) dma channel pop bx ret ENDP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ; This routine programs the DMAC for channels 0-7 ; ; IN: [DMA_Channel], [DMAbaseAdd], [DMApageReg] must be setup ; [DAMBaseAdd] = Memory Address port ; ; dh = mode ; ax = address ; cx = length ; dl = page ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PROC Prog_DMA NEAR push bx mov bx,ax cmp [DMA_Channel],4 jb @@DoDMA03 mov al,[DMA_Channel] out 0D4h,al ; mask reg bit sub al,al out 0D8h,al ; clr byte ptr mov al,[DMA_Channel] sub al,4 add al,dh out 0D6h,al ; set mode reg push dx mov dx,[DMAbaseAdd] mov al,bl out dx,al ; set base address low mov al,bh out dx,al ; set base address high add dl,2 ;point to length mov al,cl out dx,al ; set length low mov al,ch out dx,al ; set length high pop dx mov al,dl mov dx,[DmaPageReg] out dx,al ; set DMA page reg mov al,[DMA_Channel] and al,00000011b out 0D4h,al ; unmask (activate) dma channel pop bx ret @@DoDMA03: mov al,4 add al,[DMA_Channel] out 0Ah,al ; mask reg bit sub al,al out 0Ch,al ; clr byte ptr mov al,dh add al,[DMA_Channel] out 0Bh,al ; set mode reg push dx mov dx,[DMAbaseAdd] mov al,bl out dx,al ; set base address low mov al,bh out dx,al ; set base address high inc dx ;point to length mov al,cl out dx,al ; set length low mov al,ch out dx,al ; set length high pop dx mov al,dl mov dx,[DmaPageReg] out dx,al ; set DMA page reg mov al,[DMA_Channel] out 0Ah,al ; unmask (activate) dma channel pop bx ret ENDP