Subversion Repositories Kolibri OS

Rev

Rev 5363 | Rev 6014 | 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: 5569 $
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:
210
        mov     [hd_error], 1
211
        jmp     hd_read_error
5569 Pathoswith 212
;-----------------------------------------------------------------
2288 clevermous 213
bd_write_cache_chain:
214
        pusha
215
        mov     edi, OS_BASE + 0x9A000
216
        movzx   ecx, [cache_chain_size]
217
        push    ecx
218
        shl     ecx, 9-2
219
        rep movsd
220
        pop     ecx
221
        mov     dl, 43h
222
        mov     eax, [cache_chain_ptr]
223
        mov     eax, [eax]
224
        call    int13_call
225
        test    eax, eax
226
        jnz     .v86err
227
        cmp     edx, ecx
228
        jnz     .writeerr
229
        popa
230
        ret
231
.v86err:
232
.writeerr:
233
        popa
234
        mov     [hd_error], 1
235
        jmp     hd_write_error
5569 Pathoswith 236
;-----------------------------------------------------------------
2288 clevermous 237
int13_call:
238
; Because this code uses fixed addresses,
239
; it can not be run simultaniously by many threads.
3742 clevermous 240
; In current implementation it is protected by common mutex 'ide_status'
5569 Pathoswith 241
        mov     word [OS_BASE + 510h], 10h          ; packet length
242
        mov     word [OS_BASE + 512h], cx           ; number of sectors
243
        mov     dword [OS_BASE + 514h], 9A000000h   ; buffer 9A00:0000
2288 clevermous 244
        mov     dword [OS_BASE + 518h], eax
245
        and     dword [OS_BASE + 51Ch], 0
246
        push    ebx ecx esi edi
247
        mov     ebx, int13_regs_in
248
        mov     edi, ebx
2384 hidnplayr 249
        mov     ecx, sizeof.v86_regs/4
2288 clevermous 250
        xor     eax, eax
251
        rep stosd
252
        mov     byte [ebx+v86_regs.eax+1], dl
253
        mov     eax, [hdpos]
254
        lea     eax, [BiosDisksData+(eax-80h)*4]
255
        mov     dl, [eax]
256
        mov     byte [ebx+v86_regs.edx], dl
257
        movzx   edx, byte [eax+1]
258
;        mov     dl, 5
259
        test    edx, edx
260
        jnz     .hasirq
261
        dec     edx
262
        jmp     @f
263
.hasirq:
264
        pushad
265
        stdcall enable_irq, edx
266
        popad
267
@@:
268
        mov     word [ebx+v86_regs.esi], 510h
269
        mov     word [ebx+v86_regs.ss], 9000h
270
        mov     word [ebx+v86_regs.esp], 0A000h
271
        mov     word [ebx+v86_regs.eip], 500h
272
        mov     [ebx+v86_regs.eflags], 20200h
273
        mov     esi, [sys_v86_machine]
274
        mov     ecx, 0x502
275
        push    fs
276
        call    v86_start
277
        pop     fs
278
        and     [bios_hdpos], 0
279
        pop     edi esi ecx ebx
280
        movzx   edx, byte [OS_BASE + 512h]
281
        test    byte [int13_regs_out+v86_regs.eflags], 1
282
        jnz     @f
283
        mov     edx, ecx
284
@@:
285
        ret