Subversion Repositories Kolibri OS

Rev

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

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