home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
dma
/
dma.asm
Wrap
Assembly Source File
|
1994-02-11
|
8KB
|
143 lines
; DMA.ASM Copyright (C) 1994 by Chris Malcheski, Novatech Design
; FAX phone (303) 972-9107
; This file is a direct extraction from my upcoming diagnostics program, which
; I am stupidly making available to public domain for DMA programming education-
; al purposes. Note that even though the second DMA channel is provided for
; in this routine, it is set up for 8 bit operation and has never been tested
; above channel 3.
; ───── variable definitions ───────────────────────────────────────────────────
; dma_cbpt DMA clear byte pointer port location
; dma_chnl Requested DMA channel
; dma_mask DMA mask register port location
; dma_memr DMA memory register port location
; dma_mode DMA mode value holder (0 for read, 1 for write)
; dma_page DMA page register port location
; dma_rmod DMA mode register port location
; dma_work Adjusted DMA channel (0-3 down from 4-7)
; dma_xcnt DMA xfer count register port location
; hold_hi Utility work variable (word size)
; hold_lo Utility work variable (word size)
;╒═════════════════════════════════════════════════════════════════════════════╕
;│ DMA_SET: program DMA controller for diskette I/O. │
;├─────────────────────────────────────────────────────────────────────────────┤
;│ Call: AL = 0 to read; 1 to write │
;│ ES:DI = buffer address for read / write │
;│ BX = transfer count in bytes │
;├─────────────────────────────────────────────────────────────────────────────┤
;│ Uses: DMA_CBPT DMA_CHNL DMA_MASK DMA_MEMR DMA_MODE │
;│ DMA_PAGE DMA_RMOD DMA_WORK DMA_XCNT HOLD_HI │
;│ HOLD_LO │
;├─────────────────────────────────────────────────────────────────────────────┤
;│ Calls: Nothing. │
;├─────────────────────────────────────────────────────────────────────────────┤
;│ Returns: Nothing. │
;├─────────────────────────────────────────────────────────────────────────────┤
;│ Destroy: None. │
;╘═════════════════════════════════════════════════════════════════════════════╛
public dma_set ; Declare procedure public
even ; Set even alignment
dma_set proc near ; Declare procedure
;────── Save altered registers ─────────────────────────────────────────────────
push ax ; Save entry AX value
push cx ; Save entry CX value
push dx ; Save entry DX value
;────── Select the DMA channel ─────────────────────────────────────────────────
cli ; Disable interrupts
mov dma_mode,al ; Save incoming read/write
mov al,04h ; Set mask bit
or al,dma_work ; OR with DMA work channel
mov dx,dma_mask ; Mask register to DX
out dx,al ; Execute value output
jmp short $+2 ; Clear prefetch queue
;────── Set 20 bit address value ───────────────────────────────────────────────
mov ax,es ; Get segment value in AX
mov cx,16 ; Paragraph multiplier to CX
mul cx ; Execute multiply
add ax,di ; Add offset value to AX
jnc dmas_1 ; Skip carryover process
inc dx ; Process carryover
;────── Set page / address registers for DMA transfer ──────────────────────────
even ; Set even alignment
dmas_1: mov hold_hi,dx ; Save hold value high word
mov hold_lo,ax ; Save hold value low word
mov al,dl ; Get page value in AL
mov dx,dma_page ; Page register to DX
out dx,al ; Send out page value
jmp short $+2 ; Clear prefetch queue
;────── Activate DMA clear byte pointer ────────────────────────────────────────
xor al,al ; Out value to AL
mov dx,dma_cbpt ; Clear byte pointer to DX
out dx,al ; Send out clear byte value
jmp short $+2 ; Clear prefetch queue
;────── Send out value to DMAC first / last flip flop ──────────────────────────
mov al,44h ; Assume read operation
cmp dma_mode,0 ; Read operation?
jz dmas_2 ; Yes -- leave AL as is
xor al,0Ch ; Set AL for write
even ; Set even alignment
dmas_2: or al,dma_chnl ; Set bits 0-1 for channel
mov dx,dma_rmod ; DMA mode register to DX
out dx,al ; Send out DMA clear byte ptr
jmp short $+2 ; Clear prefetch queue
;────── Send out low word address to memory address registers ──────────────────
mov ax,hold_lo ; Get low word address in AX
mov dx,dma_memr ; DMA memory address to DX
out dx,al ; LSB out to DMA address reg
jmp short $+2 ; Clear prefetch queue
mov al,ah ; Get high byte in AH
out dx,al ; MSB out to DMA address reg
jmp short $+2 ; Clear prefetch queue
;────── Send out read count ────────────────────────────────────────────────────
mov ax,bx ; Get xfer count in AX
dec ax ; Adjust for DMA interpret
mov dx,dma_xcnt ; Transfer count register to DX
out dx,al ; LSB out to DMA word count
jmp short $ + 2 ; Clear prefetch queue
mov al,ah ; MSB to AL for out
out dx,al ; MSB out to DMA word count
jmp short $ + 2 ; Clear prefetch queue
;────── Activate current DMA channel ───────────────────────────────────────────
sti ; Enable interrupts
mov al,dma_chnl ; Enable DMA channel
mov dx,dma_mask ; Mask register to DX
out dx,al ; Activate DMA channel
jmp short $+2 ; Clear prefetch queue
clc ; Clear carry flag for no error
;────── Restore altered registers ──────────────────────────────────────────────
even ; Set even alignment
dmas_x: pop dx ; Restore entry DX value
pop cx ; Restore entry CX value
pop ax ; Restore entry AX value
;────── Return to caller ───────────────────────────────────────────────────────
ret ; Return to caller
dma_set endp ; End procedure