Subversion Repositories Kolibri OS

Rev

Rev 5569 | Rev 6016 | Go to most recent revision | 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: 6014 $
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
34
;-----------------------------------------------------------------
3742 clevermous 35
proc bd_read_interface stdcall uses edi, \
36
        userdata, buffer, startsector:qword, numsectors
37
        ; userdata = old [hdpos] = 80h + index in NumBiosDisks
38
        ; buffer = pointer to buffer for data
39
        ; startsector = 64-bit start sector
40
        ; numsectors = pointer to number of sectors on input,
41
        ;  must be filled with number of sectors really read
42
locals
43
sectors_todo    dd      ?
44
endl
45
; 1. Initialize number of sectors: get number of requested sectors
46
; and say that no sectors were read yet.
47
        mov     ecx, [numsectors]
48
        mov     eax, [ecx]
49
        mov     dword [ecx], 0
50
        mov     [sectors_todo], eax
51
; 2. Acquire the global lock.
52
        mov     ecx, ide_mutex
53
        call    mutex_lock
54
; 3. Convert parameters to the form suitable for worker procedures.
55
; Underlying procedures do not know about 64-bit sectors.
56
; Worker procedures use global variables and edi for [buffer].
57
        cmp     dword [startsector+4], 0
58
        jnz     .fail
59
        and     [hd_error], 0
60
        mov     eax, [userdata]
61
        mov     [hdpos], eax
62
        mov     eax, dword [startsector]
63
        mov     edi, [buffer]
64
; 4. Worker procedures take one sectors per time, so loop over all sectors to read.
65
.sectors_loop:
66
        call    bd_read
67
        cmp     [hd_error], 0
68
        jnz     .fail
69
        mov     ecx, [numsectors]
70
        inc     dword [ecx]     ; one more sector is read
71
        dec     [sectors_todo]
72
        jz      .done
73
        inc     eax
74
        jnz     .sectors_loop
75
; 5. Loop is done, either due to error or because everything is done.
76
; Release the global lock and return the corresponding status.
77
.fail:
78
        mov     ecx, ide_mutex
79
        call    mutex_unlock
80
        or      eax, -1
81
        ret
82
.done:
83
        mov     ecx, ide_mutex
84
        call    mutex_unlock
85
        xor     eax, eax
86
        ret
87
endp
5569 Pathoswith 88
;-----------------------------------------------------------------
3742 clevermous 89
proc bd_write_interface stdcall uses esi edi, \
90
        userdata, buffer, startsector:qword, numsectors
91
        ; userdata = old [hdpos] = 80h + index in NumBiosDisks
92
        ; buffer = pointer to buffer with data
93
        ; startsector = 64-bit start sector
94
        ; numsectors = pointer to number of sectors on input,
95
        ;  must be filled with number of sectors really written
96
locals
97
sectors_todo    dd      ?
98
endl
99
; 1. Initialize number of sectors: get number of requested sectors
100
; and say that no sectors were read yet.
101
        mov     ecx, [numsectors]
102
        mov     eax, [ecx]
103
        mov     dword [ecx], 0
104
        mov     [sectors_todo], eax
105
; 2. Acquire the global lock.
106
        mov     ecx, ide_mutex
107
        call    mutex_lock
108
; 3. Convert parameters to the form suitable for worker procedures.
109
; Underlying procedures do not know about 64-bit sectors.
110
; Worker procedures use global variables and esi for [buffer].
111
        cmp     dword [startsector+4], 0
112
        jnz     .fail
113
        and     [hd_error], 0
114
        mov     eax, [userdata]
115
        mov     [hdpos], eax
116
        mov     esi, [buffer]
117
        lea     edi, [startsector]
118
        mov     [cache_chain_ptr], edi
119
; 4. Worker procedures take max 16 sectors per time,
120
; loop until all sectors will be processed.
121
.sectors_loop:
122
        mov     ecx, 16
123
        cmp     ecx, [sectors_todo]
124
        jbe     @f
125
        mov     ecx, [sectors_todo]
126
@@:
127
        mov     [cache_chain_size], cl
128
        call    bd_write_cache_chain
129
        cmp     [hd_error], 0
130
        jnz     .fail
131
        movzx   ecx, [cache_chain_size]
132
        mov     eax, [numsectors]
133
        add     [eax], ecx
134
        sub     [sectors_todo], ecx
135
        jz      .done
136
        add     [edi], ecx
137
        jc      .fail
138
        shl     ecx, 9
139
        add     esi, ecx
