Subversion Repositories Kolibri OS

Rev

Rev 256 | Rev 346 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ; Low-level driver for HDD access
  2. ; DMA support by Mario79
  3.  
  4. ;**************************************************************************
  5. ;
  6. ;   0x600008  - first entry in cache list
  7. ;
  8. ;            +0   - lba sector
  9. ;            +4   - state of cache sector
  10. ;                   0 = empty
  11. ;                   1 = used for read  ( same as in hd )
  12. ;                   2 = used for write ( differs from hd )
  13. ;
  14. ;      +65536 - cache entries
  15. ;
  16. ;**************************************************************************
  17.  
  18. align 4
  19. hd_read:
  20. ;-----------------------------------------------------------
  21. ; input  : eax = block to read
  22. ;          ebx = destination
  23. ;-----------------------------------------------------------
  24.         and     [hd_error], 0
  25.     push  ecx esi edi           ; scan cache
  26.  
  27.     mov   ecx,cache_max         ; entries in cache
  28.     mov   esi,0x600000+8
  29.     mov   edi,1
  30.  
  31.   hdreadcache:
  32.  
  33.     cmp   dword [esi+4],0       ; empty
  34.     je    nohdcache
  35.  
  36.     cmp   [esi],eax             ; correct sector
  37.     je    yeshdcache
  38.  
  39.   nohdcache:
  40.  
  41.     add   esi,8
  42.     inc   edi
  43.     dec   ecx
  44.     jnz   hdreadcache
  45.  
  46.     call  find_empty_slot       ; ret in edi
  47.     cmp   [hd_error],0
  48.     jne   return_01
  49.         cmp     [dma_hdd], 1
  50.         jnz     .nodma
  51.         call    hd_read_dma
  52.         jmp     @f
  53. .nodma:
  54.         call    hd_read_pio
  55. @@:
  56.  
  57.     lea   esi,[edi*8+0x600000]
  58.     mov   [esi],eax             ; sector number
  59.     mov   dword [esi+4],1       ; hd read - mark as same as in hd
  60.  
  61.   yeshdcache:
  62.  
  63.     mov   esi,edi
  64.     shl   esi,9
  65.     add   esi,0x600000+65536
  66.     mov   edi,ebx
  67.     mov   ecx,512/4
  68.     cld
  69.     rep   movsd                 ; move data
  70.  return_01:
  71.     pop   edi esi ecx
  72.     ret
  73.  
  74. align 4
  75. hd_read_pio:
  76.     push  eax edx
  77.  
  78.     call  wait_for_hd_idle
  79.     cmp   [hd_error],0
  80.     jne   hd_read_error    
  81.  
  82.     cli
  83.     xor   eax,eax
  84.     mov   edx,[hdbase]
  85.     inc   edx
  86.     out   dx,al   ; ATAFeatures ॣ¨áâà "®á®¡¥­­®á⥩"
  87.     inc   edx
  88.     inc   eax
  89.     out   dx,al   ; ATASectorCount áçñâ稪 ᥪâ®à®¢
  90.     inc   edx
  91.     mov   eax,[esp+4]
  92.     out   dx,al   ; ATASectorNumber ॣ¨áâà ­®¬¥à  ᥪâ®à 
  93.     shr   eax,8
  94.     inc   edx
  95.     out   dx,al   ; ATACylinder ­®¬¥à 樫¨­¤à  (¬« ¤è¨© ¡ ©â)
  96.     shr   eax,8
  97.     inc   edx
  98.     out   dx,al   ; ­®¬¥à 樫¨­¤à  (áâ à訩 ¡ ©â)
  99.     shr   eax,8
  100.     inc   edx
  101.     and   al,1+2+4+8
  102.     add   al,byte [hdid]
  103.     add   al,128+64+32
  104.     out   dx,al   ; ­®¬¥à £®«®¢ª¨/­®¬¥à ¤¨áª 
  105.     inc   edx
  106.     mov   al,20h
  107.     out   dx,al   ; ATACommand ॣ¨áâà ª®¬ ­¤
  108.     sti
  109.  
  110.     call  wait_for_sector_buffer
  111.  
  112.     cmp   [hd_error],0
  113.     jne   hd_read_error
  114.  
  115.     cli
  116.     push  edi
  117.     shl   edi,9
  118.     add   edi,0x600000+65536
  119.     mov   ecx,256
  120.     mov   edx,[hdbase]
  121.     cld
  122.     rep   insw
  123.     pop   edi
  124.     sti
  125.  
  126.     pop   edx eax
  127.     ret
  128.  
  129. disable_ide_int:    
  130. ;        mov edx,[hdbase]
  131. ;        add edx,0x206
  132. ;        mov al,2
  133. ;        out dx,al
  134.         cli
  135.         ret
  136.  
  137. enable_ide_int:
  138. ;        mov edx,[hdbase]
  139. ;        add edx,0x206
  140. ;        mov al,0
  141. ;        out dx,al
  142.         sti
  143.         ret
  144.  
  145. align 4
  146. hd_write:
  147. ;-----------------------------------------------------------
  148. ; input  : eax = block
  149. ;          ebx = pointer to memory
  150. ;-----------------------------------------------------------
  151.     push  ecx esi edi
  152.  
  153.     ; check if the cache already has the sector and overwrite it
  154.  
  155.     mov   ecx,cache_max
  156.     mov   esi,0x600000+8
  157.     mov   edi,1
  158.  
  159.   hdwritecache:
  160.  
  161.     cmp   dword [esi+4],0       ; if cache slot is empty
  162.     je    not_in_cache_write
  163.  
  164.     cmp   [esi],eax             ; if the slot has the sector
  165.     je    yes_in_cache_write
  166.  
  167.   not_in_cache_write:
  168.  
  169.     add   esi,8
  170.     inc   edi
  171.     dec   ecx
  172.     jnz   hdwritecache
  173.  
  174.     ; sector not found in cache
  175.     ; write the block to a new location
  176.  
  177.     call  find_empty_slot       ; ret in edi
  178.     cmp   [hd_error],0
  179.     jne   hd_write_access_denied
  180.  
  181.     lea   esi,[edi*8+0x600000]
  182.     mov   [esi],eax             ; sector number
  183.  
  184.   yes_in_cache_write:
  185.  
  186.     mov   dword [esi+4],2       ; write - differs from hd
  187.  
  188.     shl   edi,9
  189.     add   edi,0x600000+65536
  190.     mov   esi,ebx
  191.     mov   ecx,512/4
  192.     cld
  193.     rep   movsd                 ; move data
  194.  hd_write_access_denied:
  195.     pop   edi esi ecx
  196.     ret
  197.  
  198.  
  199. write_cache:
  200. ;-----------------------------------------------------------
  201. ; write all changed sectors to disk
  202. ;-----------------------------------------------------------
  203.     push  eax ecx edx esi edi
  204.  
  205.     ; write difference ( 2 ) from cache to hd
  206.  
  207.     mov   ecx,cache_max
  208.     mov   esi,0x600000+8
  209.     mov   edi,1
  210.  
  211.   write_cache_more:
  212.  
  213.     cmp   dword [esi+4],2       ; if cache slot is not different
  214.     jne   .write_chain
  215.  
  216.     mov   dword [esi+4],1       ; same as in hd
  217.     mov   eax,[esi]             ; eax = sector to write
  218.  
  219.     cmp   eax,[PARTITION_START]
  220.     jb    danger
  221.     cmp   eax,[PARTITION_END]
  222.     ja    danger
  223.    
  224.         cmp     [dma_hdd], 1
  225.         jmp     .nodma
  226. ; Ž¡ê¥¤¨­ï¥¬ § ¯¨áì 楯®çª¨ ¯®á«¥¤®¢ â¥«ì­ëå ᥪâ®à®¢ ¢ ®¤­® ®¡à é¥­¨¥ ª ¤¨áªã
  227.         cmp     ecx, 1
  228.         jz      .nonext
  229.         cmp     dword [esi+8+4], 2
  230.         jnz     .nonext
  231.         push    eax
  232.         inc     eax
  233.         cmp     eax, [esi+8]
  234.         pop     eax
  235.         jnz     .nonext
  236.         cmp     [cache_chain_started], 1
  237.         jz      @f
  238.         mov     [cache_chain_started], 1
  239.         mov     [cache_chain_size], 0
  240.         mov     [cache_chain_pos], edi
  241.         mov     [cache_chain_ptr], esi
  242. @@:
  243.         inc     [cache_chain_size]
  244.         cmp     [cache_chain_size], 64
  245.         jnz     .continue
  246.         jmp     .write_chain
  247. .nonext:
  248.         call    flush_cache_chain
  249.         mov     [cache_chain_size], 1
  250.         mov     [cache_chain_ptr], esi
  251.         call    write_cache_sector
  252.         jmp     .continue
  253. .nodma:
  254.         call    cache_write_pio
  255. .write_chain:
  256.         call    flush_cache_chain
  257.  
  258. .continue:
  259.   danger:
  260.  
  261.     add   esi,8
  262.     inc   edi
  263.     dec   ecx
  264.     jnz   write_cache_more
  265.         call    flush_cache_chain
  266.  return_02:
  267.     pop   edi esi edx ecx eax
  268.     ret
  269.  
  270. flush_cache_chain:
  271.         cmp     [cache_chain_started], 0
  272.         jz      @f
  273.         call    write_cache_chain
  274.         mov     [cache_chain_started], 0
  275. @@:
  276.         ret
  277.  
  278. align 4
  279. cache_write_pio:
  280.     call  disable_ide_int
  281.  
  282.     call  wait_for_hd_idle
  283.     cmp   [hd_error],0
  284.     jne   hd_write_error
  285.  
  286. ;    cli
  287.     xor   eax,eax
  288.     mov   edx,[hdbase]
  289.     inc   edx
  290.     out   dx,al
  291.     inc   edx
  292.     inc   eax
  293.     out   dx,al
  294.     inc   edx
  295.     mov   eax,[esi]             ; eax = sector to write
  296.     out   dx,al
  297.     shr   eax,8
  298.     inc   edx
  299.     out   dx,al
  300.     shr   eax,8
  301.     inc   edx
  302.     out   dx,al
  303.     shr   eax,8
  304.     inc   edx
  305.     and   al,1+2+4+8
  306.     add   al,byte [hdid]
  307.     add   al,128+64+32
  308.     out   dx,al
  309.     inc   edx
  310.     mov   al,30h
  311.     out   dx,al
  312. ;    sti
  313.  
  314.     call  wait_for_sector_buffer
  315.  
  316.     cmp   [hd_error],0
  317.     jne   hd_write_error
  318.  
  319.     push  ecx esi
  320.  
  321. ;    cli
  322.     mov   esi,edi
  323.     shl   esi,9
  324.     add   esi,0x600000+65536    ; esi = from memory position
  325.     mov   ecx,256
  326.     mov   edx,[hdbase]
  327.     cld
  328.     rep   outsw
  329. ;    sti
  330.  
  331.     call  enable_ide_int
  332.     pop   esi ecx
  333.  
  334.     ret
  335.  
  336. align 4
  337. find_empty_slot:
  338. ;-----------------------------------------------------------
  339. ; find empty or read slot, flush cache if next 10% is used by write
  340. ; output : edi = cache slot
  341. ;-----------------------------------------------------------
  342. ;    push  ecx esi
  343.  
  344.   search_again:
  345.  
  346.     mov   ecx,cache_max*10/100
  347.     mov   edi,[cache_search_start]
  348.  
  349.   search_for_empty:
  350.  
  351.     inc   edi
  352.     cmp   edi,cache_max
  353.     jbe   inside_cache
  354.     mov   edi,1
  355.  
  356.   inside_cache:
  357.  
  358.     cmp   dword [edi*8+0x600000+4],2    ; get cache slot info
  359.     jb    found_slot                    ; it's empty or read
  360.     dec   ecx
  361.     jnz   search_for_empty
  362.  
  363.     call  write_cache                   ; no empty slots found, write all
  364.     cmp   [hd_error],0
  365.     jne   found_slot_access_denied
  366.  
  367.     jmp   search_again                  ; and start again
  368.  
  369.   found_slot:
  370.  
  371.     mov   [cache_search_start],edi
  372.   found_slot_access_denied:
  373.     ret
  374.  
  375. align 4
  376. clear_hd_cache:
  377.  
  378.     push  eax ecx edi
  379.     mov   edi,0x600000
  380.     mov   ecx,16384
  381.     xor   eax,eax
  382.     cld
  383.     rep   stosd                 ; clear hd cache with 0
  384.     mov   [cache_search_start],eax
  385.     mov   [fat_in_cache],-1
  386.     mov   [fat_change],0
  387.     pop   edi ecx eax
  388.     ret
  389.  
  390. save_hd_wait_timeout:
  391.  
  392.     push  eax
  393.     mov   eax,[timer_ticks];[0xfdf0]
  394.     add   eax,300               ; 3 sec timeout
  395.     mov   [hd_wait_timeout],eax
  396.     pop   eax
  397.     ret
  398.  
  399. align 4
  400. check_hd_wait_timeout:
  401.  
  402.     push  eax
  403.     mov   eax,[hd_wait_timeout]
  404.     cmp   [timer_ticks], eax ;[0xfdf0],eax
  405.     jg    hd_timeout_error
  406.     pop   eax
  407.     mov   [hd_error],0
  408.     ret
  409.  
  410. iglobal
  411.   hd_timeout_str   db 'K : FS - HD timeout',13,10,0
  412.   hd_read_str      db 'K : FS - HD read error',13,10,0
  413.   hd_write_str     db 'K : FS - HD write error',13,10,0
  414.   hd_lba_str       db 'K : FS - HD LBA error',13,10,0
  415. endg
  416.  
  417. hd_timeout_error:
  418.  
  419. ;    call  clear_hd_cache
  420. ;    call  clear_application_table_status
  421.     mov   esi,hd_timeout_str
  422.     call  sys_msg_board_str
  423. ;    jmp   $
  424.     mov   [hd_error],1
  425.     pop   eax
  426.     ret
  427.  
  428. hd_read_error:
  429.  
  430. ;    call  clear_hd_cache
  431. ;    call  clear_application_table_status
  432.     mov   esi,hd_read_str
  433.     call  sys_msg_board_str
  434.     pop   edx eax
  435.     ret
  436.  
  437. hd_write_error:
  438.  
  439. ;    call  clear_hd_cache
  440. ;    call  clear_application_table_status
  441.     mov   esi,hd_write_str
  442.     call  sys_msg_board_str
  443.     ret
  444.  
  445. hd_write_error_dma:
  446. ;        call    clear_hd_cache
  447. ;        call    clear_application_table_status
  448.         mov     esi, hd_write_str
  449.         call    sys_msg_board_str
  450.         pop     esi
  451.         ret
  452.  
  453. hd_lba_error:
  454. ;    call  clear_hd_cache
  455. ;    call  clear_application_table_status
  456.     mov   esi,hd_lba_str
  457.     call  sys_msg_board_str
  458.     jmp   LBA_read_ret
  459.  
  460.  
  461. align 4
  462. wait_for_hd_idle:
  463.  
  464.     push  eax edx
  465.  
  466.     call  save_hd_wait_timeout
  467.  
  468.     mov   edx,[hdbase]
  469.     add   edx,0x7
  470.  
  471.   wfhil1:
  472.  
  473.     call  check_hd_wait_timeout
  474.     cmp   [hd_error],0
  475.     jne   @f
  476.  
  477.     in    al,dx
  478.     test  al,128
  479.     jnz   wfhil1
  480.  
  481.  @@:
  482.  
  483.     pop   edx eax
  484.     ret
  485.  
  486.  
  487. align 4
  488. wait_for_sector_buffer:
  489.  
  490.     push  eax edx
  491.  
  492.     mov   edx,[hdbase]
  493.     add   edx,0x7
  494.  
  495.     call  save_hd_wait_timeout
  496.  
  497.   hdwait_sbuf:                  ; wait for sector buffer to be ready
  498.  
  499.     call  check_hd_wait_timeout
  500.     cmp   [hd_error],0
  501.     jne   @f
  502.  
  503.     in    al,dx
  504.     test  al,8
  505.     jz    hdwait_sbuf
  506.  
  507.     mov   [hd_error],0
  508.  
  509.     cmp   [hd_setup],1          ; do not mark error for setup request
  510.     je    buf_wait_ok
  511.  
  512.     test  al,1                  ; previous command ended up with an error
  513.     jz    buf_wait_ok
  514.  @@:
  515.     mov   [hd_error],1
  516.  
  517.   buf_wait_ok:
  518.  
  519.     pop   edx eax
  520.     ret
  521.  
  522. ; \begin{Mario79}
  523. align 4
  524. wait_for_sector_dma_ide0:
  525.         push    eax
  526.         push    edx
  527.         call    save_hd_wait_timeout
  528. .wait:
  529.         call    change_task
  530.         cmp     [irq14_func], hdd_irq14
  531.         jnz     .done
  532.         call    check_hd_wait_timeout
  533.         cmp     [hd_error], 0
  534.         jz      .wait
  535.         mov     [irq14_func], hdd_irq_null
  536.         mov     dx, [IDEContrRegsBaseAddr]
  537.         mov     al, 0
  538.         out     dx, al
  539. .done:
  540.         pop     edx
  541.         pop     eax
  542.         ret
  543.  
  544. align 4
  545. wait_for_sector_dma_ide1:
  546.         push    eax
  547.         push    edx
  548.         call    save_hd_wait_timeout
  549. .wait:
  550.         call    change_task
  551.         cmp     [irq15_func], hdd_irq15
  552.         jnz     .done
  553.         call    check_hd_wait_timeout
  554.         cmp     [hd_error], 0
  555.         jz      .wait
  556.         mov     [irq15_func], hdd_irq_null
  557.         mov     dx, [IDEContrRegsBaseAddr]
  558.         add     dx, 8
  559.         mov     al, 0
  560.         out     dx, al
  561. .done:
  562.         pop     edx
  563.         pop     eax
  564.         ret
  565.  
  566. iglobal
  567. align 4
  568. ; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary
  569. IDE_descriptor_table:
  570.         dd      284000h
  571.         dw      2000h
  572.         dw      8000h
  573.  
  574. dma_cur_sector  dd      not 40h
  575. irq14_func      dd      hdd_irq_null
  576. irq15_func      dd      hdd_irq_null
  577. endg
  578.  
  579. uglobal
  580. ; all uglobals are zeroed at boot
  581. dma_process     dd      0
  582. dma_slot_ptr    dd      0
  583. cache_chain_pos dd      0
  584. cache_chain_ptr dd      0
  585. cache_chain_size        db      0
  586. cache_chain_started     db      0
  587. dma_task_switched       db      0
  588. dma_hdd         db      0
  589. endg
  590.  
  591. align 4
  592. hdd_irq14:
  593.         pushfd
  594.         cli
  595.         pushad
  596.         mov     [irq14_func], hdd_irq_null
  597.         mov     dx, [IDEContrRegsBaseAddr]
  598.         mov     al, 0
  599.         out     dx, al
  600.         call    update_counters
  601.         mov     ebx, [dma_process]
  602.         cmp     [0x3000], ebx
  603.         jz      .noswitch
  604.         mov     [dma_task_switched], 1
  605.         mov     edi, [dma_slot_ptr]
  606.         mov     eax, [0x3000]
  607.         mov     [dma_process], eax
  608.         mov     eax, [0x3010]
  609.         mov     [dma_slot_ptr], eax
  610.         mov     [0x3000], ebx
  611.         mov     [0x3010], edi
  612.         mov     byte [0xFFFF], 1
  613.         call    do_change_task
  614. .noswitch:
  615.         popad
  616.         popfd
  617. align 4
  618. hdd_irq_null:
  619.         ret
  620.  
  621. align 4
  622. hdd_irq15:
  623.         pushfd
  624.         cli
  625.         pushad
  626.         mov     [irq15_func], hdd_irq_null
  627.         mov     dx, [IDEContrRegsBaseAddr]
  628.         add     dx, 8
  629.         mov     al, 0
  630.         out     dx, al
  631.         call    update_counters
  632.         mov     ebx, [dma_process]
  633.         cmp     [0x3000], ebx
  634.         jz      .noswitch
  635.         mov     [dma_task_switched], 1
  636.         mov     edi, [dma_slot_ptr]
  637.         mov     eax, [0x3000]
  638.         mov     [dma_process], eax
  639.         mov     eax, [0x3010]
  640.         mov     [dma_slot_ptr], eax
  641.         mov     [0x3000], ebx
  642.         mov     [0x3010], edi
  643.         mov     byte [0xFFFF], 1
  644.         call    do_change_task
  645. .noswitch:
  646.         popad
  647.         popfd
  648.         ret
  649.  
  650. align 4
  651. hd_read_dma:
  652.         push    eax
  653.         push    edx
  654.         mov     edx, [dma_cur_sector]
  655.         cmp     eax, edx
  656.         jb      .notread
  657.         add     edx, 15
  658.         cmp     [esp+4], edx
  659.         ja      .notread
  660.         mov     eax, [esp+4]
  661.         sub     eax, [dma_cur_sector]
  662.         shl     eax, 9
  663.         add     eax, 0x284000
  664.         push    ecx esi edi
  665.         mov     esi, eax
  666.         shl     edi, 9
  667.         add     edi, 0x610000
  668.         mov     ecx, 512/4
  669.         cld
  670.         rep     movsd
  671.         pop     edi esi ecx
  672.         pop     edx
  673.         pop     eax
  674.         ret
  675. .notread:
  676.         mov     eax, IDE_descriptor_table
  677.         mov     dword [eax], 0x284000
  678.         mov     word [eax+4], 0x2000
  679.         mov     dx, [IDEContrRegsBaseAddr]
  680.         cmp     [hdbase], 0x1F0
  681.         jz      @f
  682.         add     edx, 8
  683. @@:
  684.         push    edx
  685.         add     edx, 4
  686.         out     dx, eax
  687.         pop     edx
  688.         mov     al, 0
  689.         out     dx, al
  690.         add     edx, 2
  691.         mov     al, 6
  692.         out     dx, al
  693.         call    wait_for_hd_idle
  694.         cmp     [hd_error], 0
  695.         jnz     hd_read_error
  696.         call    disable_ide_int
  697.         xor     eax, eax
  698.         mov     edx, [hdbase]
  699.         inc     edx
  700.         out     dx, al
  701.         inc     edx
  702.         mov     eax, 10h
  703.         out     dx, al
  704.         inc     edx
  705.         mov     eax, [esp+4]
  706.         out     dx, al
  707.         shr     eax, 8
  708.         inc     edx
  709.         out     dx, al
  710.         shr     eax, 8
  711.         inc     edx
  712.         out     dx, al
  713.         shr     eax, 8
  714.         inc     edx
  715.         and     al, 0xF
  716.         add     al, byte [hdid]
  717.         add     al, 11100000b
  718.         out     dx, al
  719.         inc     edx
  720.         mov     al, 0xC8
  721.         out     dx, al
  722.         mov     dx, [IDEContrRegsBaseAddr]
  723.         cmp     [hdbase], 0x1F0
  724.         jz      @f
  725.         add     dx, 8
  726. @@:
  727.         mov     al, 9
  728.         out     dx, al
  729.         mov     eax, [0x3000]
  730.         mov     [dma_process], eax
  731.         mov     eax, [0x3010]
  732.         mov     [dma_slot_ptr], eax
  733.         cmp     [hdbase], 0x1F0
  734.         jnz     .ide1
  735.         mov     [irq14_func], hdd_irq14
  736.         jmp     @f
  737. .ide1:
  738.         mov     [irq15_func], hdd_irq15
  739. @@:
  740.         call    enable_ide_int
  741.         cmp     [hdbase], 0x1F0
  742.         jnz     .wait_ide1
  743.         call    wait_for_sector_dma_ide0
  744.         jmp     @f
  745. .wait_ide1:
  746.         call    wait_for_sector_dma_ide1
  747. @@:
  748.         cmp     [hd_error], 0
  749.         jnz     hd_read_error
  750.         pop     edx
  751.         pop     eax
  752.         mov     [dma_cur_sector], eax
  753.         jmp     hd_read_dma
  754.  
  755. align 4
  756. write_cache_chain:
  757.         push    esi
  758.         mov     eax, IDE_descriptor_table
  759.         mov     edx, [cache_chain_pos]
  760.         shl     edx, 9
  761.         add     edx, 0x610000
  762.         mov     [eax], edx
  763.         movzx   edx, [cache_chain_size]
  764.         shl     edx, 9
  765.         mov     [eax+4], dx
  766.         jmp     do_write_dma
  767. write_cache_sector:
  768.         push    esi
  769.         mov     eax, IDE_descriptor_table
  770.         mov     edx, edi
  771.         shl     edx, 9
  772.         add     edx, 0x610000
  773.         mov     [eax], edx
  774.         mov     word [eax+4], 0x200
  775. do_write_dma:
  776.         mov     dx, [IDEContrRegsBaseAddr]
  777.         cmp     [hdbase], 0x1F0
  778.         jz      @f
  779.         add     edx, 8
  780. @@:
  781.         push    edx
  782.         add     edx, 4
  783.         out     dx, eax
  784.         pop     edx
  785.         mov     al, 0
  786.         out     dx, al
  787.         add     edx, 2
  788.         mov     al, 6
  789.         out     dx, al
  790.         call    wait_for_hd_idle
  791.         cmp     [hd_error], 0
  792.         jnz     hd_write_error_dma
  793.         call    disable_ide_int
  794.         xor     eax, eax
  795.         mov     edx, [hdbase]
  796.         inc     edx
  797.         out     dx, al
  798.         inc     edx
  799.         mov     al, [cache_chain_size]
  800.         out     dx, al
  801.         inc     edx
  802.         mov     esi, [cache_chain_ptr]
  803.         mov     eax, [esi]
  804.         out     dx, al
  805.         shr     eax, 8
  806.         inc     edx
  807.         out     dx, al
  808.         shr     eax, 8
  809.         inc     edx
  810.         out     dx, al
  811.         shr     eax, 8
  812.         inc     edx
  813.         and     al, 0xF
  814.         add     al, byte [hdid]
  815.         add     al, 11100000b
  816.         out     dx, al
  817.         inc     edx
  818.         mov     al, 0xCA
  819.         out     dx, al
  820.         mov     dx, [IDEContrRegsBaseAddr]
  821.         cmp     [hdbase], 0x1F0
  822.         jz      @f
  823.         add     dx, 8
  824. @@:
  825.         mov     al, 1
  826.         out     dx, al
  827.         mov     eax, [0x3000]
  828.         mov     [dma_process], eax
  829.         mov     eax, [0x3010]
  830.         mov     [dma_slot_ptr], eax
  831.         cmp     [hdbase], 0x1F0
  832.         jnz     .ide1
  833.         mov     [irq14_func], hdd_irq14
  834.         jmp     @f
  835. .ide1:
  836.         mov     [irq15_func], hdd_irq15
  837. @@:
  838.         call    enable_ide_int
  839.         mov     [dma_cur_sector], not 0x40
  840.         cmp     [hdbase], 0x1F0
  841.         jnz     .wait_ide1
  842.         call    wait_for_sector_dma_ide0
  843.         jmp     @f
  844. .wait_ide1:
  845.         call    wait_for_sector_dma_ide1
  846. @@:
  847.         cmp     [hd_error], 0
  848.         jnz     hd_write_error_dma
  849.         pop     esi
  850.         ret
  851.  
  852. uglobal
  853. IDEContrRegsBaseAddr    dw      ?
  854. endg
  855. ; \end{Mario79}
  856.