Subversion Repositories Kolibri OS

Rev

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

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