;----------------------------------------------------------;
; BOS kernel Christoffer Bubach, 2004-2005. ;
;----------------------------------------------------------;
; ;
; DMA transfer code. ;
; ;
;----------------------------------------------------------;
;------------------------------------------;
; Lookup table for DMA controller ports ;
;------------------------------------------;
dma_mask_reg dw 0x0A, 0x0A, 0x0A, 0x0A, 0xD4, 0xD4, 0xD4, 0xD4
dma_mode_reg dw 0x0B, 0x0B, 0x0B, 0x0B, 0xD6, 0xD6, 0xD6, 0xD6
dma_clear_reg dw 0x0C, 0x0C, 0x0C, 0x0C, 0xD8, 0xD8, 0xD8, 0xD8
dma_page_port dw 0x87, 0x83, 0x81, 0x82, 0x8F, 0x8B, 0x89, 0x8A
dma_addr_port dw 0x00, 0x02, 0x04, 0x06, 0xC0, 0xC4, 0xC8, 0xCC
dma_count_port dw 0x01, 0x03, 0x05, 0x07, 0xC2, 0xC6, 0xCA, 0xCE
;-----------------------------------;
; dma transfer ;
; ;
; in: ecx = page:offset ;
; bl = channel ;
; bh = 1=read, 0=write ;
; esi = count ;
; ;
; out: nothing. ;
;-----------------------------------;
dma_transfer:
push eax
push edx
push esi
cli
or bh, bh
jz .dont_read
mov bh, bl
add bh, 0x48
jmp .read
.dont_read:
mov bh, bl
add bh, 0x44
.read:
dec esi
movzx eax, bl
mov dx, word [(eax*2)+dma_mask_reg]
mov al, bl
or al, 0x04
out dx, al ; disable the channel
movzx eax, bl
mov dx, word [(eax*2)+dma_clear_reg]
mov al, 0
out dx, al ; initialize flip-flop
movzx eax, bl
mov dx, word [(eax*2)+dma_mode_reg]
mov al, bh
out dx, al ; set DMA mode
movzx eax, bl
mov dx, word [(eax*2)+dma_addr_port]
mov al, cl
out dx, al ; write low offset part
mov al, ch
out dx, al ; and high offset part
movzx eax, bl
mov dx, word [(eax*2)+dma_page_port]
mov eax, ecx
shr eax, 16
out dx, al ; write page.
movzx eax, bl
mov dx, word [(eax*2)+dma_count_port]
mov eax, esi
out dx, al ; low count
mov al, ah
out dx, al ; high count
movzx eax, bl
mov dx, word [(eax*2)+dma_mask_reg]
mov al, bl
out dx, al ; enable channel
sti
pop esi
pop edx
pop eax
ret