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