����������������������������������������������������������������������������� 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