[bits 16] org 100h dma_status equ 0d0h dma_command equ 0d0h dma_mask equ 0d4h ;was 0ah dma_mode equ 0d6h dma_clear equ 0d8h ;was 0ch dma_offset equ 0c8h ;was 04 dma_page equ 089h ;was 081h dma_length equ 0cah ;was 05h mov dx, dma_status;08h in al, dx ;dma status register: bits 7-4 tell if a dma channel mov cx, 0 waiting4dma: test al, 0f0h ;is in use jz dma_notbusy loop waiting4dma dma_notbusy: ;************ mask ch2 to set it up ************** mov al, 6 ;6 = 110 or set mask(1) for ch2 (10) out dma_mask, al;dma mask register: must mask dma channel before ;setting it up. ;************ stop any dma transfers ************** xor al, al ;The dma wait waited for any dma transfers, now stop out dma_clear, al ;dma transfers (shouldn't interfere now) ;************ setup mode register *************** mov al, 086h ;block mode(10),incmem(0),autoini(0),write(01),ch2(10) out dma_mode, al;=10000110xb=86h; 0bh=mode port; write operation b/c ;writing to mem (not writing to device) ;************ setup offset ************** mov bx, ds ;need to take low 12 bits of ds into account and bx, 0fffh shl bx, 4 mov ax, buffer ;ax = offset w/out low 12 bits segment, (doesn't use add ax, bx ;segments, uses pages (high 4 bits seg)) out dma_offset, al ;low byte of offset mov al, ah out dma_offset, al ;high byte of offset ;************ setup page ************** mov ax, ds ;get ready for page and ax, 0f000h ;only need high 4 bits shr ax, 12 ;mov to al out dma_page, al ;ch2 page port ;************ setup length of transfer ************** mov al, 1 out dma_length, al xor al, al out dma_length, al ;************ send dma command **************** ;mov al, ;************ unclear ch2 mask bit *********** mov al, 2 ;set al for ch2, bit2 = 0 to indicate to clear mask out dma_mask, al ;unmask ch2 on mask register ;mov al, 6 ;bit2=1=request, bits1,0=10=ch2 ;out 09h, al ;write request port: set to request a write transfer ;********* DMA COMPLETE ************ ;********* SETUP HD ********** call wait4ready jnc setCHS_drv_head jmp error setCHS_drv_head: mov dx, 01f6h mov al, 0a0h ;10100000xb = CHS, Drive 0, Head 0 out dx, al call wait4ready jnc maskirq jmp error maskirq: mov dx, 0a1h ;irq masking register in al, dx or al, 040h ;01000000xb = mask irq14 out dx, al mov ah, 8 mov dl, 80h int 13h ;Get drive parameters, return: dh=physical # heads cmp dh, 8 ;For some reason, if < 8 heads, say 0, if >= say 8 jae changeto8heads xor al, al jmp outputphysicalheads changeto8heads: mov al, 8 outputphysicalheads: mov dx, 0376h out dx, al ;If there was a precompensation cylinder, it would go to port 01f1h ;but for now keep it simple. (precomp cylinder would be divided by 4) mov dx, 01f2h ;Set #sectors = 1 mov al, 1 out dx, al inc dl out dx, al ;sector # = 1 inc dl dec al out dx, al ;cylinder low = 0 inc dl out dx, al ;cylinder high = 0 inc dl mov al, 0a0h ;=10100000xb=1,CHS,1,drive 0, head 0000 out dx, al ;******** issue the command ************ inc dl mov al, 0c8h ;read dma w/ retry out dx, al ;******** wait until transfer done ******** mov cx, 10 outside_waiting4read: push cx mov cx, 0 waiting4read: loop waiting4read pop cx loop outside_waiting4read ;still_reading: ; in al, dx ; test al, 128 ;see if bit7 set = busy ; jnz still_reading ;********* check for error *************** mov dx, 01f7h in al, dx test al, 1 jnz error mov dx, buffer mov ah, 9 int 21h jmp done ;*********************** Called procedures ************************ error: mov dx, 01f1h in al, dx inc al inc al mov dl, al mov ah, 2 int 21h mov dx, err_message mov ah, 9 int 21h done: mov dx, 0a1h ;irq masking register in al, dx and al, 0bfh ;10111111xb = unmask irq14 out dx, al mov ax, 4c00h int 21h err_message db "Error in waiting...$" ;****************** wait4ready: pusha mov dx, 01f7h mov cx, 0 waitloop: in al, dx and al, 040h ;01000000xb = drive ready cmp al, 040h jz ready push cx xor cx, cx pause: loop pause pop cx loop waitloop stc ;store carry flag as a return error ready: popa ret ;********************* DATA ********************** buffer TIMES 80h dd 0 ;reserve 512 bytes for sector endbuffer db "$"