140
        jmp     .sectors_loop
141
; 5. Loop is done, either due to error or because everything is done.
142
; Release the global lock and return the corresponding status.
143
.fail:
144
        mov     ecx, ide_mutex
145
        call    mutex_unlock
146
        or      eax, -1
147
        ret
148
.done:
149
        mov     ecx, ide_mutex
150
        call    mutex_unlock
151
        xor     eax, eax
152
        ret
153
endp
5569 Pathoswith 154
;-----------------------------------------------------------------
3742 clevermous 155
; This is a stub.
156
proc bd_querymedia stdcall, hd_data, mediainfo
157
        mov     eax, [mediainfo]
158
        mov     [eax+DISKMEDIAINFO.Flags], 0
159
        mov     [eax+DISKMEDIAINFO.SectorSize], 512
160
        or      dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF
161
        or      dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
162
        xor     eax, eax
163
        ret
164
endp
5569 Pathoswith 165
;-----------------------------------------------------------------
2288 clevermous 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)
3742 clevermous 182
        push    ecx esi
2288 clevermous 183
        mov     esi, eax
184
        mov     ecx, 512/4
185
        cld
186
        rep movsd
3742 clevermous 187
        pop     esi ecx
2288 clevermous 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:
6014 clevermous 210
        pop     edx
211
        pop     eax
2288 clevermous 212
        mov     [hd_error], 1
213
        jmp     hd_read_error
5569 Pathoswith 214
;-----------------------------------------------------------------
2288 clevermous 215
bd_write_cache_chain:
216
        pusha
217
        mov     edi, OS_BASE + 0x9A000
218
        movzx   ecx, [cache_chain_size]
219
        push    ecx
220
        shl     ecx, 9-2
221
        rep movsd
222
        pop     ecx
223
        mov     dl, 43h
224
        mov     eax, [cache_chain_ptr]
225
        mov     eax, [eax]
226
        call    int13_call
227
        test    eax, eax
228
        jnz     .v86err
229
        cmp     edx, ecx
230
        jnz     .writeerr
231
        popa
232
        ret
233
.v86err:
234
.writeerr:
235
        popa
236
        mov     [hd_error], 1
237
        jmp     hd_write_error
5569 Pathoswith 238
;-----------------------------------------------------------------
2288 clevermous 239
int13_call:
240
; Because this code uses fixed addresses,
241
; it can not be run simultaniously by many threads.
3742 clevermous 242
; In current implementation it is protected by common mutex 'ide_status'
5569 Pathoswith 243
        mov     word [OS_BASE + 510h], 10h          ; packet length
244
        mov     word [OS_BASE + 512h], cx           ; number of sectors
245
        mov     dword [OS_BASE + 514h], 9A000000h   ; buffer 9A00:0000
2288 clevermous 246
        mov     dword [OS_BASE + 518h], eax
247
        and     dword [OS_BASE + 51Ch], 0
248
        push    ebx ecx esi edi
249
        mov     ebx, int13_regs_in
250
        mov     edi, ebx
2384 hidnplayr 251
        mov     ecx, sizeof.v86_regs/4
2288 clevermous 252
        xor     eax, eax
253
        rep stosd
254
        mov     byte [ebx+v86_regs.eax+1], dl
255
        mov     eax, [hdpos]
256
        lea     eax, [BiosDisksData+(eax-80h)*4]
257
        mov     dl, [eax]
258
        mov     byte [ebx+v86_regs.edx], dl
259
        movzx   edx, byte [eax+1]
260
;        mov     dl, 5
261
        test    edx, edx
262
        jnz     .hasirq
263
        dec     edx
264
        jmp     @f
265
.hasirq:
266
        pushad
267
        stdcall enable_irq, edx
268
        popad
269
@@:
270
        mov     word [ebx+v86_regs.esi], 510h
271
        mov     word [ebx+v86_regs.ss], 9000h
272
        mov     word [ebx+v86_regs.esp], 0A000h
273
        mov     word [ebx+v86_regs.eip], 500h
274
        mov     [ebx+v86_regs.eflags], 20200h
275
        mov     esi, [sys_v86_machine]
276
        mov     ecx, 0x502
277
        push    fs
278
        call    v86_start
279
        pop     fs
280
        and     [bios_hdpos], 0
281
        pop     edi esi ecx ebx
282
        movzx   edx, byte [OS_BASE + 512h]
283
        test    byte [int13_regs_out+v86_regs.eflags], 1
284
        jnz     @f
285
        mov     edx, ecx
286
@@:
287
        ret