Subversion Repositories Kolibri OS

Rev

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

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