Subversion Repositories Kolibri OS

Rev

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