Subversion Repositories Kolibri OS

Rev

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

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