Rev 3712 | Rev 3762 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3712 | Rev 3742 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 7... | Line 7... | ||
7 | 7 | ||
Line 8... | Line 8... | ||
8 | $Revision: 3712 $ |
8 | $Revision: 3742 $ |
9 | 9 | ||
10 | 10 | ||
11 | ; Low-level driver for HDD access |
11 | ; Low-level driver for HDD access |
12 | ; DMA support by Mario79 |
12 | ; DMA support by Mario79 |
13 | ; Access through BIOS by diamond |
13 | ; Access through BIOS by diamond |
14 | ; LBA48 support by Mario79 |
- | |
15 | ;----------------------------------------------------------------------------- |
- | |
16 | align 4 |
- | |
17 | hd_read: |
- | |
18 | ;----------------------------------------------------------- |
- | |
19 | ; input : eax = block to read |
14 | ; LBA48 support by Mario79 |
20 | ; ebx = destination |
- | |
21 | ;----------------------------------------------------------- |
- | |
22 | and [hd_error], 0 |
- | |
23 | push ecx esi edi ; scan cache |
15 | ;----------------------------------------------------------------------------- |
24 | - | ||
25 | call calculate_cache |
16 | struct HD_DATA |
26 | add esi, 8 |
- | |
27 | 17 | hdbase dd ? |
|
28 | mov edi, 1 |
- | |
29 | - | ||
Line -... | Line 18... | ||
- | 18 | hdid dd ? |
|
- | 19 | hdpos dd ? |
|
- | 20 | ends |
|
- | 21 | ||
30 | hdreadcache: |
22 | iglobal |
- | 23 | align 4 |
|
- | 24 | ide_callbacks: |
|
- | 25 | dd ide_callbacks.end - ide_callbacks ; strucsize |
|
31 | cmp dword [esi+4], 0 ; empty |
26 | dd 0 ; no close function |
- | 27 | dd 0 ; no closemedia function |
|
- | 28 | dd ide_querymedia |
|
- | 29 | dd ide_read |
|
- | 30 | dd ide_write |
|
- | 31 | dd 0 ; no flush function |
|
- | 32 | dd 0 ; use default cache size |
|
- | 33 | .end: |
|
- | 34 | ||
- | 35 | bd_callbacks: |
|
- | 36 | dd bd_callbacks.end - bd_callbacks ; strucsize |
|
- | 37 | dd 0 ; no close function |
|
- | 38 | dd 0 ; no closemedia function |
|
- | 39 | dd bd_querymedia |
|
- | 40 | dd bd_read_interface |
|
- | 41 | dd bd_write_interface |
|
- | 42 | dd 0 ; no flush function |
|
- | 43 | dd 0 ; use default cache size |
|
- | 44 | .end: |
|
- | 45 | ||
- | 46 | hd0_data HD_DATA ?, 0, 1 |
|
Line 32... | Line 47... | ||
32 | je nohdcache |
47 | hd1_data HD_DATA ?, 0x10, 2 |
33 | 48 | hd2_data HD_DATA ?, 0, 3 |
|
34 | cmp [esi], eax ; correct sector |
49 | hd3_data HD_DATA ?, 0x10, 4 |
35 | je yeshdcache |
50 | endg |
36 | 51 | ||
Line -... | Line 52... | ||
- | 52 | uglobal |
|
- | 53 | ide_mutex MUTEX |
|
- | 54 | ide_channel1_mutex MUTEX |
|
- | 55 | ide_channel2_mutex MUTEX |
|
- | 56 | endg |
|
- | 57 | ||
- | 58 | proc ide_read stdcall uses edi, \ |
|
- | 59 | hd_data, buffer, startsector:qword, numsectors |
|
- | 60 | ; hd_data = pointer to hd*_data |
|
- | 61 | ; buffer = pointer to buffer for data |
|
- | 62 | ; startsector = 64-bit start sector |
|
- | 63 | ; numsectors = pointer to number of sectors on input, |
|
- | 64 | ; must be filled with number of sectors really read |
|
- | 65 | locals |
|
- | 66 | sectors_todo dd ? |
|
- | 67 | channel_lock dd ? |
|
- | 68 | endl |
|
- | 69 | ; 1. Initialize number of sectors: get number of requested sectors |
|
- | 70 | ; and say that no sectors were read yet. |
|
- | 71 | mov ecx, [numsectors] |
|
- | 72 | mov eax, [ecx] |
|
- | 73 | mov dword [ecx], 0 |
|
- | 74 | mov [sectors_todo], eax |
|
- | 75 | ; 2. Acquire the global lock. |
|
- | 76 | mov ecx, ide_mutex |
|
- | 77 | call mutex_lock |
|
- | 78 | mov ecx, ide_channel2_mutex |
|
- | 79 | mov eax, [hd_data] |
|
- | 80 | cmp [eax+HD_DATA.hdbase], 0x1F0 |
|
- | 81 | jne .IDE_Channel_2 |
|
- | 82 | mov ecx, ide_channel1_mutex |
|
37 | nohdcache: |
83 | .IDE_Channel_2: |
- | 84 | mov [channel_lock], ecx |
|
38 | add esi, 8 |
85 | call mutex_lock |
39 | inc edi |
86 | ; 3. Convert parameters to the form suitable for worker procedures. |
- | 87 | ; Underlying procedures do not know about 64-bit sectors. |
|
- | 88 | ; Worker procedures use global variables and edi for [buffer]. |
|
- | 89 | cmp dword [startsector+4], 0 |
|
40 | dec ecx |
90 | jnz .fail |
- | 91 | and [hd_error], 0 |
|
41 | jnz hdreadcache |
92 | mov ecx, [hd_data] |
- | 93 | mov eax, [ecx+HD_DATA.hdbase] |
|
42 | 94 | mov [hdbase], eax |
|
- | 95 | mov eax, [ecx+HD_DATA.hdid] |
|
- | 96 | mov [hdid], eax |
|
43 | call find_empty_slot ; ret in edi |
97 | mov eax, [ecx+HD_DATA.hdpos] |
44 | cmp [hd_error], 0 |
98 | mov [hdpos], eax |
45 | jne return_01 |
99 | mov eax, dword [startsector] |
46 | ; Read through BIOS? |
100 | mov edi, [buffer] |
47 | cmp [hdpos], 0x80 |
101 | ; 4. Worker procedures take one sectors per time, so loop over all sectors to read. |
48 | jae .bios |
102 | .sectors_loop: |
49 | ; DMA read is permitted if [allow_dma_access]=1 or 2 |
103 | ; DMA read is permitted if [allow_dma_access]=1 or 2 |
50 | cmp [allow_dma_access], 2 |
104 | cmp [allow_dma_access], 2 |
51 | ja .nodma |
105 | ja .nodma |
52 | cmp [dma_hdd], 1 |
- | |
53 | jnz .nodma |
- | |
54 | call hd_read_dma |
- | |
55 | jmp @f |
106 | cmp [dma_hdd], 1 |
56 | .nodma: |
107 | jnz .nodma |
- | 108 | call hd_read_dma |
|
- | 109 | jmp @f |
|
- | 110 | .nodma: |
|
- | 111 | call hd_read_pio |
|
- | 112 | @@: |
|
- | 113 | cmp [hd_error], 0 |
|
57 | call hd_read_pio |
114 | jnz .fail |
- | 115 | mov ecx, [numsectors] |
|
- | 116 | inc dword [ecx] ; one more sector is read |
|
- | 117 | dec [sectors_todo] |
|
- | 118 | jz .done |
|
- | 119 | inc eax |
|
- | 120 | jnz .sectors_loop |
|
- | 121 | ; 5. Loop is done, either due to error or because everything is done. |
|
- | 122 | ; Release the global lock and return the corresponding status. |
|
- | 123 | .fail: |
|
58 | jmp @f |
124 | mov ecx, [channel_lock] |
- | 125 | call mutex_unlock |
|
59 | .bios: |
126 | mov ecx, ide_mutex |
60 | call bd_read |
127 | call mutex_unlock |
- | 128 | or eax, -1 |
|
- | 129 | ret |
|
- | 130 | .done: |
|
- | 131 | mov ecx, [channel_lock] |
|
Line -... | Line 132... | ||
- | 132 | call mutex_unlock |
|
- | 133 | mov ecx, ide_mutex |
|
- | 134 | call mutex_unlock |
|
- | 135 | xor eax, eax |
|
- | 136 | ret |
|
- | 137 | endp |
|
- | 138 | ||
- | 139 | proc ide_write stdcall uses esi edi, \ |
|
- | 140 | hd_data, buffer, startsector:qword, numsectors |
|
- | 141 | ; hd_data = pointer to hd*_data |
|
- | 142 | ; buffer = pointer to buffer with data |
|
- | 143 | ; startsector = 64-bit start sector |
|
- | 144 | ; numsectors = pointer to number of sectors on input, |
|
61 | @@: |
145 | ; must be filled with number of sectors really written |
- | 146 | locals |
|
- | 147 | sectors_todo dd ? |
|
- | 148 | channel_lock dd ? |
|
- | 149 | endl |
|
- | 150 | ; 1. Initialize number of sectors: get number of requested sectors |
|
- | 151 | ; and say that no sectors were read yet. |
|
- | 152 | mov ecx, [numsectors] |
|
- | 153 | mov eax, [ecx] |
|
- | 154 | mov dword [ecx], 0 |
|
- | 155 | mov [sectors_todo], eax |
|
- | 156 | ; 2. Acquire the global lock. |
|
- | 157 | mov ecx, ide_mutex |
|
- | 158 | call mutex_lock |
|
- | 159 | mov ecx, ide_channel2_mutex |
|
- | 160 | mov eax, [hd_data] |
|
- | 161 | cmp [eax+HD_DATA.hdbase], 0x1F0 |
|
- | 162 | jne .IDE_Channel_2 |
|
- | 163 | mov ecx, ide_channel1_mutex |
|
- | 164 | .IDE_Channel_2: |
|
- | 165 | mov [channel_lock], ecx |
|
- | 166 | call mutex_lock |
|
62 | cmp [hd_error], 0 |
167 | ; 3. Convert parameters to the form suitable for worker procedures. |
- | 168 | ; Underlying procedures do not know about 64-bit sectors. |
|
- | 169 | ; Worker procedures use global variables and esi for [buffer]. |
|
- | 170 | cmp dword [startsector+4], 0 |
|
- | 171 | jnz .fail |
|
- | 172 | and [hd_error], 0 |
|
- | 173 | mov ecx, [hd_data] |
|
- | 174 | mov eax, [ecx+HD_DATA.hdbase] |
|
- | 175 | mov [hdbase], eax |
|
- | 176 | mov eax, [ecx+HD_DATA.hdid] |
|
- | 177 | mov [hdid], eax |
|
- | 178 | mov eax, [ecx+HD_DATA.hdpos] |
|
- | 179 | mov [hdpos], eax |
|
- | 180 | mov esi, [buffer] |
|
- | 181 | lea edi, [startsector] |
|
- | 182 | mov [cache_chain_ptr], edi |
|
- | 183 | ; 4. Worker procedures take max 16 sectors per time, |
|
- | 184 | ; loop until all sectors will be processed. |
|
- | 185 | .sectors_loop: |
|
- | 186 | mov ecx, 16 |
|
- | 187 | cmp ecx, [sectors_todo] |
|
- | 188 | jbe @f |
|
- | 189 | mov ecx, [sectors_todo] |
|
- | 190 | @@: |
|
- | 191 | mov [cache_chain_size], cl |
|
- | 192 | ; DMA write is permitted only if [allow_dma_access]=1 |
|
- | 193 | cmp [allow_dma_access], 2 |
|
- | 194 | jae .nodma |
|
- | 195 | cmp [dma_hdd], 1 |
|
- | 196 | jnz .nodma |
|
- | 197 | call cache_write_dma |
|
- | 198 | jmp .common |
|
- | 199 | .nodma: |
|
- | 200 | mov [cache_chain_size], 1 |
|
- | 201 | call cache_write_pio |
|
- | 202 | .common: |
|
- | 203 | cmp [hd_error], 0 |
|
- | 204 | jnz .fail |
|
- | 205 | movzx ecx, [cache_chain_size] |
|
- | 206 | mov eax, [numsectors] |
|
- | 207 | add [eax], ecx |
|
- | 208 | sub [sectors_todo], ecx |
|
- | 209 | jz .done |
|
- | 210 | add [edi], ecx |
|
- | 211 | jc .fail |
|
- | 212 | shl ecx, 9 |
|
- | 213 | add esi, ecx |
|
- | 214 | jmp .sectors_loop |
|
- | 215 | ; 5. Loop is done, either due to error or because everything is done. |
|
- | 216 | ; Release the global lock and return the corresponding status. |
|
- | 217 | .fail: |
|
- | 218 | mov ecx, [channel_lock] |
|
- | 219 | call mutex_unlock |
|
- | 220 | mov ecx, ide_mutex |
|
- | 221 | call mutex_unlock |
|
- | 222 | or eax, -1 |
|
- | 223 | ret |
|
- | 224 | .done: |
|
Line 63... | Line 225... | ||
63 | jne return_01 |
225 | mov ecx, [channel_lock] |
- | 226 | call mutex_unlock |
|
64 | 227 | mov ecx, ide_mutex |
|
- | 228 | call mutex_unlock |
|
- | 229 | xor eax, eax |
|
- | 230 | ret |
|
- | 231 | endp |
|
65 | call calculate_cache_1 |
232 | |
- | 233 | ; This is a stub. |
|
- | 234 | proc ide_querymedia stdcall, hd_data, mediainfo |
|
Line -... | Line 235... | ||
- | 235 | mov eax, [mediainfo] |
|
- | 236 | mov [eax+DISKMEDIAINFO.Flags], 0 |
|
- | 237 | mov [eax+DISKMEDIAINFO.SectorSize], 512 |
|
- | 238 | or dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF |
|
- | 239 | or dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF |
|
- | 240 | xor eax, eax |
|
- | 241 | ret |
|
- | 242 | endp |
|
- | 243 | ||
- | 244 | proc bd_read_interface stdcall uses edi, \ |
|
- | 245 | userdata, buffer, startsector:qword, numsectors |
|
- | 246 | ; userdata = old [hdpos] = 80h + index in NumBiosDisks |
|
- | 247 | ; buffer = pointer to buffer for data |
|
- | 248 | ; startsector = 64-bit start sector |
|
- | 249 | ; numsectors = pointer to number of sectors on input, |
|
- | 250 | ; must be filled with number of sectors really read |
|
- | 251 | locals |
|
- | 252 | sectors_todo dd ? |
|
- | 253 | endl |
|
- | 254 | ; 1. Initialize number of sectors: get number of requested sectors |
|
- | 255 | ; and say that no sectors were read yet. |
|
- | 256 | mov ecx, [numsectors] |
|
- | 257 | mov eax, [ecx] |
|
- | 258 | mov dword [ecx], 0 |
|
- | 259 | mov [sectors_todo], eax |
|
- | 260 | ; 2. Acquire the global lock. |
|
- | 261 | mov ecx, ide_mutex |
|
- | 262 | call mutex_lock |
|
- | 263 | ; 3. Convert parameters to the form suitable for worker procedures. |
|
- | 264 | ; Underlying procedures do not know about 64-bit sectors. |
|
- | 265 | ; Worker procedures use global variables and edi for [buffer]. |
|
- | 266 | cmp dword [startsector+4], 0 |
|
- | 267 | jnz .fail |
|
- | 268 | and [hd_error], 0 |
|
- | 269 | mov eax, [userdata] |
|
- | 270 | mov [hdpos], eax |
|
- | 271 | mov eax, dword [startsector] |
|
- | 272 | mov edi, [buffer] |
|
66 | lea esi, [edi*8+esi] |
273 | ; 4. Worker procedures take one sectors per time, so loop over all sectors to read. |
- | 274 | .sectors_loop: |
|
- | 275 | call bd_read |
|
- | 276 | cmp [hd_error], 0 |
|
- | 277 | jnz .fail |
|
- | 278 | mov ecx, [numsectors] |
|
67 | 279 | inc dword [ecx] ; one more sector is read |
|
68 | mov [esi], eax ; sector number |
280 | dec [sectors_todo] |
- | 281 | jz .done |
|
- | 282 | inc eax |
|
- | 283 | jnz .sectors_loop |
|
- | 284 | ; 5. Loop is done, either due to error or because everything is done. |
|
69 | mov dword [esi+4], 1 ; hd read - mark as same as in hd |
285 | ; Release the global lock and return the corresponding status. |
- | 286 | .fail: |
|
- | 287 | mov ecx, ide_mutex |
|
Line -... | Line 288... | ||
- | 288 | call mutex_unlock |
|
- | 289 | or eax, -1 |
|
- | 290 | ret |
|
- | 291 | .done: |
|
- | 292 | mov ecx, ide_mutex |
|
- | 293 | call mutex_unlock |
|
- | 294 | xor eax, eax |
|
- | 295 | ret |
|
- | 296 | endp |
|
- | 297 | ||
- | 298 | proc bd_write_interface stdcall uses esi edi, \ |
|
- | 299 | userdata, buffer, startsector:qword, numsectors |
|
- | 300 | ; userdata = old [hdpos] = 80h + index in NumBiosDisks |
|
70 | 301 | ; buffer = pointer to buffer with data |
|
- | 302 | ; startsector = 64-bit start sector |
|
- | 303 | ; numsectors = pointer to number of sectors on input, |
|
- | 304 | ; must be filled with number of sectors really written |
|
- | 305 | locals |
|
- | 306 | sectors_todo dd ? |
|
- | 307 | endl |
|
- | 308 | ; 1. Initialize number of sectors: get number of requested sectors |
|
- | 309 | ; and say that no sectors were read yet. |
|
- | 310 | mov ecx, [numsectors] |
|
- | 311 | mov eax, [ecx] |
|
- | 312 | mov dword [ecx], 0 |
|
- | 313 | mov [sectors_todo], eax |
|
- | 314 | ; 2. Acquire the global lock. |
|
- | 315 | mov ecx, ide_mutex |
|
- | 316 | call mutex_lock |
|
- | 317 | ; 3. Convert parameters to the form suitable for worker procedures. |
|
- | 318 | ; Underlying procedures do not know about 64-bit sectors. |
|
- | 319 | ; Worker procedures use global variables and esi for [buffer]. |
|
- | 320 | cmp dword [startsector+4], 0 |
|
71 | yeshdcache: |
321 | jnz .fail |
- | 322 | and [hd_error], 0 |
|
- | 323 | mov eax, [userdata] |
|
- | 324 | mov [hdpos], eax |
|
- | 325 | mov esi, [buffer] |
|
- | 326 | lea edi, [startsector] |
|
- | 327 | mov [cache_chain_ptr], edi |
|
- | 328 | ; 4. Worker procedures take max 16 sectors per time, |
|
- | 329 | ; loop until all sectors will be processed. |
|
- | 330 | .sectors_loop: |
|
- | 331 | mov ecx, 16 |
|
- | 332 | cmp ecx, [sectors_todo] |
|
- | 333 | jbe @f |
|
- | 334 | mov ecx, [sectors_todo] |
|
- | 335 | @@: |
|
- | 336 | mov [cache_chain_size], cl |
|
- | 337 | call bd_write_cache_chain |
|
- | 338 | cmp [hd_error], 0 |
|
- | 339 | jnz .fail |
|
- | 340 | movzx ecx, [cache_chain_size] |
|
- | 341 | mov eax, [numsectors] |
|
- | 342 | add [eax], ecx |
|
- | 343 | sub [sectors_todo], ecx |
|
- | 344 | jz .done |
|
- | 345 | add [edi], ecx |
|
72 | mov esi, edi |
346 | jc .fail |
- | 347 | shl ecx, 9 |
|
73 | shl esi, 9 |
348 | add esi, ecx |
- | 349 | jmp .sectors_loop |
|
- | 350 | ; 5. Loop is done, either due to error or because everything is done. |
|
- | 351 | ; Release the global lock and return the corresponding status. |
|
- | 352 | .fail: |
|
Line 74... | Line 353... | ||
74 | 353 | mov ecx, ide_mutex |
|
- | 354 | call mutex_unlock |
|
- | 355 | or eax, -1 |
|
- | 356 | ret |
|
- | 357 | .done: |
|
- | 358 | mov ecx, ide_mutex |
|
- | 359 | call mutex_unlock |
|
75 | push eax |
360 | xor eax, eax |
76 | call calculate_cache_2 |
361 | ret |
- | 362 | endp |
|
- | 363 | ||
77 | add esi, eax |
364 | ; This is a stub. |
78 | pop eax |
365 | proc bd_querymedia stdcall, hd_data, mediainfo |
- | 366 | mov eax, [mediainfo] |
|
- | 367 | mov [eax+DISKMEDIAINFO.Flags], 0 |
|
79 | 368 | mov [eax+DISKMEDIAINFO.SectorSize], 512 |
|
80 | mov edi, ebx |
369 | or dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF |
Line 81... | Line 370... | ||
81 | mov ecx, 512/4 |
370 | or dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF |
82 | cld |
371 | xor eax, eax |
Line 182... | Line 471... | ||
182 | cmp [hd_error], 0 |
471 | cmp [hd_error], 0 |
183 | jne hd_read_error |
472 | jne hd_read_error |
Line 184... | Line 473... | ||
184 | 473 | ||
185 | pushfd |
474 | pushfd |
186 | cli |
- | |
187 | push edi |
- | |
188 | shl edi, 9 |
- | |
189 | - | ||
190 | push eax |
- | |
191 | call calculate_cache_2 |
- | |
192 | add edi, eax |
- | |
Line 193... | Line 475... | ||
193 | pop eax |
475 | cli |
194 | 476 | ||
195 | mov ecx, 256 |
477 | mov ecx, 256 |
196 | mov edx, [hdbase] |
478 | mov edx, [hdbase] |
197 | cld |
- | |
198 | rep insw |
479 | cld |
Line 199... | Line 480... | ||
199 | pop edi |
480 | rep insw |
200 | popfd |
481 | popfd |
201 | 482 | ||
202 | pop edx eax |
483 | pop edx eax |
203 | ret |
- | |
204 | ;----------------------------------------------------------------------------- |
- | |
205 | align 4 |
- | |
206 | hd_write: |
- | |
207 | ;----------------------------------------------------------- |
- | |
208 | ; input : eax = block |
- | |
209 | ; ebx = pointer to memory |
- | |
210 | ;----------------------------------------------------------- |
- | |
211 | push ecx esi edi |
- | |
212 | - | ||
213 | ; check if the cache already has the sector and overwrite it |
- | |
214 | call calculate_cache |
- | |
215 | add esi, 8 |
- | |
216 | mov edi, 1 |
- | |
217 | - | ||
218 | hdwritecache: |
- | |
219 | cmp dword [esi+4], 0 ; if cache slot is empty |
- | |
220 | je not_in_cache_write |
- | |
221 | - | ||
222 | cmp [esi], eax ; if the slot has the sector |
- | |
223 | je yes_in_cache_write |
- | |
224 | - | ||
225 | not_in_cache_write: |
- | |
226 | add esi, 8 |
- | |
227 | inc edi |
- | |
228 | dec ecx |
- | |
229 | jnz hdwritecache |
- | |
230 | - | ||
231 | ; sector not found in cache |
- | |
232 | ; write the block to a new location |
- | |
233 | call find_empty_slot ; ret in edi |
- | |
234 | cmp [hd_error], 0 |
- | |
235 | jne hd_write_access_denied |
- | |
236 | - | ||
237 | call calculate_cache_1 |
- | |
238 | lea esi, [edi*8+esi] |
- | |
239 | mov [esi], eax ; sector number |
- | |
240 | - | ||
241 | yes_in_cache_write: |
- | |
242 | mov dword [esi+4], 2 ; write - differs from hd |
- | |
243 | - | ||
244 | shl edi, 9 |
- | |
245 | - | ||
246 | push eax |
- | |
247 | call calculate_cache_2 |
- | |
248 | add edi, eax |
- | |
249 | pop eax |
- | |
250 | - | ||
251 | mov esi, ebx |
- | |
252 | mov ecx, 512/4 |
- | |
253 | cld |
- | |
254 | rep movsd ; move data |
484 | ret |
255 | - | ||
256 | hd_write_access_denied: |
- | |
257 | pop edi esi ecx |
- | |
258 | ret |
485 | ;----------------------------------------------------------------------------- |
259 | ;----------------------------------------------------------------------------- |
486 | align 4 |
260 | align 4 |
487 | ; edi -> sector, esi -> data |
261 | cache_write_pio: |
488 | cache_write_pio: |
262 | ; Select the desired drive |
489 | ; Select the desired drive |
Line 269... | Line 496... | ||
269 | call wait_for_hd_idle |
496 | call wait_for_hd_idle |
270 | cmp [hd_error], 0 |
497 | cmp [hd_error], 0 |
271 | jne hd_write_error |
498 | jne hd_write_error |
Line 272... | Line 499... | ||
272 | 499 | ||
273 | ; ATA with 28 or 48 bit for sector number? |
500 | ; ATA with 28 or 48 bit for sector number? |
274 | mov eax, [esi] |
501 | mov eax, [edi] |
275 | cmp eax, 0x10000000 |
502 | cmp eax, 0x10000000 |
276 | jae .lba48 |
503 | jae .lba48 |
277 | ;-------------------------------------- |
504 | ;-------------------------------------- |
278 | .lba28: |
505 | .lba28: |
Line 284... | Line 511... | ||
284 | out dx, al ; ATA Features регистр "особенностей" |
511 | out dx, al ; ATA Features регистр "особенностей" |
285 | inc edx |
512 | inc edx |
286 | inc eax |
513 | inc eax |
287 | out dx, al ; ATA Sector Counter счётчик секторов |
514 | out dx, al ; ATA Sector Counter счётчик секторов |
288 | inc edx |
515 | inc edx |
289 | mov eax, [esi] ; eax = sector to write |
516 | mov eax, [edi] ; eax = sector to write |
290 | out dx, al ; LBA Low LBA (7:0) |
517 | out dx, al ; LBA Low LBA (7:0) |
291 | shr eax, 8 |
518 | shr eax, 8 |
292 | inc edx |
519 | inc edx |
293 | out dx, al ; LBA Mid LBA (15:8) |
520 | out dx, al ; LBA Mid LBA (15:8) |
294 | shr eax, 8 |
521 | shr eax, 8 |
Line 317... | Line 544... | ||
317 | inc edx |
544 | inc edx |
318 | out dx, al ; Sector Count Previous Sector count (15:8) |
545 | out dx, al ; Sector Count Previous Sector count (15:8) |
319 | inc eax |
546 | inc eax |
320 | out dx, al ; Sector Count Current Sector count (7:0) |
547 | out dx, al ; Sector Count Current Sector count (7:0) |
321 | inc edx |
548 | inc edx |
322 | mov eax, [esi] |
549 | mov eax, [edi] |
323 | rol eax, 8 |
550 | rol eax, 8 |
324 | out dx, al ; LBA Low Previous LBA (31:24) |
551 | out dx, al ; LBA Low Previous LBA (31:24) |
325 | xor eax, eax ; because only 32 bit cache |
552 | xor eax, eax ; because only 32 bit cache |
326 | inc edx |
553 | inc edx |
327 | out dx, al ; LBA Mid Previous LBA (39:32) |
554 | out dx, al ; LBA Mid Previous LBA (39:32) |
328 | inc edx |
555 | inc edx |
329 | out dx, al ; LBA High Previous LBA (47:40) |
556 | out dx, al ; LBA High Previous LBA (47:40) |
330 | sub edx, 2 |
557 | sub edx, 2 |
331 | mov eax, [esi] |
558 | mov eax, [edi] |
332 | out dx, al ; LBA Low Current LBA (7:0) |
559 | out dx, al ; LBA Low Current LBA (7:0) |
333 | shr eax, 8 |
560 | shr eax, 8 |
334 | inc edx |
561 | inc edx |
335 | out dx, al ; LBA Mid Current LBA (15:8) |
562 | out dx, al ; LBA Mid Current LBA (15:8) |
336 | shr eax, 8 |
563 | shr eax, 8 |
Line 353... | Line 580... | ||
353 | 580 | ||
Line 354... | Line 581... | ||
354 | push ecx esi |
581 | push ecx esi |
355 | 582 | ||
356 | pushfd |
- | |
357 | cli |
- | |
358 | mov esi, edi |
- | |
359 | shl esi, 9 |
- | |
360 | - | ||
361 | push eax |
- | |
362 | call calculate_cache_2 |
- | |
363 | add esi, eax |
- | |
364 | pop eax |
583 | pushfd |
365 | 584 | cli |
|
366 | mov ecx, 256 |
585 | mov ecx, 256 |
367 | mov edx, [hdbase] |
586 | mov edx, [hdbase] |
368 | cld |
587 | cld |
Line 603... | Line 822... | ||
603 | ja .notread |
822 | ja .notread |
604 | mov eax, [esp+4] |
823 | mov eax, [esp+4] |
605 | sub eax, [dma_cur_sector] |
824 | sub eax, [dma_cur_sector] |
606 | shl eax, 9 |
825 | shl eax, 9 |
607 | add eax, (OS_BASE+IDE_DMA) |
826 | add eax, (OS_BASE+IDE_DMA) |
608 | push ecx esi edi |
827 | push ecx esi |
609 | mov esi, eax |
828 | mov esi, eax |
610 | shl edi, 9 |
- | |
611 | - | ||
612 | push eax |
- | |
613 | call calculate_cache_2 |
- | |
614 | add edi, eax |
- | |
615 | pop eax |
- | |
Line 616... | Line 829... | ||
616 | 829 | ||
617 | mov ecx, 512/4 |
830 | mov ecx, 512/4 |
618 | cld |
831 | cld |
619 | rep movsd |
832 | rep movsd |
620 | pop edi esi ecx |
833 | pop esi ecx |
621 | pop edx |
834 | pop edx |
622 | pop eax |
835 | pop eax |
623 | ret |
836 | ret |
624 | .notread: |
837 | .notread: |
Line 764... | Line 977... | ||
764 | pop edx |
977 | pop edx |
765 | pop eax |
978 | pop eax |
766 | mov [dma_cur_sector], eax |
979 | mov [dma_cur_sector], eax |
767 | jmp hd_read_dma |
980 | jmp hd_read_dma |
768 | ;----------------------------------------------------------------------------- |
981 | ;----------------------------------------------------------------------------- |
769 | align 4 |
- | |
770 | write_cache_sector: |
- | |
771 | mov [cache_chain_size], 1 |
- | |
772 | mov [cache_chain_pos], edi |
- | |
773 | ;-------------------------------------- |
- | |
774 | align 4 |
- | |
775 | write_cache_chain: |
982 | cache_write_dma: |
776 | cmp [hdpos], 0x80 |
- | |
777 | jae bd_write_cache_chain |
- | |
778 | mov eax, [cache_chain_ptr] |
983 | mov eax, [cache_chain_ptr] |
779 | push esi |
984 | push esi |
780 | mov eax, IDE_descriptor_table |
985 | mov eax, IDE_descriptor_table |
781 | mov edx, eax |
986 | mov edx, eax |
782 | pusha |
987 | pusha |
783 | mov esi, [cache_chain_pos] |
- | |
784 | shl esi, 9 |
- | |
785 | call calculate_cache_2 |
- | |
786 | add esi, eax |
- | |
787 | mov edi, (OS_BASE+IDE_DMA) |
988 | mov edi, (OS_BASE+IDE_DMA) |
788 | mov dword [edx], IDE_DMA |
989 | mov dword [edx], IDE_DMA |
789 | movzx ecx, [cache_chain_size] |
990 | movzx ecx, [cache_chain_size] |
790 | shl ecx, 9 |
991 | shl ecx, 9 |
791 | mov word [edx+4], cx |
992 | mov word [edx+4], cx |
Line 963... | Line 1164... | ||
963 | cmp eax, edx |
1164 | cmp eax, edx |
964 | ja .notread |
1165 | ja .notread |
965 | sub eax, [bios_cur_sector] |
1166 | sub eax, [bios_cur_sector] |
966 | shl eax, 9 |
1167 | shl eax, 9 |
967 | add eax, (OS_BASE+0x9A000) |
1168 | add eax, (OS_BASE+0x9A000) |
968 | push ecx esi edi |
1169 | push ecx esi |
969 | mov esi, eax |
1170 | mov esi, eax |
970 | shl edi, 9 |
- | |
971 | - | ||
972 | push eax |
- | |
973 | call calculate_cache_2 |
- | |
974 | add edi, eax |
- | |
975 | pop eax |
- | |
976 | - | ||
977 | mov ecx, 512/4 |
1171 | mov ecx, 512/4 |
978 | cld |
1172 | cld |
979 | rep movsd |
1173 | rep movsd |
980 | pop edi esi ecx |
1174 | pop esi ecx |
981 | pop edx |
1175 | pop edx |
982 | pop eax |
1176 | pop eax |
983 | ret |
1177 | ret |
984 | .notread: |
1178 | .notread: |
985 | push ecx |
1179 | push ecx |
Line 1004... | Line 1198... | ||
1004 | jmp hd_read_error |
1198 | jmp hd_read_error |
1005 | ;----------------------------------------------------------------------------- |
1199 | ;----------------------------------------------------------------------------- |
1006 | align 4 |
1200 | align 4 |
1007 | bd_write_cache_chain: |
1201 | bd_write_cache_chain: |
1008 | pusha |
1202 | pusha |
1009 | mov esi, [cache_chain_pos] |
- | |
1010 | shl esi, 9 |
- | |
1011 | call calculate_cache_2 |
- | |
1012 | add esi, eax |
- | |
1013 | mov edi, OS_BASE + 0x9A000 |
1203 | mov edi, OS_BASE + 0x9A000 |
1014 | movzx ecx, [cache_chain_size] |
1204 | movzx ecx, [cache_chain_size] |
1015 | push ecx |
1205 | push ecx |
1016 | shl ecx, 9-2 |
1206 | shl ecx, 9-2 |
1017 | rep movsd |
1207 | rep movsd |
Line 1039... | Line 1229... | ||
1039 | ;----------------------------------------------------------------------------- |
1229 | ;----------------------------------------------------------------------------- |
1040 | align 4 |
1230 | align 4 |
1041 | int13_call: |
1231 | int13_call: |
1042 | ; Because this code uses fixed addresses, |
1232 | ; Because this code uses fixed addresses, |
1043 | ; it can not be run simultaniously by many threads. |
1233 | ; it can not be run simultaniously by many threads. |
1044 | ; In current implementation it is protected by common mutex 'hd1_status' |
1234 | ; In current implementation it is protected by common mutex 'ide_status' |
1045 | mov word [OS_BASE + 510h], 10h ; packet length |
1235 | mov word [OS_BASE + 510h], 10h ; packet length |
1046 | mov word [OS_BASE + 512h], cx ; number of sectors |
1236 | mov word [OS_BASE + 512h], cx ; number of sectors |
1047 | mov dword [OS_BASE + 514h], 9A000000h ; buffer 9A00:0000 |
1237 | mov dword [OS_BASE + 514h], 9A000000h ; buffer 9A00:0000 |
1048 | mov dword [OS_BASE + 518h], eax |
1238 | mov dword [OS_BASE + 518h], eax |
1049 | and dword [OS_BASE + 51Ch], 0 |
1239 | and dword [OS_BASE + 51Ch], 0 |
Line 1086... | Line 1276... | ||
1086 | jnz @f |
1276 | jnz @f |
1087 | mov edx, ecx |
1277 | mov edx, ecx |
1088 | @@: |
1278 | @@: |
1089 | ret |
1279 | ret |
1090 | ; \end{diamond} |
1280 | ; \end{diamond} |
1091 | ;----------------------------------------------------------------------------- |
- | |
1092 | align 4 |
- | |
1093 | reserve_hd1: |
- | |
1094 | cli |
- | |
1095 | cmp [hd1_status], 0 |
- | |
1096 | je reserve_ok1 |
- | |
1097 | - | ||
1098 | sti |
- | |
1099 | call change_task |
- | |
1100 | jmp reserve_hd1 |
- | |
1101 | - | ||
1102 | reserve_ok1: |
- | |
1103 | push eax |
- | |
1104 | mov eax, [CURRENT_TASK] |
- | |
1105 | shl eax, 5 |
- | |
1106 | mov eax, [eax+CURRENT_TASK+TASKDATA.pid] |
- | |
1107 | mov [hd1_status], eax |
- | |
1108 | pop eax |
- | |
1109 | sti |
- | |
1110 | ret |
- | |
1111 | ;----------------------------------------------------------------------------- |
- | |
1112 | uglobal |
- | |
1113 | hd_in_cache db ? |
- | |
1114 | endg |
- | |
1115 | ;----------------------------------------------------------------------------- |
- | |
1116 | align 4 |
- | |
1117 | reserve_hd_channel: |
- | |
1118 | ; BIOS disk accesses are protected with common mutex hd1_status |
- | |
1119 | ; This must be modified when hd1_status will not be valid! |
- | |
1120 | cmp [hdpos], 0x80 |
- | |
1121 | jae .ret |
- | |
1122 | cmp [hdbase], 0x1F0 |
- | |
1123 | jne .IDE_Channel_2 |
- | |
1124 | .IDE_Channel_1: |
- | |
1125 | cli |
- | |
1126 | cmp [IDE_Channel_1], 0 |
- | |
1127 | je .reserve_ok_1 |
- | |
1128 | sti |
- | |
1129 | call change_task |
- | |
1130 | jmp .IDE_Channel_1 |
- | |
1131 | .IDE_Channel_2: |
- | |
1132 | cli |
- | |
1133 | cmp [IDE_Channel_2], 0 |
- | |
1134 | je .reserve_ok_2 |
- | |
1135 | sti |
- | |
1136 | call change_task |
- | |
1137 | jmp .IDE_Channel_2 |
- | |
1138 | .reserve_ok_1: |
- | |
1139 | mov [IDE_Channel_1], 1 |
- | |
1140 | push eax |
- | |
1141 | mov al, 1 |
- | |
1142 | jmp @f |
- | |
1143 | .reserve_ok_2: |
- | |
1144 | mov [IDE_Channel_2], 1 |
- | |
1145 | push eax |
- | |
1146 | mov al, 3 |
- | |
1147 | @@: |
- | |
1148 | cmp [hdid], 1 |
- | |
1149 | sbb al, -1 |
- | |
1150 | mov [hd_in_cache], al |
- | |
1151 | pop eax |
- | |
1152 | sti |
- | |
1153 | .ret: |
- | |
1154 | ret |
- | |
1155 | ;----------------------------------------------------------------------------- |
- | |
1156 | free_hd_channel: |
- | |
1157 | ; see comment at reserve_hd_channel |
- | |
1158 | cmp [hdpos], 0x80 |
- | |
1159 | jae .ret |
- | |
1160 | cmp [hdbase], 0x1F0 |
- | |
1161 | jne .IDE_Channel_2 |
- | |
1162 | .IDE_Channel_1: |
- | |
1163 | mov [IDE_Channel_1], 0 |
- | |
1164 | .ret: |
- | |
1165 | ret |
- | |
1166 | .IDE_Channel_2: |
- | |
1167 | mov [IDE_Channel_2], 0 |
- | |
1168 | ret |
- | |
1169 | ;----------------------------------------------------------------------------- |
- |