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