Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 4420 $
  9.  
  10.  
  11. ; Access through BIOS by diamond
  12. iglobal
  13. align 4
  14. bd_callbacks:
  15.         dd      bd_callbacks.end - bd_callbacks         ; strucsize
  16.         dd      0       ; no close function
  17.         dd      0       ; no closemedia function
  18.         dd      bd_querymedia
  19.         dd      bd_read_interface
  20.         dd      bd_write_interface
  21.         dd      0       ; no flush function
  22.         dd      0       ; use default cache size
  23. .end:
  24. endg
  25.  
  26. proc bd_read_interface stdcall uses edi, \
  27.         userdata, buffer, startsector:qword, numsectors
  28.         ; userdata = old [hdpos] = 80h + index in NumBiosDisks
  29.         ; buffer = pointer to buffer for data
  30.         ; startsector = 64-bit start sector
  31.         ; numsectors = pointer to number of sectors on input,
  32.         ;  must be filled with number of sectors really read
  33. locals
  34. sectors_todo    dd      ?
  35. endl
  36. ; 1. Initialize number of sectors: get number of requested sectors
  37. ; and say that no sectors were read yet.
  38.         mov     ecx, [numsectors]
  39.         mov     eax, [ecx]
  40.         mov     dword [ecx], 0
  41.         mov     [sectors_todo], eax
  42. ; 2. Acquire the global lock.
  43.         mov     ecx, ide_mutex
  44.         call    mutex_lock
  45. ; 3. Convert parameters to the form suitable for worker procedures.
  46. ; Underlying procedures do not know about 64-bit sectors.
  47. ; Worker procedures use global variables and edi for [buffer].
  48.         cmp     dword [startsector+4], 0
  49.         jnz     .fail
  50.         and     [hd_error], 0
  51.         mov     eax, [userdata]
  52.         mov     [hdpos], eax
  53.         mov     eax, dword [startsector]
  54.         mov     edi, [buffer]
  55. ; 4. Worker procedures take one sectors per time, so loop over all sectors to read.
  56. .sectors_loop:
  57.         call    bd_read
  58.         cmp     [hd_error], 0
  59.         jnz     .fail
  60.         mov     ecx, [numsectors]
  61.         inc     dword [ecx]     ; one more sector is read
  62.         dec     [sectors_todo]
  63.         jz      .done
  64.         inc     eax
  65.         jnz     .sectors_loop
  66. ; 5. Loop is done, either due to error or because everything is done.
  67. ; Release the global lock and return the corresponding status.
  68. .fail:
  69.         mov     ecx, ide_mutex
  70.         call    mutex_unlock
  71.         or      eax, -1
  72.         ret
  73. .done:
  74.         mov     ecx, ide_mutex
  75.         call    mutex_unlock
  76.         xor     eax, eax
  77.         ret
  78. endp
  79.  
  80. proc bd_write_interface stdcall uses esi edi, \
  81.         userdata, buffer, startsector:qword, numsectors
  82.         ; userdata = old [hdpos] = 80h + index in NumBiosDisks
  83.         ; buffer = pointer to buffer with data
  84.         ; startsector = 64-bit start sector
  85.         ; numsectors = pointer to number of sectors on input,
  86.         ;  must be filled with number of sectors really written
  87. locals
  88. sectors_todo    dd      ?
  89. endl
  90. ; 1. Initialize number of sectors: get number of requested sectors
  91. ; and say that no sectors were read yet.      
  92.         mov     ecx, [numsectors]
  93.         mov     eax, [ecx]
  94.         mov     dword [ecx], 0
  95.         mov     [sectors_todo], eax
  96. ; 2. Acquire the global lock.
  97.         mov     ecx, ide_mutex
  98.         call    mutex_lock
  99. ; 3. Convert parameters to the form suitable for worker procedures.
  100. ; Underlying procedures do not know about 64-bit sectors.
  101. ; Worker procedures use global variables and esi for [buffer].
  102.         cmp     dword [startsector+4], 0
  103.         jnz     .fail
  104.         and     [hd_error], 0
  105.         mov     eax, [userdata]
  106.         mov     [hdpos], eax
  107.         mov     esi, [buffer]
  108.         lea     edi, [startsector]
  109.         mov     [cache_chain_ptr], edi
  110. ; 4. Worker procedures take max 16 sectors per time,
  111. ; loop until all sectors will be processed.
  112. .sectors_loop:
  113.         mov     ecx, 16
  114.         cmp     ecx, [sectors_todo]
  115.         jbe     @f
  116.         mov     ecx, [sectors_todo]
  117. @@:
  118.         mov     [cache_chain_size], cl
  119.         call    bd_write_cache_chain
  120.         cmp     [hd_error], 0
  121.         jnz     .fail
  122.         movzx   ecx, [cache_chain_size]
  123.         mov     eax, [numsectors]
  124.         add     [eax], ecx
  125.         sub     [sectors_todo], ecx
  126.         jz      .done
  127.         add     [edi], ecx
  128.         jc      .fail
  129.         shl     ecx, 9
  130.         add     esi, ecx
  131.         jmp     .sectors_loop
  132. ; 5. Loop is done, either due to error or because everything is done.
  133. ; Release the global lock and return the corresponding status.
  134. .fail:
  135.         mov     ecx, ide_mutex
  136.         call    mutex_unlock
  137.         or      eax, -1
  138.         ret
  139. .done:
  140.         mov     ecx, ide_mutex
  141.         call    mutex_unlock
  142.         xor     eax, eax
  143.         ret
  144. endp
  145.  
  146. ; This is a stub.
  147. proc bd_querymedia stdcall, hd_data, mediainfo
  148.         mov     eax, [mediainfo]
  149.         mov     [eax+DISKMEDIAINFO.Flags], 0
  150.         mov     [eax+DISKMEDIAINFO.SectorSize], 512
  151.         or      dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF
  152.         or      dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
  153.         xor     eax, eax
  154.         ret
  155. endp
  156.  
  157. ;-----------------------------------------------------------------------------
  158. ; \begin{diamond}
  159. uglobal
  160. bios_hdpos      dd 0       ; 0 is invalid value for [hdpos]
  161. bios_cur_sector dd ?
  162. bios_read_len   dd ?
  163. endg
  164. ;-----------------------------------------------------------------------------
  165. align 4
  166. bd_read:
  167.         push    eax
  168.         push    edx
  169.         mov     edx, [bios_hdpos]
  170.         cmp     edx, [hdpos]
  171.         jne     .notread
  172.         mov     edx, [bios_cur_sector]
  173.         cmp     eax, edx
  174.         jb      .notread
  175.         add     edx, [bios_read_len]
  176.         dec     edx
  177.         cmp     eax, edx
  178.         ja      .notread
  179.         sub     eax, [bios_cur_sector]
  180.         shl     eax, 9
  181.         add     eax, (OS_BASE+0x9A000)
  182.         push    ecx esi
  183.         mov     esi, eax
  184.         mov     ecx, 512/4
  185.         cld
  186.         rep movsd
  187.         pop     esi ecx
  188.         pop     edx
  189.         pop     eax
  190.         ret
  191. .notread:
  192.         push    ecx
  193.         mov     dl, 42h
  194.         mov     ecx, 16
  195.         call    int13_call
  196.         pop     ecx
  197.         test    eax, eax
  198.         jnz     .v86err
  199.         test    edx, edx
  200.         jz      .readerr
  201.         mov     [bios_read_len], edx
  202.         mov     edx, [hdpos]
  203.         mov     [bios_hdpos], edx
  204.         pop     edx
  205.         pop     eax
  206.         mov     [bios_cur_sector], eax
  207.         jmp     bd_read
  208. .readerr:
  209. .v86err:
  210.         mov     [hd_error], 1
  211.         jmp     hd_read_error
  212. ;-----------------------------------------------------------------------------
  213. align 4
  214. bd_write_cache_chain:
  215.         pusha
  216.         mov     edi, OS_BASE + 0x9A000
  217.         movzx   ecx, [cache_chain_size]
  218.         push    ecx
  219.         shl     ecx, 9-2
  220.         rep movsd
  221.         pop     ecx
  222.         mov     dl, 43h
  223.         mov     eax, [cache_chain_ptr]
  224.         mov     eax, [eax]
  225.         call    int13_call
  226.         test    eax, eax
  227.         jnz     .v86err
  228.         cmp     edx, ecx
  229.         jnz     .writeerr
  230.         popa
  231.         ret
  232. .v86err:
  233. .writeerr:
  234.         popa
  235.         mov     [hd_error], 1
  236.         jmp     hd_write_error
  237. ;-----------------------------------------------------------------------------
  238. uglobal
  239. int13_regs_in   rb sizeof.v86_regs
  240. int13_regs_out  rb sizeof.v86_regs
  241. endg
  242. ;-----------------------------------------------------------------------------
  243. align 4
  244. int13_call:
  245. ; Because this code uses fixed addresses,
  246. ; it can not be run simultaniously by many threads.
  247. ; In current implementation it is protected by common mutex 'ide_status'
  248.         mov     word [OS_BASE + 510h], 10h             ; packet length
  249.         mov     word [OS_BASE + 512h], cx              ; number of sectors
  250.         mov     dword [OS_BASE + 514h], 9A000000h      ; buffer 9A00:0000
  251.         mov     dword [OS_BASE + 518h], eax
  252.         and     dword [OS_BASE + 51Ch], 0
  253.         push    ebx ecx esi edi
  254.         mov     ebx, int13_regs_in
  255.         mov     edi, ebx
  256.         mov     ecx, sizeof.v86_regs/4
  257.         xor     eax, eax
  258.         rep stosd
  259.         mov     byte [ebx+v86_regs.eax+1], dl
  260.         mov     eax, [hdpos]
  261.         lea     eax, [BiosDisksData+(eax-80h)*4]
  262.         mov     dl, [eax]
  263.         mov     byte [ebx+v86_regs.edx], dl
  264.         movzx   edx, byte [eax+1]
  265. ;        mov     dl, 5
  266.         test    edx, edx
  267.         jnz     .hasirq
  268.         dec     edx
  269.         jmp     @f
  270. .hasirq:
  271.         pushad
  272.         stdcall enable_irq, edx
  273.         popad
  274. @@:
  275.         mov     word [ebx+v86_regs.esi], 510h
  276.         mov     word [ebx+v86_regs.ss], 9000h
  277.         mov     word [ebx+v86_regs.esp], 0A000h
  278.         mov     word [ebx+v86_regs.eip], 500h
  279.         mov     [ebx+v86_regs.eflags], 20200h
  280.         mov     esi, [sys_v86_machine]
  281.         mov     ecx, 0x502
  282.         push    fs
  283.         call    v86_start
  284.         pop     fs
  285.         and     [bios_hdpos], 0
  286.         pop     edi esi ecx ebx
  287.         movzx   edx, byte [OS_BASE + 512h]
  288.         test    byte [int13_regs_out+v86_regs.eflags], 1
  289.         jnz     @f
  290.         mov     edx, ecx
  291. @@:
  292.         ret
  293. ; \end{diamond}
  294.