Subversion Repositories Kolibri OS

Rev

Rev 593 | Rev 709 | 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: 597 $
  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. dma_hdpos       dd      0
  481. irq14_func      dd      hdd_irq_null
  482. irq15_func      dd      hdd_irq_null
  483. endg
  484.  
  485. uglobal
  486. ; all uglobals are zeroed at boot
  487. dma_process     dd      0
  488. dma_slot_ptr    dd      0
  489. cache_chain_pos dd      0
  490. cache_chain_ptr dd      0
  491. cache_chain_size        db      0
  492. cache_chain_started     db      0
  493. dma_task_switched       db      0
  494. dma_hdd         db      0
  495. allow_dma_access db      0
  496. endg
  497.  
  498. align 4
  499. hdd_irq14:
  500.         pushfd
  501.         cli
  502.         pushad
  503.         mov     [irq14_func], hdd_irq_null
  504.         mov     dx, [IDEContrRegsBaseAddr]
  505.         mov     al, 0
  506.         out     dx, al
  507. ;        call    update_counters
  508. ;        mov     ebx, [dma_process]
  509. ;        cmp     [CURRENT_TASK], ebx
  510. ;        jz      .noswitch
  511. ;        mov     [dma_task_switched], 1
  512. ;        mov     edi, [dma_slot_ptr]
  513. ;        mov     eax, [CURRENT_TASK]
  514. ;        mov     [dma_process], eax
  515. ;        mov     eax, [TASK_BASE]
  516. ;        mov     [dma_slot_ptr], eax
  517. ;        mov     [CURRENT_TASK], ebx
  518. ;        mov     [TASK_BASE], edi
  519. ;        mov     byte [DONT_SWITCH], 1
  520. ;        call    do_change_task
  521. .noswitch:
  522.         popad
  523.         popfd
  524. align 4
  525. hdd_irq_null:
  526.         ret
  527.  
  528. align 4
  529. hdd_irq15:
  530.         pushfd
  531.         cli
  532.         pushad
  533.         mov     [irq15_func], hdd_irq_null
  534.         mov     dx, [IDEContrRegsBaseAddr]
  535.         add     dx, 8
  536.         mov     al, 0
  537.         out     dx, al
  538. ;        call    update_counters
  539. ;        mov     ebx, [dma_process]
  540. ;        cmp     [CURRENT_TASK], ebx
  541. ;        jz      .noswitch
  542. ;        mov     [dma_task_switched], 1
  543. ;        mov     edi, [dma_slot_ptr]
  544. ;        mov     eax, [CURRENT_TASK]
  545. ;        mov     [dma_process], eax
  546. ;        mov     eax, [TASK_BASE]
  547. ;        mov     [dma_slot_ptr], eax
  548. ;        mov     [CURRENT_TASK], ebx
  549. ;        mov     [TASK_BASE], edi
  550. ;        mov     byte [DONT_SWITCH], 1
  551. ;        call    do_change_task
  552. .noswitch:
  553.         popad
  554.         popfd
  555.         ret
  556.  
  557. align 4
  558. hd_read_dma:
  559.         push    eax
  560.         push    edx
  561.         mov     edx,[dma_hdpos]
  562.         cmp     edx,[hdpos]
  563.         jne     .notread
  564.         mov     edx, [dma_cur_sector]
  565.         cmp     eax, edx
  566.         jb      .notread
  567.         add     edx, 15
  568.         cmp     [esp+4], edx
  569.         ja      .notread
  570.         mov     eax, [esp+4]
  571.         sub     eax, [dma_cur_sector]
  572.         shl     eax, 9
  573.         add     eax, (OS_BASE+IDE_DMA)
  574.         push    ecx esi edi
  575.         mov     esi, eax
  576.         shl     edi, 9
  577. ;        add     edi, HD_CACHE+0x10000
  578.         push  eax
  579.         call  calculate_cache_2
  580.         add   edi,eax
  581.         pop   eax
  582.  
  583.         mov     ecx, 512/4
  584.         cld
  585.         rep     movsd
  586.         pop     edi esi ecx
  587.         pop     edx
  588.         pop     eax
  589.         ret
  590. .notread:
  591.         mov     eax, IDE_descriptor_table
  592.         mov     dword [eax],  IDE_DMA
  593.         mov     word [eax+4], 0x2000
  594.         sub     eax, OS_BASE
  595.         mov     dx, [IDEContrRegsBaseAddr]
  596.         cmp     [hdbase], 0x1F0
  597.         jz      @f
  598.         add     edx, 8
  599. @@:
  600.         push    edx
  601.         add     edx, 4
  602.         out     dx, eax
  603.         pop     edx
  604.         mov     al, 0
  605.         out     dx, al
  606.         add     edx, 2
  607.         mov     al, 6
  608.         out     dx, al
  609.         call    wait_for_hd_idle
  610.         cmp     [hd_error], 0
  611.         jnz     hd_read_error
  612.         call    disable_ide_int
  613.         xor     eax, eax
  614.         mov     edx, [hdbase]
  615.         inc     edx
  616.         out     dx, al
  617.         inc     edx
  618.         mov     eax, 10h
  619.         out     dx, al
  620.         inc     edx
  621.         mov     eax, [esp+4]
  622.         out     dx, al
  623.         shr     eax, 8
  624.         inc     edx
  625.         out     dx, al
  626.         shr     eax, 8
  627.         inc     edx
  628.         out     dx, al
  629.         shr     eax, 8
  630.         inc     edx
  631.         and     al, 0xF
  632.         add     al, byte [hdid]
  633.         add     al, 11100000b
  634.         out     dx, al
  635.         inc     edx
  636.         mov     al, 0xC8
  637.         out     dx, al
  638.         mov     dx, [IDEContrRegsBaseAddr]
  639.         cmp     [hdbase], 0x1F0
  640.         jz      @f
  641.         add     dx, 8
  642. @@:
  643.         mov     al, 9
  644.         out     dx, al
  645.         mov     eax, [CURRENT_TASK]
  646.         mov     [dma_process], eax
  647.         mov     eax, [TASK_BASE]
  648.         mov     [dma_slot_ptr], eax
  649.         cmp     [hdbase], 0x1F0
  650.         jnz     .ide1
  651.         mov     [irq14_func], hdd_irq14
  652.         jmp     @f
  653. .ide1:
  654.         mov     [irq15_func], hdd_irq15
  655. @@:
  656.         call    enable_ide_int
  657.         cmp     [hdbase], 0x1F0
  658.         jnz     .wait_ide1
  659.         call    wait_for_sector_dma_ide0
  660.         jmp     @f
  661. .wait_ide1:
  662.         call    wait_for_sector_dma_ide1
  663. @@:
  664.         cmp     [hd_error], 0
  665.         jnz     hd_read_error
  666.         mov     eax,[hdpos]
  667.         mov     [dma_hdpos],eax
  668.         pop     edx
  669.         pop     eax
  670.         mov     [dma_cur_sector], eax
  671.         jmp     hd_read_dma
  672.  
  673. align 4
  674. write_cache_sector:
  675.         mov     [cache_chain_size],1
  676.         mov     [cache_chain_pos],edi
  677. write_cache_chain:
  678.         push    esi
  679.         mov     eax, IDE_descriptor_table
  680.         mov     edx,eax
  681.         pusha
  682.         mov     esi,[cache_chain_pos]
  683.         shl     esi, 9
  684.         call    calculate_cache_2
  685.         add     esi,eax
  686.         mov     edi, (OS_BASE+IDE_DMA)
  687.         mov     dword [edx], IDE_DMA
  688.         movzx   ecx, [cache_chain_size]
  689.         shl     ecx, 9
  690.         mov     word [edx+4], cx
  691.         shr     ecx,2
  692.         cld
  693.         rep movsd
  694.         popa
  695.         sub     eax, OS_BASE
  696.         mov     dx, [IDEContrRegsBaseAddr]
  697.         cmp     [hdbase], 0x1F0
  698.         jz      @f
  699.         add     edx, 8
  700. @@:
  701.         push    edx
  702.         add     edx, 4
  703.         out     dx, eax
  704.         pop     edx
  705.         mov     al, 0
  706.         out     dx, al
  707.         add     edx, 2
  708.         mov     al, 6
  709.         out     dx, al
  710.         call    wait_for_hd_idle
  711.         cmp     [hd_error], 0
  712.         jnz     hd_write_error_dma
  713.         call    disable_ide_int
  714.         xor     eax, eax
  715.         mov     edx, [hdbase]
  716.         inc     edx
  717.         out     dx, al
  718.         inc     edx
  719.         mov     al, [cache_chain_size]
  720.         out     dx, al
  721.         inc     edx
  722.         mov     esi, [cache_chain_ptr]
  723.         mov     eax, [esi]
  724.         out     dx, al
  725.         shr     eax, 8
  726.         inc     edx
  727.         out     dx, al
  728.         shr     eax, 8
  729.         inc     edx
  730.         out     dx, al
  731.         shr     eax, 8
  732.         inc     edx
  733.         and     al, 0xF
  734.         add     al, byte [hdid]
  735.         add     al, 11100000b
  736.         out     dx, al
  737.         inc     edx
  738.         mov     al, 0xCA
  739.         out     dx, al
  740.         mov     dx, [IDEContrRegsBaseAddr]
  741.         cmp     [hdbase], 0x1F0
  742.         jz      @f
  743.         add     dx, 8
  744. @@:
  745.         mov     al, 1
  746.         out     dx, al
  747.         mov     eax, [CURRENT_TASK]
  748.         mov     [dma_process], eax
  749.         mov     eax, [TASK_BASE]
  750.         mov     [dma_slot_ptr], eax
  751.         cmp     [hdbase], 0x1F0
  752.         jnz     .ide1
  753.         mov     [irq14_func], hdd_irq14
  754.         jmp     @f
  755. .ide1:
  756.         mov     [irq15_func], hdd_irq15
  757. @@:
  758.         call    enable_ide_int
  759.         mov     [dma_cur_sector], not 0x40
  760.         cmp     [hdbase], 0x1F0
  761.         jnz     .wait_ide1
  762.         call    wait_for_sector_dma_ide0
  763.         jmp     @f
  764. .wait_ide1:
  765.         call    wait_for_sector_dma_ide1
  766. @@:
  767.         cmp     [hd_error], 0
  768.         jnz     hd_write_error_dma
  769.         pop     esi
  770.         ret
  771.  
  772. uglobal
  773. IDEContrRegsBaseAddr    dw      ?
  774. endg
  775. ; \end{Mario79}
  776.