;在图3-31的系统上进行DMA控制的存储器到存储器的数据块传送。
;
;调用参数:
; SI = 源存储器地址
; DI = 目的存储器地址
; CX = 计数值
; ES = 源和目的的段值
;
LATCH_B EQU 10H ;锁存器B
CLEAR_F EQU 7CH ;F/L触发器
CH0_A EQU 70H ;0通道地址寄存器
CH1_A EQU 72H ;1通道地址寄存器
CH1_C EQU 73H ;1通道字节计数寄存器
MODE EQU 7BH ;模式寄存器
CMMD EQU 78H ;命令寄存器
MASKS EQU 7FH ;屏蔽字寄存器
REQ EQU 79H ;请求寄存器
STATUS EQU 78H ;状态寄存器
TRANS PROC FAR USES AX
MOV AX,ES ;编程锁存器B
MOV AL,AH
SHR AL,4
OUT LATCHB,AL
OUT CLEAR_F,AL ;清零F/L触发器
MOV AX,ES ;编程源存储器地址
SHL AX,4
ADD AX,SI ;段内偏移地址SI是相对段起始地址的,而DMA传输过程中所用到的存储器地址应该是物理地址,因此需要通过段地址和段内偏移两部分计算得到。
OUT CH0_A, AL
MOV AL,AH
OUT CH0_A, AL ;分两步向通道0的基本地址寄存器写入源数据的起始地址。与此同时,起始地址也写入了当前地址寄存器。
MOV AX, ES ;编程目标存储器地址
SHL AX, 4
ADD AX, DI ;形成目标存储器地址偏移量
OUT CH1_A, AL
MOV AL, AH
OUT CH1_A, AL
MOV AX, CX ;编程字节计数寄存器
DEC AX
OUT CH1_C, AL
MOV AL, AH
OUT CH1_C, AL
MOV AL, 88H ;编程方式字
OUT MODE, AL ;88H即1000 1000,D7D6=10,传输模式为块传输模式;D5=0,当前地址寄存器内容为增量方式;D4=0,禁止自动预置功能;D3D2=10,读传输,D1D0=00,选择通道0,即通过通道0读源地址数据。
MOV AL, 85H
OUT MODE, AL ;85H即1000 0101,D7D6=10,传输模式为块传输模式;D5=0,当前地址寄存器内容为增量方式;D4=0,禁止自动预置功能;D3D2=01,写传输,D1D0=01,选择通道1。即通过通道1向目标地址写数据。
MOV AL, 1 ;编程命令字
OUT CMND, AL ;向命令寄存器写入0000 0001的意义为:D7=0,DACK低电平有效;D6=0,DREQ高电平有效;D5=0,不扩展写信号;D4=0,固定通道优先级;D3=0,正常传输时序;D2=0,使能8237A;D1D0=01,进行存储器到存储器的传输,并且是从存储器区域到存储器区域的传输。
MOV AL, 0EH ;解除通道0屏蔽
OUT MASKS, AL ;0EH的二进制为0000 1110,写入屏蔽字寄存器就表示解除通道0的屏蔽,同时设置通道1、通道2和通道3的屏蔽。
MOV AL, 4 ;启动DMA传送
OUT REQ, AL ;向请求寄存器写入二进制字0000 0100。D1D0=00,选择通道0;D2=1,有DMA请求。即通过软件向DMA控制器发送DMA传送请求,等待DMA控制器处理。
REPEAT ;等待,直至DMA完成传送
IN AL, STATUS
.UNTIL AL &1
RET
TRANS ENDP
|