Subversion Repositories Kolibri OS

Rev

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

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