Subversion Repositories Kolibri OS

Rev

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

  1. $Revision: 425 $
  2. ; Low-level driver for HDD access
  3. ; DMA support by Mario79
  4.  
  5. ;**************************************************************************
  6. ;
  7. ;   0x600008  - first entry in cache list
  8. ;
  9. ;            +0   - lba sector
  10. ;            +4   - state of cache sector
  11. ;                   0 = empty
  12. ;                   1 = used for read  ( same as in hd )
  13. ;                   2 = used for write ( differs from hd )
  14. ;
  15. ;      +65536 - cache entries
  16. ;
  17. ;**************************************************************************
  18.  
  19. align 4
  20. hd_read:
  21. ;-----------------------------------------------------------
  22. ; input  : eax = block to read
  23. ;          ebx = destination
  24. ;-----------------------------------------------------------
  25.         and     [hd_error], 0
  26.     push  ecx esi edi           ; scan cache
  27.  
  28.     mov   ecx,cache_max         ; entries in cache
  29.     mov   esi,OS_BASE+0x600000+8
  30.     mov   edi,1
  31.  
  32.   hdreadcache:
  33.  
  34.     cmp   dword [esi+4],0       ; empty
  35.     je    nohdcache
  36.  
  37.     cmp   [esi],eax             ; correct sector
  38.     je    yeshdcache
  39.  
  40.   nohdcache:
  41.  
  42.     add   esi,8
  43.     inc   edi
  44.     dec   ecx
  45.     jnz   hdreadcache
  46.  
  47.     call  find_empty_slot       ; ret in edi
  48.     cmp   [hd_error],0
  49.     jne   return_01
  50.         cmp     [dma_hdd], 1
  51.         jnz     .nodma
  52.         call    hd_read_dma
  53.         jmp     @f
  54. .nodma:
  55.         call    hd_read_pio
  56. @@:
  57.  
  58.     lea   esi,[edi*8+OS_BASE+0x600000]
  59.     mov   [esi],eax             ; sector number
  60.     mov   dword [esi+4],1       ; hd read - mark as same as in hd
  61.  
  62.   yeshdcache:
  63.  
  64.     mov   esi,edi
  65.     shl   esi,9
  66.     add   esi,OS_BASE+0x600000+65536
  67.     mov   edi,ebx
  68.     mov   ecx,512/4
  69.     cld
  70.     rep   movsd                 ; move data
  71.  return_01:
  72.     pop   edi esi ecx
  73.     ret
  74.  
  75. align 4
  76. hd_read_pio:
  77.     push  eax edx
  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,OS_BASE+0x600000+65536
  120.     mov   ecx,256
  121.     mov   edx,[hdbase]
  122.     cld
  123.     rep   insw
  124.     pop   edi
  125.     sti
  126.  
  127.     pop   edx eax
  128.     ret
  129.  
  130. disable_ide_int:
  131. ;        mov edx,[hdbase]
  132. ;        add edx,0x206
  133. ;        mov al,2
  134. ;        out dx,al
  135.         cli
  136.         ret
  137.  
  138. enable_ide_int:
  139. ;        mov edx,[hdbase]
  140. ;        add edx,0x206
  141. ;        mov al,0
  142. ;        out dx,al
  143.         sti
  144.         ret
  145.  
  146. align 4
  147. hd_write:
  148. ;-----------------------------------------------------------
  149. ; input  : eax = block
  150. ;          ebx = pointer to memory
  151. ;-----------------------------------------------------------
  152.     push  ecx esi edi
  153.  
  154.     ; check if the cache already has the sector and overwrite it
  155.  
  156.     mov   ecx,cache_max
  157.     mov   esi,OS_BASE+0x600000+8
  158.     mov   edi,1
  159.  
  160.   hdwritecache:
  161.  
  162.     cmp   dword [esi+4],0       ; if cache slot is empty
  163.     je    not_in_cache_write
  164.  
  165.     cmp   [esi],eax             ; if the slot has the sector
  166.     je    yes_in_cache_write
  167.  
  168.   not_in_cache_write:
  169.  
  170.     add   esi,8
  171.     inc   edi
  172.     dec   ecx
  173.     jnz   hdwritecache
  174.  
  175.     ; sector not found in cache
  176.     ; write the block to a new location
  177.  
  178.     call  find_empty_slot       ; ret in edi
  179.     cmp   [hd_error],0
  180.     jne   hd_write_access_denied
  181.  
  182.     lea   esi,[edi*8+OS_BASE+0x600000]
  183.     mov   [esi],eax             ; sector number
  184.  
  185.   yes_in_cache_write:
  186.  
  187.     mov   dword [esi+4],2       ; write - differs from hd
  188.  
  189.     shl   edi,9
  190.     add   edi,OS_BASE+0x600000+65536
  191.     mov   esi,ebx
  192.     mov   ecx,512/4
  193.     cld
  194.     rep   movsd                 ; move data
  195.  hd_write_access_denied:
  196.     pop   edi esi ecx
  197.     ret
  198.  
  199.  
  200. write_cache:
  201. ;-----------------------------------------------------------
  202. ; write all changed sectors to disk
  203. ;-----------------------------------------------------------
  204.     push  eax ecx edx esi edi
  205.  
  206.     ; write difference ( 2 ) from cache to hd
  207.  
  208.     mov   ecx,cache_max
  209.     mov   esi,OS_BASE+0x600000+8
  210.     mov   edi,1
  211.  
  212.   write_cache_more:
  213.  
  214.     cmp   dword [esi+4],2       ; if cache slot is not different
  215.     jne   .write_chain
  216.  
  217.     mov   dword [esi+4],1       ; same as in hd
  218.     mov   eax,[esi]             ; eax = sector to write
  219.  
  220.     cmp   eax,[PARTITION_START]
  221.     jb    danger
  222.     cmp   eax,[PARTITION_END]
  223.     ja    danger
  224.  
  225.         cmp     [allow_dma_write], 1
  226.         jnz     .nodma
  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,OS_BASE+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+OS_BASE+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,OS_BASE+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',0
  415. ;  hd_read_str      db 'K : FS - HD read error',0
  416. ;  hd_write_str     db 'K : FS - HD write error',0
  417. ;  hd_lba_str       db 'K : FS - HD LBA error',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.     DEBUGF 1,"K : FS - HD timeout\n"
  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.     DEBUGF 1,"K : FS - HD read error\n"
  439.     pop   edx eax
  440.     ret
  441.  
  442. hd_write_error:
  443.  
  444. ;    call  clear_hd_cache
  445. ;    call  clear_application_table_status
  446. ;    mov   esi,hd_write_str
  447. ;    call  sys_msg_board_str
  448.     DEBUGF 1,"K : FS - HD write error\n"
  449.     ret
  450.  
  451. hd_write_error_dma:
  452. ;        call    clear_hd_cache
  453. ;        call    clear_application_table_status
  454. ;        mov     esi, hd_write_str
  455. ;        call    sys_msg_board_str
  456.         DEBUGF 1,"K : FS - HD read error\n"
  457.         pop     esi
  458.         ret
  459.  
  460. hd_lba_error:
  461. ;    call  clear_hd_cache
  462. ;    call  clear_application_table_status
  463. ;    mov   esi,hd_lba_str
  464. ;    call  sys_msg_board_str
  465.     DEBUGF 1,"K : FS - HD LBA error\n"
  466.     jmp   LBA_read_ret
  467.  
  468.  
  469. align 4
  470. wait_for_hd_idle:
  471.  
  472.     push  eax edx
  473.  
  474.     call  save_hd_wait_timeout
  475.  
  476.     mov   edx,[hdbase]
  477.     add   edx,0x7
  478.  
  479.   wfhil1:
  480.  
  481.     call  check_hd_wait_timeout
  482.     cmp   [hd_error],0
  483.     jne   @f
  484.  
  485.     in    al,dx
  486.     test  al,128
  487.     jnz   wfhil1
  488.  
  489.  @@:
  490.  
  491.     pop   edx eax
  492.     ret
  493.  
  494.  
  495. align 4
  496. wait_for_sector_buffer:
  497.  
  498.     push  eax edx
  499.  
  500.     mov   edx,[hdbase]
  501.     add   edx,0x7
  502.  
  503.     call  save_hd_wait_timeout
  504.  
  505.   hdwait_sbuf:                  ; wait for sector buffer to be ready
  506.  
  507.     call  check_hd_wait_timeout
  508.     cmp   [hd_error],0
  509.     jne   @f
  510.  
  511.     in    al,dx
  512.     test  al,8
  513.     jz    hdwait_sbuf
  514.  
  515.     mov   [hd_error],0
  516.  
  517.     cmp   [hd_setup],1          ; do not mark error for setup request
  518.     je    buf_wait_ok
  519.  
  520.     test  al,1                  ; previous command ended up with an error
  521.     jz    buf_wait_ok
  522.  @@:
  523.     mov   [hd_error],1
  524.  
  525.   buf_wait_ok:
  526.  
  527.     pop   edx eax
  528.     ret
  529.  
  530. ; \begin{Mario79}
  531. align 4
  532. wait_for_sector_dma_ide0:
  533.         push    eax
  534.         push    edx
  535.         call    save_hd_wait_timeout
  536. .wait:
  537.         call    change_task
  538.         cmp     [irq14_func], hdd_irq14
  539.         jnz     .done
  540.         call    check_hd_wait_timeout
  541.         cmp     [hd_error], 0
  542.         jz      .wait
  543.         mov     [irq14_func], hdd_irq_null
  544.         mov     dx, [IDEContrRegsBaseAddr]
  545.         mov     al, 0
  546.         out     dx, al
  547. .done:
  548.         pop     edx
  549.         pop     eax
  550.         ret
  551.  
  552. align 4
  553. wait_for_sector_dma_ide1:
  554.         push    eax
  555.         push    edx
  556.         call    save_hd_wait_timeout
  557. .wait:
  558.         call    change_task
  559.         cmp     [irq15_func], hdd_irq15
  560.         jnz     .done
  561.         call    check_hd_wait_timeout
  562.         cmp     [hd_error], 0
  563.         jz      .wait
  564.         mov     [irq15_func], hdd_irq_null
  565.         mov     dx, [IDEContrRegsBaseAddr]
  566.         add     dx, 8
  567.         mov     al, 0
  568.         out     dx, al
  569. .done:
  570.         pop     edx
  571.         pop     eax
  572.         ret
  573.  
  574. iglobal
  575. align 4
  576. ; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary
  577. IDE_descriptor_table:
  578.         dd      OS_BASE+284000h
  579.         dw      2000h
  580.         dw      8000h
  581.  
  582. dma_cur_sector  dd      not 40h
  583. irq14_func      dd      hdd_irq_null
  584. irq15_func      dd      hdd_irq_null
  585. endg
  586.  
  587. uglobal
  588. ; all uglobals are zeroed at boot
  589. dma_process     dd      0
  590. dma_slot_ptr    dd      0
  591. cache_chain_pos dd      0
  592. cache_chain_ptr dd      0
  593. cache_chain_size        db      0
  594. cache_chain_started     db      0
  595. dma_task_switched       db      0
  596. dma_hdd         db      0
  597. allow_dma_write db      0
  598. endg
  599.  
  600. align 4
  601. hdd_irq14:
  602.         pushfd
  603.         cli
  604.         pushad
  605.         mov     [irq14_func], hdd_irq_null
  606.         mov     dx, [IDEContrRegsBaseAddr]
  607.         mov     al, 0
  608.         out     dx, al
  609.         call    update_counters
  610.         mov     ebx, [dma_process]
  611.         cmp     [CURRENT_TASK], ebx
  612.         jz      .noswitch
  613.         mov     [dma_task_switched], 1
  614.         mov     edi, [dma_slot_ptr]
  615.         mov     eax, [CURRENT_TASK]
  616.         mov     [dma_process], eax
  617.         mov     eax, [TASK_BASE]
  618.         mov     [dma_slot_ptr], eax
  619.         mov     [CURRENT_TASK], ebx
  620.         mov     [TASK_BASE], edi
  621.         mov     byte [0xFFFF], 1
  622.         call    do_change_task
  623. .noswitch:
  624.         popad
  625.         popfd
  626. align 4
  627. hdd_irq_null:
  628.         ret
  629.  
  630. align 4
  631. hdd_irq15:
  632.         pushfd
  633.         cli
  634.         pushad
  635.         mov     [irq15_func], hdd_irq_null
  636.         mov     dx, [IDEContrRegsBaseAddr]
  637.         add     dx, 8
  638.         mov     al, 0
  639.         out     dx, al
  640.         call    update_counters
  641.         mov     ebx, [dma_process]
  642.         cmp     [CURRENT_TASK], ebx
  643.         jz      .noswitch
  644.         mov     [dma_task_switched], 1
  645.         mov     edi, [dma_slot_ptr]
  646.         mov     eax, [CURRENT_TASK]
  647.         mov     [dma_process], eax
  648.         mov     eax, [TASK_BASE]
  649.         mov     [dma_slot_ptr], eax
  650.         mov     [CURRENT_TASK], ebx
  651.         mov     [TASK_BASE], edi
  652.         mov     byte [0xFFFF], 1
  653.         call    do_change_task
  654. .noswitch:
  655.         popad
  656.         popfd
  657.         ret
  658.  
  659. align 4
  660. hd_read_dma:
  661.         push    eax
  662.         push    edx
  663.         mov     edx, [dma_cur_sector]
  664.         cmp     eax, edx
  665.         jb      .notread
  666.         add     edx, 15
  667.         cmp     [esp+4], edx
  668.         ja      .notread
  669.         mov     eax, [esp+4]
  670.         sub     eax, [dma_cur_sector]
  671.         shl     eax, 9
  672.         add     eax, OS_BASE+0x284000
  673.         push    ecx esi edi
  674.         mov     esi, eax
  675.         shl     edi, 9
  676.         add     edi, OS_BASE+0x610000
  677.         mov     ecx, 512/4
  678.         cld
  679.         rep     movsd
  680.         pop     edi esi ecx
  681.         pop     edx
  682.         pop     eax
  683.         ret
  684. .notread:
  685.         mov     eax, IDE_descriptor_table-OS_BASE
  686.         mov     dword [eax+OS_BASE],  0x284000
  687.         mov     word [eax+4+OS_BASE], 0x2000
  688.         mov     dx, [IDEContrRegsBaseAddr]
  689.         cmp     [hdbase], 0x1F0
  690.         jz      @f
  691.         add     edx, 8
  692. @@:
  693.         push    edx
  694.         add     edx, 4
  695.         out     dx, eax
  696.         pop     edx
  697.         mov     al, 0
  698.         out     dx, al
  699.         add     edx, 2
  700.         mov     al, 6
  701.         out     dx, al
  702.         call    wait_for_hd_idle
  703.         cmp     [hd_error], 0
  704.         jnz     hd_read_error
  705.         call    disable_ide_int
  706.         xor     eax, eax
  707.         mov     edx, [hdbase]
  708.         inc     edx
  709.         out     dx, al
  710.         inc     edx
  711.         mov     eax, 10h
  712.         out     dx, al
  713.         inc     edx
  714.         mov     eax, [esp+4]
  715.         out     dx, al
  716.         shr     eax, 8
  717.         inc     edx
  718.         out     dx, al
  719.         shr     eax, 8
  720.         inc     edx
  721.         out     dx, al
  722.         shr     eax, 8
  723.         inc     edx
  724.         and     al, 0xF
  725.         add     al, byte [hdid]
  726.         add     al, 11100000b
  727.         out     dx, al
  728.         inc     edx
  729.         mov     al, 0xC8
  730.         out     dx, al
  731.         mov     dx, [IDEContrRegsBaseAddr]
  732.         cmp     [hdbase], 0x1F0
  733.         jz      @f
  734.         add     dx, 8
  735. @@:
  736.         mov     al, 9
  737.         out     dx, al
  738.         mov     eax, [CURRENT_TASK]
  739.         mov     [dma_process], eax
  740.         mov     eax, [TASK_BASE]
  741.         mov     [dma_slot_ptr], eax
  742.         cmp     [hdbase], 0x1F0
  743.         jnz     .ide1
  744.         mov     [irq14_func], hdd_irq14
  745.         jmp     @f
  746. .ide1:
  747.         mov     [irq15_func], hdd_irq15
  748. @@:
  749.         call    enable_ide_int
  750.         cmp     [hdbase], 0x1F0
  751.         jnz     .wait_ide1
  752.         call    wait_for_sector_dma_ide0
  753.         jmp     @f
  754. .wait_ide1:
  755.         call    wait_for_sector_dma_ide1
  756. @@:
  757.         cmp     [hd_error], 0
  758.         jnz     hd_read_error
  759.         pop     edx
  760.         pop     eax
  761.         mov     [dma_cur_sector], eax
  762.         jmp     hd_read_dma
  763.  
  764. align 4
  765. write_cache_chain:
  766.         push    esi
  767.         mov     eax, IDE_descriptor_table
  768.         mov     edx, [cache_chain_pos]
  769.         shl     edx, 9
  770.         add     edx, OS_BASE+0x610000
  771.         mov     [eax], edx
  772.         movzx   edx, [cache_chain_size]
  773.         shl     edx, 9
  774.         mov     [eax+4], dx
  775.         jmp     do_write_dma
  776. write_cache_sector:
  777.         push    esi
  778.         mov     eax, IDE_descriptor_table
  779.         mov     edx, edi
  780.         shl     edx, 9
  781.         add     edx, OS_BASE+0x610000
  782.         mov     [eax], edx
  783.         mov     word [eax+4], 0x200
  784. do_write_dma:
  785.         mov     dx, [IDEContrRegsBaseAddr]
  786.         cmp     [hdbase], 0x1F0
  787.         jz      @f
  788.         add     edx, 8
  789. @@:
  790.         push    edx
  791.         add     edx, 4
  792.         out     dx, eax
  793.         pop     edx
  794.         mov     al, 0
  795.         out     dx, al
  796.         add     edx, 2
  797.         mov     al, 6
  798.         out     dx, al
  799.         call    wait_for_hd_idle
  800.         cmp     [hd_error], 0
  801.         jnz     hd_write_error_dma
  802.         call    disable_ide_int
  803.         xor     eax, eax
  804.         mov     edx, [hdbase]
  805.         inc     edx
  806.         out     dx, al
  807.         inc     edx
  808.         mov     al, [cache_chain_size]
  809.         out     dx, al
  810.         inc     edx
  811.         mov     esi, [cache_chain_ptr]
  812.         mov     eax, [esi]
  813.         out     dx, al
  814.         shr     eax, 8
  815.         inc     edx
  816.         out     dx, al
  817.         shr     eax, 8
  818.         inc     edx
  819.         out     dx, al
  820.         shr     eax, 8
  821.         inc     edx
  822.         and     al, 0xF
  823.         add     al, byte [hdid]
  824.         add     al, 11100000b
  825.         out     dx, al
  826.         inc     edx
  827.         mov     al, 0xCA
  828.         out     dx, al
  829.         mov     dx, [IDEContrRegsBaseAddr]
  830.         cmp     [hdbase], 0x1F0
  831.         jz      @f
  832.         add     dx, 8
  833. @@:
  834.         mov     al, 1
  835.         out     dx, al
  836.         mov     eax, [CURRENT_TASK]
  837.         mov     [dma_process], eax
  838.         mov     eax, [TASK_BASE]
  839.         mov     [dma_slot_ptr], eax
  840.         cmp     [hdbase], 0x1F0
  841.         jnz     .ide1
  842.         mov     [irq14_func], hdd_irq14
  843.         jmp     @f
  844. .ide1:
  845.         mov     [irq15_func], hdd_irq15
  846. @@:
  847.         call    enable_ide_int
  848.         mov     [dma_cur_sector], not 0x40
  849.         cmp     [hdbase], 0x1F0
  850.         jnz     .wait_ide1
  851.         call    wait_for_sector_dma_ide0
  852.         jmp     @f
  853. .wait_ide1:
  854.         call    wait_for_sector_dma_ide1
  855. @@:
  856.         cmp     [hd_error], 0
  857.         jnz     hd_write_error_dma
  858.         pop     esi
  859.         ret
  860.  
  861. uglobal
  862. IDEContrRegsBaseAddr    dw      ?
  863. endg
  864. ; \end{Mario79}
  865.