Subversion Repositories Kolibri OS

Rev

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
;-----------------------------------------------------------------------------
-