Subversion Repositories Kolibri OS

Rev

Rev 6016 | Details | Compare with Previous | Last modification | View Log | RSS feed

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