[INTEL NAVIGATION HEADER]

Shows Code Necessary to Setup 2 DMA Channels

Shows Code Necessary to Setup 2 DMA Channels

$MOD186
NAME DMA_EXAMPLE_1

; This example shows code necessary
; to setup of two DMA channels. One
; channel performs an unsynchronized
; transfer from memory to memory.
; The second channel is used by a
; hard disk controller located in
; I/O space.

; It is assumed that the constants for PCB register
; addresses are defined elsewhere with EQUates.
; (Works for 80C186EA & EC family of microcontrollers)

CODE_SEG SEGMENT
ASSUME CS:CODE_SEG

START: MOV AX, DATA_SEG ; DATA SEGMENT POINTER

MOV DS, AX
ASSUME DS:DATA_SEG

; First we must initialize DMA channel 0. DMA0 will
; an unsynchronized transfer from SOURCE_DATA_1 to
; DEST_DATA_1. The first step is to calculate the
; proper values for the source and destination
; pointers.

MOV AX, SEG SOURCE_DATA_1

ROL AX, 4 ; GET HIGH 4 BITS
MOV BX, AX ; SAVE ROTATED VALUE
AND AX, 0FFF0H ; GET SHIFTED LOW 4

; NIBBLES

ADD AX, OFFSET SOURCE_DATA_1

; NOW LOW BYTES OF
; POINTER ARE IN AX

ADC BX, 0 ; ADD IN THE CARRY
; TO THE HIGH NIBBLE
AND BX, 000FH ; GET JUST THE HIGH
; NIBBLE
MOV DX, D0SRCL
OUT DX, AX ; AX=LOW 4 BYTES

MOV DX, D0SRCH
MOV AX, BX ; GET HIGH NIBBLE
OUT DX, AX

; SOURCE POINTER DONE. REPEAT FOR DEST.

MOV AX, SEG DEST_DATA_1

ROL AX, 4 ; GET HIGH 4 BITS
MOV BX, AX ; SAVE ROTATED VALUE
AND AX, 0FFF0H ; GET SHIFTED LOW 4
; NIBBLES

ADD AX, OFFSET DEST_DATA_1

; NOW LOW BYTES OF
; POINTER ARE IN AX

ADC BX, 0 ; ADD IN THE CARRY
; TO THE HIGH NIBBLE
AND BX, 000FH ; GET JUST THE HIGH
; NIBBLE
MOV DX, D0DSTL
OUT DX, AX ; AX=LOW 4 BYTES

MOV DX, D0DSTH
MOV AX, BX ; GET HIGH NIBBLE

OUT DX, AX

; THE POINTER ADDRESSES HAVE BEEN SET UP. NOW
; WE SET UP THE TRANSFER COUNT.

MOV AX, 29 ; THE MESSAGE IS
; 29 BYTES LONG.
MOV DX, D0TC ; XFER COUNT REG
OUT DX, AX

; NOW WE NEED TO SET THE PARAMETERS FOR
; THE CHANNEL AS FOLLOWS:
;
; DESTINATION SOURCE
; ----------- ------
; MEMORY SPACE MEMORY SPACE
; INCREMENT PTR INCREMENT PTR
;
; TERMINATE ON TC, NO INTERRUPT, UNSYNCHRONIZED,

; LOW PRIORITY RELATIVE TO CHANNEL 1, BYTE XFERS.
; WE START THE CHANNEL

MOV AX, 1011011000000110B
MOV DX, D0CON
OUT DX, AX

; THE UNSYNCHRONIZED BURST IS NOW RUNNING ON
; THE BUS...

; NOW SET UP CHANNEL 1 TO SERVICE THE DISK
; CONTROLLER. FOR THIS EXAMPLE WE WILL ONLY
; BE READING FROM THE DISK.

; THE SOURCE IS THE I/O PORT FOR THE
; DISK CONTROLLER.

MOV AX, DISK_IO_ADDR
MOV DX, D1SRCL
OUT DX, AL ; PROGRAM LOW ADDR

XOR AX, AX
MOV DX, D1SRCH ; HI ADDR FOR IO=0
OUT DX, AL

; THE DESTINATION IS THE DISK BUFFER IN MEMORY

MOV AX, SEG DISK_BUFF

ROL AX, 4 ; GET HIGH 4 BITS
MOV BX, AX ; SAVE ROTATED VALUE
AND AX, 0FFF0H ; GET SHIFTED LOW 4
; NIBBLES

ADD AX, OFFSET DISK_BUFF

; NOW LOW BYTES OF
; POINTER ARE IN AX

ADC BX, 0 ; ADD IN THE CARRY
; TO THE HIGH NIBBLE

AND BX, 000FH ; GET JUST THE HIGH
; NIBBLE
MOV DX, D1DSTL
OUT DX, AX ; AX=LOW 4 BYTES

MOV DX, D1DSTH
MOV AX, BX ; GET HIGH NIBBLE
OUT DX, AX

; THE POINTER ADDRESSES HAVE BEEN SET UP. NOW
; WE SET UP THE TRANSFER COUNT.

MOV AX, 512 ; THE DISK READS IN
; 512 BYTE SECTORS.
MOV DX, D1TC ; XFER COUNT REG
OUT DX, AX

; NOW WE NEED TO SET THE PARAMETERS FOR
; THE CHANNEL AS FOLLOWS:

;
; DESTINATION SOURCE
; ----------- ------
; MEMORY SPACE I/O SPACE
; INCREMENT PTR CONSTANT PTR
;
; TERMINATE ON TC, INTERRUPT, SOURCE SYNC,
; HIGH PRIORITY RELATIVE TO CHANNEL 0, BYTE XFERS,
; USE DRQ PIN FOR REQUEST SOURCE.

; THE CHANNEL IS ARMED.

MOV AX, 1010001101100110B
MOV DX, D0CON
OUT DX, AX

; REQUESTS ON DRQ1 WILL NOW RESULT IN TRANSFERS

CODE_SEG ENDS

DATA_SEG SEGMENT

SOURCE_DATA_1 DB '80C186EC INTEGRATED PROCESSOR'
DEST_DATA_1 DB 30 DUP('MITCH') ; JUNK DATA FOR TEST

DISK_BUFF DB 512 DUP(?)

DATA_SEG ENDS

END START

Free Web Hosting



Legal Stuff © 1997 Intel Corporation