Rev 725 | Rev 820 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 725 | Rev 770 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2008. 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: 725 $ |
8 | $Revision: 770 $ |
9 | 9 | ||
10 | 10 | ||
11 | ; Low-level driver for HDD access |
11 | ; Low-level driver for HDD access |
12 | ; DMA support by Mario79 |
12 | ; DMA support by Mario79 |
13 | ; Access through BIOS by diamond |
13 | ; Access through BIOS by diamond |
14 | 14 | ||
15 | align 4 |
15 | align 4 |
16 | hd_read: |
16 | hd_read: |
17 | ;----------------------------------------------------------- |
17 | ;----------------------------------------------------------- |
18 | ; input : eax = block to read |
18 | ; input : eax = block to read |
19 | ; ebx = destination |
19 | ; ebx = destination |
20 | ;----------------------------------------------------------- |
20 | ;----------------------------------------------------------- |
21 | and [hd_error], 0 |
21 | and [hd_error], 0 |
22 | push ecx esi edi ; scan cache |
22 | push ecx esi edi ; scan cache |
23 | 23 | ||
24 | ; mov ecx,cache_max ; entries in cache |
24 | ; mov ecx,cache_max ; entries in cache |
25 | ; mov esi,HD_CACHE+8 |
25 | ; mov esi,HD_CACHE+8 |
26 | call calculate_cache |
26 | call calculate_cache |
27 | add esi,8 |
27 | add esi,8 |
28 | 28 | ||
29 | mov edi,1 |
29 | mov edi,1 |
30 | 30 | ||
31 | hdreadcache: |
31 | hdreadcache: |
32 | 32 | ||
33 | cmp dword [esi+4],0 ; empty |
33 | cmp dword [esi+4],0 ; empty |
34 | je nohdcache |
34 | je nohdcache |
35 | 35 | ||
36 | cmp [esi],eax ; correct sector |
36 | cmp [esi],eax ; correct sector |
37 | je yeshdcache |
37 | je yeshdcache |
38 | 38 | ||
39 | nohdcache: |
39 | nohdcache: |
40 | 40 | ||
41 | add esi,8 |
41 | add esi,8 |
42 | inc edi |
42 | inc edi |
43 | dec ecx |
43 | dec ecx |
44 | jnz hdreadcache |
44 | jnz hdreadcache |
45 | 45 | ||
46 | call find_empty_slot ; ret in edi |
46 | call find_empty_slot ; ret in edi |
47 | cmp [hd_error],0 |
47 | cmp [hd_error],0 |
48 | jne return_01 |
48 | jne return_01 |
49 | ; Read through BIOS? |
49 | ; Read through BIOS? |
50 | cmp [hdpos], 0x80 |
50 | cmp [hdpos], 0x80 |
51 | jae .bios |
51 | jae .bios |
52 | ; DMA read is permitted if [allow_dma_access]=1 or 2 |
52 | ; DMA read is permitted if [allow_dma_access]=1 or 2 |
53 | cmp [allow_dma_access], 2 |
53 | cmp [allow_dma_access], 2 |
54 | ja .nodma |
54 | ja .nodma |
55 | cmp [dma_hdd], 1 |
55 | cmp [dma_hdd], 1 |
56 | jnz .nodma |
56 | jnz .nodma |
57 | call hd_read_dma |
57 | call hd_read_dma |
58 | jmp @f |
58 | jmp @f |
59 | .nodma: |
59 | .nodma: |
60 | call hd_read_pio |
60 | call hd_read_pio |
61 | jmp @f |
61 | jmp @f |
62 | .bios: |
62 | .bios: |
63 | call bd_read |
63 | call bd_read |
64 | @@: |
64 | @@: |
65 | cmp [hd_error], 0 |
65 | cmp [hd_error], 0 |
66 | jne return_01 |
66 | jne return_01 |
67 | ; lea esi,[edi*8+HD_CACHE] |
67 | ; lea esi,[edi*8+HD_CACHE] |
68 | ; push eax |
68 | ; push eax |
69 | call calculate_cache_1 |
69 | call calculate_cache_1 |
70 | lea esi,[edi*8+esi] |
70 | lea esi,[edi*8+esi] |
71 | ; pop eax |
71 | ; pop eax |
72 | 72 | ||
73 | mov [esi],eax ; sector number |
73 | mov [esi],eax ; sector number |
74 | mov dword [esi+4],1 ; hd read - mark as same as in hd |
74 | mov dword [esi+4],1 ; hd read - mark as same as in hd |
75 | 75 | ||
76 | yeshdcache: |
76 | yeshdcache: |
77 | 77 | ||
78 | mov esi,edi |
78 | mov esi,edi |
79 | shl esi,9 |
79 | shl esi,9 |
80 | ; add esi,HD_CACHE+65536 |
80 | ; add esi,HD_CACHE+65536 |
81 | push eax |
81 | push eax |
82 | call calculate_cache_2 |
82 | call calculate_cache_2 |
83 | add esi,eax |
83 | add esi,eax |
84 | pop eax |
84 | pop eax |
85 | 85 | ||
86 | mov edi,ebx |
86 | mov edi,ebx |
87 | mov ecx,512/4 |
87 | mov ecx,512/4 |
88 | cld |
88 | cld |
89 | rep movsd ; move data |
89 | rep movsd ; move data |
90 | return_01: |
90 | return_01: |
91 | pop edi esi ecx |
91 | pop edi esi ecx |
92 | ret |
92 | ret |
93 | 93 | ||
94 | align 4 |
94 | align 4 |
95 | hd_read_pio: |
95 | hd_read_pio: |
96 | push eax edx |
96 | push eax edx |
97 | 97 | ||
98 | call wait_for_hd_idle |
98 | call wait_for_hd_idle |
99 | cmp [hd_error],0 |
99 | cmp [hd_error],0 |
100 | jne hd_read_error |
100 | jne hd_read_error |
101 | 101 | ||
102 | cli |
102 | cli |
103 | xor eax,eax |
103 | xor eax,eax |
104 | mov edx,[hdbase] |
104 | mov edx,[hdbase] |
105 | inc edx |
105 | inc edx |
106 | out dx,al ; ATAFeatures ॣ¨áâà "®á®¡¥®á⥩" |
106 | out dx,al ; ATAFeatures ॣ¨áâà "®á®¡¥®á⥩" |
107 | inc edx |
107 | inc edx |
108 | inc eax |
108 | inc eax |
109 | out dx,al ; ATASectorCount áçñâ稪 ᥪâ®à®¢ |
109 | out dx,al ; ATASectorCount áçñâ稪 ᥪâ®à®¢ |
110 | inc edx |
110 | inc edx |
111 | mov eax,[esp+4] |
111 | mov eax,[esp+4] |
112 | out dx,al ; ATASectorNumber ॣ¨áâà ®¬¥à ᥪâ®à |
112 | out dx,al ; ATASectorNumber ॣ¨áâà ®¬¥à ᥪâ®à |
113 | shr eax,8 |
113 | shr eax,8 |
114 | inc edx |
114 | inc edx |
115 | out dx,al ; ATACylinder ®¬¥à 樫¨¤à (¬« ¤è¨© ¡ ©â) |
115 | out dx,al ; ATACylinder ®¬¥à 樫¨¤à (¬« ¤è¨© ¡ ©â) |
116 | shr eax,8 |
116 | shr eax,8 |
117 | inc edx |
117 | inc edx |
118 | out dx,al ; ®¬¥à 樫¨¤à (áâ à訩 ¡ ©â) |
118 | out dx,al ; ®¬¥à 樫¨¤à (áâ à訩 ¡ ©â) |
119 | shr eax,8 |
119 | shr eax,8 |
120 | inc edx |
120 | inc edx |
121 | and al,1+2+4+8 |
121 | and al,1+2+4+8 |
122 | add al,byte [hdid] |
122 | add al,byte [hdid] |
123 | add al,128+64+32 |
123 | add al,128+64+32 |
124 | out dx,al ; ®¬¥à £®«®¢ª¨/®¬¥à ¤¨áª |
124 | out dx,al ; ®¬¥à £®«®¢ª¨/®¬¥à ¤¨áª |
125 | inc edx |
125 | inc edx |
126 | mov al,20h |
126 | mov al,20h |
127 | out dx,al ; ATACommand ॣ¨áâà ª®¬ ¤ |
127 | out dx,al ; ATACommand ॣ¨áâà ª®¬ ¤ |
128 | sti |
128 | sti |
129 | 129 | ||
130 | call wait_for_sector_buffer |
130 | call wait_for_sector_buffer |
131 | 131 | ||
132 | cmp [hd_error],0 |
132 | cmp [hd_error],0 |
133 | jne hd_read_error |
133 | jne hd_read_error |
134 | 134 | ||
135 | cli |
135 | cli |
136 | push edi |
136 | push edi |
137 | shl edi,9 |
137 | shl edi,9 |
138 | ; add edi,HD_CACHE+65536 |
138 | ; add edi,HD_CACHE+65536 |
139 | push eax |
139 | push eax |
140 | call calculate_cache_2 |
140 | call calculate_cache_2 |
141 | add edi,eax |
141 | add edi,eax |
142 | pop eax |
142 | pop eax |
143 | 143 | ||
144 | mov ecx,256 |
144 | mov ecx,256 |
145 | mov edx,[hdbase] |
145 | mov edx,[hdbase] |
146 | cld |
146 | cld |
147 | rep insw |
147 | rep insw |
148 | pop edi |
148 | pop edi |
149 | sti |
149 | sti |
150 | 150 | ||
151 | pop edx eax |
151 | pop edx eax |
152 | ret |
152 | ret |
153 | 153 | ||
154 | disable_ide_int: |
154 | disable_ide_int: |
155 | ; mov edx,[hdbase] |
155 | ; mov edx,[hdbase] |
156 | ; add edx,0x206 |
156 | ; add edx,0x206 |
157 | ; mov al,2 |
157 | ; mov al,2 |
158 | ; out dx,al |
158 | ; out dx,al |
159 | cli |
159 | cli |
160 | ret |
160 | ret |
161 | 161 | ||
162 | enable_ide_int: |
162 | enable_ide_int: |
163 | ; mov edx,[hdbase] |
163 | ; mov edx,[hdbase] |
164 | ; add edx,0x206 |
164 | ; add edx,0x206 |
165 | ; mov al,0 |
165 | ; mov al,0 |
166 | ; out dx,al |
166 | ; out dx,al |
167 | sti |
167 | sti |
168 | ret |
168 | ret |
169 | 169 | ||
170 | align 4 |
170 | align 4 |
171 | hd_write: |
171 | hd_write: |
172 | ;----------------------------------------------------------- |
172 | ;----------------------------------------------------------- |
173 | ; input : eax = block |
173 | ; input : eax = block |
174 | ; ebx = pointer to memory |
174 | ; ebx = pointer to memory |
175 | ;----------------------------------------------------------- |
175 | ;----------------------------------------------------------- |
176 | push ecx esi edi |
176 | push ecx esi edi |
177 | 177 | ||
178 | ; check if the cache already has the sector and overwrite it |
178 | ; check if the cache already has the sector and overwrite it |
179 | 179 | ||
180 | ; mov ecx,cache_max |
180 | ; mov ecx,cache_max |
181 | ; mov esi,HD_CACHE+8 |
181 | ; mov esi,HD_CACHE+8 |
182 | call calculate_cache |
182 | call calculate_cache |
183 | add esi,8 |
183 | add esi,8 |
184 | 184 | ||
185 | mov edi,1 |
185 | mov edi,1 |
186 | 186 | ||
187 | hdwritecache: |
187 | hdwritecache: |
188 | 188 | ||
189 | cmp dword [esi+4],0 ; if cache slot is empty |
189 | cmp dword [esi+4],0 ; if cache slot is empty |
190 | je not_in_cache_write |
190 | je not_in_cache_write |
191 | 191 | ||
192 | cmp [esi],eax ; if the slot has the sector |
192 | cmp [esi],eax ; if the slot has the sector |
193 | je yes_in_cache_write |
193 | je yes_in_cache_write |
194 | 194 | ||
195 | not_in_cache_write: |
195 | not_in_cache_write: |
196 | 196 | ||
197 | add esi,8 |
197 | add esi,8 |
198 | inc edi |
198 | inc edi |
199 | dec ecx |
199 | dec ecx |
200 | jnz hdwritecache |
200 | jnz hdwritecache |
201 | 201 | ||
202 | ; sector not found in cache |
202 | ; sector not found in cache |
203 | ; write the block to a new location |
203 | ; write the block to a new location |
204 | 204 | ||
205 | call find_empty_slot ; ret in edi |
205 | call find_empty_slot ; ret in edi |
206 | cmp [hd_error],0 |
206 | cmp [hd_error],0 |
207 | jne hd_write_access_denied |
207 | jne hd_write_access_denied |
208 | 208 | ||
209 | ; lea esi,[edi*8+HD_CACHE] |
209 | ; lea esi,[edi*8+HD_CACHE] |
210 | ; push eax |
210 | ; push eax |
211 | call calculate_cache_1 |
211 | call calculate_cache_1 |
212 | lea esi,[edi*8+esi] |
212 | lea esi,[edi*8+esi] |
213 | ; pop eax |
213 | ; pop eax |
214 | 214 | ||
215 | mov [esi],eax ; sector number |
215 | mov [esi],eax ; sector number |
216 | 216 | ||
217 | yes_in_cache_write: |
217 | yes_in_cache_write: |
218 | 218 | ||
219 | mov dword [esi+4],2 ; write - differs from hd |
219 | mov dword [esi+4],2 ; write - differs from hd |
220 | 220 | ||
221 | shl edi,9 |
221 | shl edi,9 |
222 | ; add edi,HD_CACHE+65536 |
222 | ; add edi,HD_CACHE+65536 |
223 | push eax |
223 | push eax |
224 | call calculate_cache_2 |
224 | call calculate_cache_2 |
225 | add edi,eax |
225 | add edi,eax |
226 | pop eax |
226 | pop eax |
227 | 227 | ||
228 | mov esi,ebx |
228 | mov esi,ebx |
229 | mov ecx,512/4 |
229 | mov ecx,512/4 |
230 | cld |
230 | cld |
231 | rep movsd ; move data |
231 | rep movsd ; move data |
232 | hd_write_access_denied: |
232 | hd_write_access_denied: |
233 | pop edi esi ecx |
233 | pop edi esi ecx |
234 | ret |
234 | ret |
235 | 235 | ||
236 | align 4 |
236 | align 4 |
237 | cache_write_pio: |
237 | cache_write_pio: |
238 | ; call disable_ide_int |
238 | ; call disable_ide_int |
239 | 239 | ||
240 | call wait_for_hd_idle |
240 | call wait_for_hd_idle |
241 | cmp [hd_error],0 |
241 | cmp [hd_error],0 |
242 | jne hd_write_error |
242 | jne hd_write_error |
243 | 243 | ||
244 | cli |
244 | cli |
245 | xor eax,eax |
245 | xor eax,eax |
246 | mov edx,[hdbase] |
246 | mov edx,[hdbase] |
247 | inc edx |
247 | inc edx |
248 | out dx,al |
248 | out dx,al |
249 | inc edx |
249 | inc edx |
250 | inc eax |
250 | inc eax |
251 | out dx,al |
251 | out dx,al |
252 | inc edx |
252 | inc edx |
253 | mov eax,[esi] ; eax = sector to write |
253 | mov eax,[esi] ; eax = sector to write |
254 | out dx,al |
254 | out dx,al |
255 | shr eax,8 |
255 | shr eax,8 |
256 | inc edx |
256 | inc edx |
257 | out dx,al |
257 | out dx,al |
258 | shr eax,8 |
258 | shr eax,8 |
259 | inc edx |
259 | inc edx |
260 | out dx,al |
260 | out dx,al |
261 | shr eax,8 |
261 | shr eax,8 |
262 | inc edx |
262 | inc edx |
263 | and al,1+2+4+8 |
263 | and al,1+2+4+8 |
264 | add al,byte [hdid] |
264 | add al,byte [hdid] |
265 | add al,128+64+32 |
265 | add al,128+64+32 |
266 | out dx,al |
266 | out dx,al |
267 | inc edx |
267 | inc edx |
268 | mov al,30h |
268 | mov al,30h |
269 | out dx,al |
269 | out dx,al |
270 | sti |
270 | sti |
271 | 271 | ||
272 | call wait_for_sector_buffer |
272 | call wait_for_sector_buffer |
273 | 273 | ||
274 | cmp [hd_error],0 |
274 | cmp [hd_error],0 |
275 | jne hd_write_error |
275 | jne hd_write_error |
276 | 276 | ||
277 | push ecx esi |
277 | push ecx esi |
278 | 278 | ||
279 | cli |
279 | cli |
280 | mov esi,edi |
280 | mov esi,edi |
281 | shl esi,9 |
281 | shl esi,9 |
282 | ; add esi,HD_CACHE+65536 ; esi = from memory position |
282 | ; add esi,HD_CACHE+65536 ; esi = from memory position |
283 | push eax |
283 | push eax |
284 | call calculate_cache_2 |
284 | call calculate_cache_2 |
285 | add esi,eax |
285 | add esi,eax |
286 | pop eax |
286 | pop eax |
287 | 287 | ||
288 | mov ecx,256 |
288 | mov ecx,256 |
289 | mov edx,[hdbase] |
289 | mov edx,[hdbase] |
290 | cld |
290 | cld |
291 | rep outsw |
291 | rep outsw |
292 | sti |
292 | sti |
293 | 293 | ||
294 | ; call enable_ide_int |
294 | ; call enable_ide_int |
295 | pop esi ecx |
295 | pop esi ecx |
296 | 296 | ||
297 | ret |
297 | ret |
298 | 298 | ||
299 | save_hd_wait_timeout: |
299 | save_hd_wait_timeout: |
300 | 300 | ||
301 | push eax |
301 | push eax |
302 | mov eax,[timer_ticks] |
302 | mov eax,[timer_ticks] |
303 | add eax,300 ; 3 sec timeout |
303 | add eax,300 ; 3 sec timeout |
304 | mov [hd_wait_timeout],eax |
304 | mov [hd_wait_timeout],eax |
305 | pop eax |
305 | pop eax |
306 | ret |
306 | ret |
307 | 307 | ||
308 | align 4 |
308 | align 4 |
309 | check_hd_wait_timeout: |
309 | check_hd_wait_timeout: |
310 | 310 | ||
311 | push eax |
311 | push eax |
312 | mov eax,[hd_wait_timeout] |
312 | mov eax,[hd_wait_timeout] |
313 | cmp [timer_ticks], eax |
313 | cmp [timer_ticks], eax |
314 | jg hd_timeout_error |
314 | jg hd_timeout_error |
315 | pop eax |
315 | pop eax |
316 | mov [hd_error],0 |
316 | mov [hd_error],0 |
317 | ret |
317 | ret |
318 | 318 | ||
319 | ;iglobal |
319 | ;iglobal |
320 | ; hd_timeout_str db 'K : FS - HD timeout',0 |
320 | ; hd_timeout_str db 'K : FS - HD timeout',0 |
321 | ; hd_read_str db 'K : FS - HD read error',0 |
321 | ; hd_read_str db 'K : FS - HD read error',0 |
322 | ; hd_write_str db 'K : FS - HD write error',0 |
322 | ; hd_write_str db 'K : FS - HD write error',0 |
323 | ; hd_lba_str db 'K : FS - HD LBA error',0 |
323 | ; hd_lba_str db 'K : FS - HD LBA error',0 |
324 | ;endg |
324 | ;endg |
325 | 325 | ||
326 | hd_timeout_error: |
326 | hd_timeout_error: |
327 | 327 | ||
328 | ; call clear_hd_cache |
328 | ; call clear_hd_cache |
329 | ; call clear_application_table_status |
329 | ; call clear_application_table_status |
330 | ; mov esi,hd_timeout_str |
330 | ; mov esi,hd_timeout_str |
331 | ; call sys_msg_board_str |
331 | ; call sys_msg_board_str |
332 | DEBUGF 1,"K : FS - HD timeout\n" |
332 | DEBUGF 1,"K : FS - HD timeout\n" |
333 | 333 | ||
334 | mov [hd_error],1 |
334 | mov [hd_error],1 |
335 | pop eax |
335 | pop eax |
336 | ret |
336 | ret |
337 | 337 | ||
338 | hd_read_error: |
338 | hd_read_error: |
339 | 339 | ||
340 | ; call clear_hd_cache |
340 | ; call clear_hd_cache |
341 | ; call clear_application_table_status |
341 | ; call clear_application_table_status |
342 | ; mov esi,hd_read_str |
342 | ; mov esi,hd_read_str |
343 | ; call sys_msg_board_str |
343 | ; call sys_msg_board_str |
344 | DEBUGF 1,"K : FS - HD read error\n" |
344 | DEBUGF 1,"K : FS - HD read error\n" |
345 | pop edx eax |
345 | pop edx eax |
346 | ret |
346 | ret |
347 | 347 | ||
348 | hd_write_error: |
348 | hd_write_error: |
349 | 349 | ||
350 | ; call clear_hd_cache |
350 | ; call clear_hd_cache |
351 | ; call clear_application_table_status |
351 | ; call clear_application_table_status |
352 | ; mov esi,hd_write_str |
352 | ; mov esi,hd_write_str |
353 | ; call sys_msg_board_str |
353 | ; call sys_msg_board_str |
354 | DEBUGF 1,"K : FS - HD write error\n" |
354 | DEBUGF 1,"K : FS - HD write error\n" |
355 | ret |
355 | ret |
356 | 356 | ||
357 | hd_write_error_dma: |
357 | hd_write_error_dma: |
358 | ; call clear_hd_cache |
358 | ; call clear_hd_cache |
359 | ; call clear_application_table_status |
359 | ; call clear_application_table_status |
360 | ; mov esi, hd_write_str |
360 | ; mov esi, hd_write_str |
361 | ; call sys_msg_board_str |
361 | ; call sys_msg_board_str |
362 | DEBUGF 1,"K : FS - HD read error\n" |
362 | DEBUGF 1,"K : FS - HD read error\n" |
363 | pop esi |
363 | pop esi |
364 | ret |
364 | ret |
365 | 365 | ||
366 | hd_lba_error: |
366 | hd_lba_error: |
367 | ; call clear_hd_cache |
367 | ; call clear_hd_cache |
368 | ; call clear_application_table_status |
368 | ; call clear_application_table_status |
369 | ; mov esi,hd_lba_str |
369 | ; mov esi,hd_lba_str |
370 | ; call sys_msg_board_str |
370 | ; call sys_msg_board_str |
371 | DEBUGF 1,"K : FS - HD LBA error\n" |
371 | DEBUGF 1,"K : FS - HD LBA error\n" |
372 | jmp LBA_read_ret |
372 | jmp LBA_read_ret |
373 | 373 | ||
374 | 374 | ||
375 | align 4 |
375 | align 4 |
376 | wait_for_hd_idle: |
376 | wait_for_hd_idle: |
377 | 377 | ||
378 | push eax edx |
378 | push eax edx |
379 | 379 | ||
380 | call save_hd_wait_timeout |
380 | call save_hd_wait_timeout |
381 | 381 | ||
382 | mov edx,[hdbase] |
382 | mov edx,[hdbase] |
383 | add edx,0x7 |
383 | add edx,0x7 |
384 | 384 | ||
385 | wfhil1: |
385 | wfhil1: |
386 | 386 | ||
387 | call check_hd_wait_timeout |
387 | call check_hd_wait_timeout |
388 | cmp [hd_error],0 |
388 | cmp [hd_error],0 |
389 | jne @f |
389 | jne @f |
390 | 390 | ||
391 | in al,dx |
391 | in al,dx |
392 | test al,128 |
392 | test al,128 |
393 | jnz wfhil1 |
393 | jnz wfhil1 |
394 | 394 | ||
395 | @@: |
395 | @@: |
396 | 396 | ||
397 | pop edx eax |
397 | pop edx eax |
398 | ret |
398 | ret |
399 | 399 | ||
400 | 400 | ||
401 | align 4 |
401 | align 4 |
402 | wait_for_sector_buffer: |
402 | wait_for_sector_buffer: |
403 | 403 | ||
404 | push eax edx |
404 | push eax edx |
405 | 405 | ||
406 | mov edx,[hdbase] |
406 | mov edx,[hdbase] |
407 | add edx,0x7 |
407 | add edx,0x7 |
408 | 408 | ||
409 | call save_hd_wait_timeout |
409 | call save_hd_wait_timeout |
410 | 410 | ||
411 | hdwait_sbuf: ; wait for sector buffer to be ready |
411 | hdwait_sbuf: ; wait for sector buffer to be ready |
412 | 412 | ||
413 | call check_hd_wait_timeout |
413 | call check_hd_wait_timeout |
414 | cmp [hd_error],0 |
414 | cmp [hd_error],0 |
415 | jne @f |
415 | jne @f |
416 | 416 | ||
417 | in al,dx |
417 | in al,dx |
418 | test al,8 |
418 | test al,8 |
419 | jz hdwait_sbuf |
419 | jz hdwait_sbuf |
420 | 420 | ||
421 | mov [hd_error],0 |
421 | mov [hd_error],0 |
422 | 422 | ||
423 | cmp [hd_setup],1 ; do not mark error for setup request |
423 | cmp [hd_setup],1 ; do not mark error for setup request |
424 | je buf_wait_ok |
424 | je buf_wait_ok |
425 | 425 | ||
426 | test al,1 ; previous command ended up with an error |
426 | test al,1 ; previous command ended up with an error |
427 | jz buf_wait_ok |
427 | jz buf_wait_ok |
428 | @@: |
428 | @@: |
429 | mov [hd_error],1 |
429 | mov [hd_error],1 |
430 | 430 | ||
431 | buf_wait_ok: |
431 | buf_wait_ok: |
432 | 432 | ||
433 | pop edx eax |
433 | pop edx eax |
434 | ret |
434 | ret |
435 | 435 | ||
436 | ; \begin{Mario79} |
436 | ; \begin{Mario79} |
437 | align 4 |
437 | align 4 |
438 | wait_for_sector_dma_ide0: |
438 | wait_for_sector_dma_ide0: |
439 | push eax |
439 | push eax |
440 | push edx |
440 | push edx |
441 | call save_hd_wait_timeout |
441 | call save_hd_wait_timeout |
442 | .wait: |
442 | .wait: |
443 | call change_task |
443 | call change_task |
444 | cmp [irq14_func], hdd_irq14 |
444 | cmp [irq14_func], hdd_irq14 |
445 | jnz .done |
445 | jnz .done |
446 | call check_hd_wait_timeout |
446 | call check_hd_wait_timeout |
447 | cmp [hd_error], 0 |
447 | cmp [hd_error], 0 |
448 | jz .wait |
448 | jz .wait |
449 | mov [irq14_func], hdd_irq_null |
449 | mov [irq14_func], hdd_irq_null |
450 | mov dx, [IDEContrRegsBaseAddr] |
450 | mov dx, [IDEContrRegsBaseAddr] |
451 | mov al, 0 |
451 | mov al, 0 |
452 | out dx, al |
452 | out dx, al |
453 | .done: |
453 | .done: |
454 | pop edx |
454 | pop edx |
455 | pop eax |
455 | pop eax |
456 | ret |
456 | ret |
457 | 457 | ||
458 | align 4 |
458 | align 4 |
459 | wait_for_sector_dma_ide1: |
459 | wait_for_sector_dma_ide1: |
460 | push eax |
460 | push eax |
461 | push edx |
461 | push edx |
462 | call save_hd_wait_timeout |
462 | call save_hd_wait_timeout |
463 | .wait: |
463 | .wait: |
464 | call change_task |
464 | call change_task |
465 | cmp [irq15_func], hdd_irq15 |
465 | cmp [irq15_func], hdd_irq15 |
466 | jnz .done |
466 | jnz .done |
467 | call check_hd_wait_timeout |
467 | call check_hd_wait_timeout |
468 | cmp [hd_error], 0 |
468 | cmp [hd_error], 0 |
469 | jz .wait |
469 | jz .wait |
470 | mov [irq15_func], hdd_irq_null |
470 | mov [irq15_func], hdd_irq_null |
471 | mov dx, [IDEContrRegsBaseAddr] |
471 | mov dx, [IDEContrRegsBaseAddr] |
472 | add dx, 8 |
472 | add dx, 8 |
473 | mov al, 0 |
473 | mov al, 0 |
474 | out dx, al |
474 | out dx, al |
475 | .done: |
475 | .done: |
476 | pop edx |
476 | pop edx |
477 | pop eax |
477 | pop eax |
478 | ret |
478 | ret |
479 | 479 | ||
480 | iglobal |
480 | iglobal |
481 | align 4 |
481 | align 4 |
482 | ; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary |
482 | ; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary |
483 | IDE_descriptor_table: |
483 | IDE_descriptor_table: |
484 | dd IDE_DMA |
484 | dd IDE_DMA |
485 | dw 0x2000 |
485 | dw 0x2000 |
486 | dw 0x8000 |
486 | dw 0x8000 |
487 | 487 | ||
488 | dma_cur_sector dd not 40h |
488 | dma_cur_sector dd not 40h |
489 | dma_hdpos dd 0 |
489 | dma_hdpos dd 0 |
490 | irq14_func dd hdd_irq_null |
490 | irq14_func dd hdd_irq_null |
491 | irq15_func dd hdd_irq_null |
491 | irq15_func dd hdd_irq_null |
492 | endg |
492 | endg |
493 | 493 | ||
494 | uglobal |
494 | uglobal |
495 | ; all uglobals are zeroed at boot |
495 | ; all uglobals are zeroed at boot |
496 | dma_process dd 0 |
496 | dma_process dd 0 |
497 | dma_slot_ptr dd 0 |
497 | dma_slot_ptr dd 0 |
498 | cache_chain_pos dd 0 |
498 | cache_chain_pos dd 0 |
499 | cache_chain_ptr dd 0 |
499 | cache_chain_ptr dd 0 |
500 | cache_chain_size db 0 |
500 | cache_chain_size db 0 |
501 | cache_chain_started db 0 |
501 | cache_chain_started db 0 |
502 | dma_task_switched db 0 |
502 | dma_task_switched db 0 |
503 | dma_hdd db 0 |
503 | dma_hdd db 0 |
504 | allow_dma_access db 0 |
504 | allow_dma_access db 0 |
505 | endg |
505 | endg |
506 | 506 | ||
507 | align 4 |
507 | align 4 |
508 | hdd_irq14: |
508 | hdd_irq14: |
509 | pushfd |
509 | pushfd |
510 | cli |
510 | cli |
511 | pushad |
511 | pushad |
512 | mov [irq14_func], hdd_irq_null |
512 | mov [irq14_func], hdd_irq_null |
513 | mov dx, [IDEContrRegsBaseAddr] |
513 | mov dx, [IDEContrRegsBaseAddr] |
514 | mov al, 0 |
514 | mov al, 0 |
515 | out dx, al |
515 | out dx, al |
516 | ; call update_counters |
516 | ; call update_counters |
517 | ; mov ebx, [dma_process] |
517 | ; mov ebx, [dma_process] |
518 | ; cmp [CURRENT_TASK], ebx |
518 | ; cmp [CURRENT_TASK], ebx |
519 | ; jz .noswitch |
519 | ; jz .noswitch |
520 | ; mov [dma_task_switched], 1 |
520 | ; mov [dma_task_switched], 1 |
521 | ; mov edi, [dma_slot_ptr] |
521 | ; mov edi, [dma_slot_ptr] |
522 | ; mov eax, [CURRENT_TASK] |
522 | ; mov eax, [CURRENT_TASK] |
523 | ; mov [dma_process], eax |
523 | ; mov [dma_process], eax |
524 | ; mov eax, [TASK_BASE] |
524 | ; mov eax, [TASK_BASE] |
525 | ; mov [dma_slot_ptr], eax |
525 | ; mov [dma_slot_ptr], eax |
526 | ; mov [CURRENT_TASK], ebx |
526 | ; mov [CURRENT_TASK], ebx |
527 | ; mov [TASK_BASE], edi |
527 | ; mov [TASK_BASE], edi |
528 | ; mov byte [DONT_SWITCH], 1 |
528 | ; mov byte [DONT_SWITCH], 1 |
529 | ; call do_change_task |
529 | ; call do_change_task |
530 | .noswitch: |
530 | .noswitch: |
531 | popad |
531 | popad |
532 | popfd |
532 | popfd |
533 | align 4 |
533 | align 4 |
534 | hdd_irq_null: |
534 | hdd_irq_null: |
535 | ret |
535 | ret |
536 | 536 | ||
537 | align 4 |
537 | align 4 |
538 | hdd_irq15: |
538 | hdd_irq15: |
539 | pushfd |
539 | pushfd |
540 | cli |
540 | cli |
541 | pushad |
541 | pushad |
542 | mov [irq15_func], hdd_irq_null |
542 | mov [irq15_func], hdd_irq_null |
543 | mov dx, [IDEContrRegsBaseAddr] |
543 | mov dx, [IDEContrRegsBaseAddr] |
544 | add dx, 8 |
544 | add dx, 8 |
545 | mov al, 0 |
545 | mov al, 0 |
546 | out dx, al |
546 | out dx, al |
547 | ; call update_counters |
547 | ; call update_counters |
548 | ; mov ebx, [dma_process] |
548 | ; mov ebx, [dma_process] |
549 | ; cmp [CURRENT_TASK], ebx |
549 | ; cmp [CURRENT_TASK], ebx |
550 | ; jz .noswitch |
550 | ; jz .noswitch |
551 | ; mov [dma_task_switched], 1 |
551 | ; mov [dma_task_switched], 1 |
552 | ; mov edi, [dma_slot_ptr] |
552 | ; mov edi, [dma_slot_ptr] |
553 | ; mov eax, [CURRENT_TASK] |
553 | ; mov eax, [CURRENT_TASK] |
554 | ; mov [dma_process], eax |
554 | ; mov [dma_process], eax |
555 | ; mov eax, [TASK_BASE] |
555 | ; mov eax, [TASK_BASE] |
556 | ; mov [dma_slot_ptr], eax |
556 | ; mov [dma_slot_ptr], eax |
557 | ; mov [CURRENT_TASK], ebx |
557 | ; mov [CURRENT_TASK], ebx |
558 | ; mov [TASK_BASE], edi |
558 | ; mov [TASK_BASE], edi |
559 | ; mov byte [DONT_SWITCH], 1 |
559 | ; mov byte [DONT_SWITCH], 1 |
560 | ; call do_change_task |
560 | ; call do_change_task |
561 | .noswitch: |
561 | .noswitch: |
562 | popad |
562 | popad |
563 | popfd |
563 | popfd |
564 | ret |
564 | ret |
565 | 565 | ||
566 | align 4 |
566 | align 4 |
567 | hd_read_dma: |
567 | hd_read_dma: |
568 | push eax |
568 | push eax |
569 | push edx |
569 | push edx |
570 | mov edx,[dma_hdpos] |
570 | mov edx,[dma_hdpos] |
571 | cmp edx,[hdpos] |
571 | cmp edx,[hdpos] |
572 | jne .notread |
572 | jne .notread |
573 | mov edx, [dma_cur_sector] |
573 | mov edx, [dma_cur_sector] |
574 | cmp eax, edx |
574 | cmp eax, edx |
575 | jb .notread |
575 | jb .notread |
576 | add edx, 15 |
576 | add edx, 15 |
577 | cmp [esp+4], edx |
577 | cmp [esp+4], edx |
578 | ja .notread |
578 | ja .notread |
579 | mov eax, [esp+4] |
579 | mov eax, [esp+4] |
580 | sub eax, [dma_cur_sector] |
580 | sub eax, [dma_cur_sector] |
581 | shl eax, 9 |
581 | shl eax, 9 |
582 | add eax, (OS_BASE+IDE_DMA) |
582 | add eax, (OS_BASE+IDE_DMA) |
583 | push ecx esi edi |
583 | push ecx esi edi |
584 | mov esi, eax |
584 | mov esi, eax |
585 | shl edi, 9 |
585 | shl edi, 9 |
586 | ; add edi, HD_CACHE+0x10000 |
586 | ; add edi, HD_CACHE+0x10000 |
587 | push eax |
587 | push eax |
588 | call calculate_cache_2 |
588 | call calculate_cache_2 |
589 | add edi,eax |
589 | add edi,eax |
590 | pop eax |
590 | pop eax |
591 | 591 | ||
592 | mov ecx, 512/4 |
592 | mov ecx, 512/4 |
593 | cld |
593 | cld |
594 | rep movsd |
594 | rep movsd |
595 | pop edi esi ecx |
595 | pop edi esi ecx |
596 | pop edx |
596 | pop edx |
597 | pop eax |
597 | pop eax |
598 | ret |
598 | ret |
599 | .notread: |
599 | .notread: |
600 | mov eax, IDE_descriptor_table |
600 | mov eax, IDE_descriptor_table |
601 | mov dword [eax], IDE_DMA |
601 | mov dword [eax], IDE_DMA |
602 | mov word [eax+4], 0x2000 |
602 | mov word [eax+4], 0x2000 |
603 | sub eax, OS_BASE |
603 | sub eax, OS_BASE |
604 | mov dx, [IDEContrRegsBaseAddr] |
604 | mov dx, [IDEContrRegsBaseAddr] |
605 | cmp [hdbase], 0x1F0 |
605 | cmp [hdbase], 0x1F0 |
606 | jz @f |
606 | jz @f |
607 | add edx, 8 |
607 | add edx, 8 |
608 | @@: |
608 | @@: |
609 | push edx |
609 | push edx |
610 | add edx, 4 |
610 | add edx, 4 |
611 | out dx, eax |
611 | out dx, eax |
612 | pop edx |
612 | pop edx |
613 | mov al, 0 |
613 | mov al, 0 |
614 | out dx, al |
614 | out dx, al |
615 | add edx, 2 |
615 | add edx, 2 |
616 | mov al, 6 |
616 | mov al, 6 |
617 | out dx, al |
617 | out dx, al |
618 | call wait_for_hd_idle |
618 | call wait_for_hd_idle |
619 | cmp [hd_error], 0 |
619 | cmp [hd_error], 0 |
620 | jnz hd_read_error |
620 | jnz hd_read_error |
621 | call disable_ide_int |
621 | call disable_ide_int |
622 | xor eax, eax |
622 | xor eax, eax |
623 | mov edx, [hdbase] |
623 | mov edx, [hdbase] |
624 | inc edx |
624 | inc edx |
625 | out dx, al |
625 | out dx, al |
626 | inc edx |
626 | inc edx |
627 | mov eax, 10h |
627 | mov eax, 10h |
628 | out dx, al |
628 | out dx, al |
629 | inc edx |
629 | inc edx |
630 | mov eax, [esp+4] |
630 | mov eax, [esp+4] |
631 | out dx, al |
631 | out dx, al |
632 | shr eax, 8 |
632 | shr eax, 8 |
633 | inc edx |
633 | inc edx |
634 | out dx, al |
634 | out dx, al |
635 | shr eax, 8 |
635 | shr eax, 8 |
636 | inc edx |
636 | inc edx |
637 | out dx, al |
637 | out dx, al |
638 | shr eax, 8 |
638 | shr eax, 8 |
639 | inc edx |
639 | inc edx |
640 | and al, 0xF |
640 | and al, 0xF |
641 | add al, byte [hdid] |
641 | add al, byte [hdid] |
642 | add al, 11100000b |
642 | add al, 11100000b |
643 | out dx, al |
643 | out dx, al |
644 | inc edx |
644 | inc edx |
645 | mov al, 0xC8 |
645 | mov al, 0xC8 |
646 | out dx, al |
646 | out dx, al |
647 | mov dx, [IDEContrRegsBaseAddr] |
647 | mov dx, [IDEContrRegsBaseAddr] |
648 | cmp [hdbase], 0x1F0 |
648 | cmp [hdbase], 0x1F0 |
649 | jz @f |
649 | jz @f |
650 | add dx, 8 |
650 | add dx, 8 |
651 | @@: |
651 | @@: |
652 | mov al, 9 |
652 | mov al, 9 |
653 | out dx, al |
653 | out dx, al |
654 | mov eax, [CURRENT_TASK] |
654 | mov eax, [CURRENT_TASK] |
655 | mov [dma_process], eax |
655 | mov [dma_process], eax |
656 | mov eax, [TASK_BASE] |
656 | mov eax, [TASK_BASE] |
657 | mov [dma_slot_ptr], eax |
657 | mov [dma_slot_ptr], eax |
658 | cmp [hdbase], 0x1F0 |
658 | cmp [hdbase], 0x1F0 |
659 | jnz .ide1 |
659 | jnz .ide1 |
660 | mov [irq14_func], hdd_irq14 |
660 | mov [irq14_func], hdd_irq14 |
661 | jmp @f |
661 | jmp @f |
662 | .ide1: |
662 | .ide1: |
663 | mov [irq15_func], hdd_irq15 |
663 | mov [irq15_func], hdd_irq15 |
664 | @@: |
664 | @@: |
665 | call enable_ide_int |
665 | call enable_ide_int |
666 | cmp [hdbase], 0x1F0 |
666 | cmp [hdbase], 0x1F0 |
667 | jnz .wait_ide1 |
667 | jnz .wait_ide1 |
668 | call wait_for_sector_dma_ide0 |
668 | call wait_for_sector_dma_ide0 |
669 | jmp @f |
669 | jmp @f |
670 | .wait_ide1: |
670 | .wait_ide1: |
671 | call wait_for_sector_dma_ide1 |
671 | call wait_for_sector_dma_ide1 |
672 | @@: |
672 | @@: |
673 | cmp [hd_error], 0 |
673 | cmp [hd_error], 0 |
674 | jnz hd_read_error |
674 | jnz hd_read_error |
675 | mov eax,[hdpos] |
675 | mov eax,[hdpos] |
676 | mov [dma_hdpos],eax |
676 | mov [dma_hdpos],eax |
677 | pop edx |
677 | pop edx |
678 | pop eax |
678 | pop eax |
679 | mov [dma_cur_sector], eax |
679 | mov [dma_cur_sector], eax |
680 | jmp hd_read_dma |
680 | jmp hd_read_dma |
681 | 681 | ||
682 | align 4 |
682 | align 4 |
683 | write_cache_sector: |
683 | write_cache_sector: |
684 | mov [cache_chain_size],1 |
684 | mov [cache_chain_size],1 |
685 | mov [cache_chain_pos],edi |
685 | mov [cache_chain_pos],edi |
686 | write_cache_chain: |
686 | write_cache_chain: |
687 | cmp [hdpos], 0x80 |
687 | cmp [hdpos], 0x80 |
688 | jae bd_write_cache_chain |
688 | jae bd_write_cache_chain |
689 | push esi |
689 | push esi |
690 | mov eax, IDE_descriptor_table |
690 | mov eax, IDE_descriptor_table |
691 | mov edx,eax |
691 | mov edx,eax |
692 | pusha |
692 | pusha |
693 | mov esi,[cache_chain_pos] |
693 | mov esi,[cache_chain_pos] |
694 | shl esi, 9 |
694 | shl esi, 9 |
695 | call calculate_cache_2 |
695 | call calculate_cache_2 |
696 | add esi,eax |
696 | add esi,eax |
697 | mov edi, (OS_BASE+IDE_DMA) |
697 | mov edi, (OS_BASE+IDE_DMA) |
698 | mov dword [edx], IDE_DMA |
698 | mov dword [edx], IDE_DMA |
699 | movzx ecx, [cache_chain_size] |
699 | movzx ecx, [cache_chain_size] |
700 | shl ecx, 9 |
700 | shl ecx, 9 |
701 | mov word [edx+4], cx |
701 | mov word [edx+4], cx |
702 | shr ecx,2 |
702 | shr ecx,2 |
703 | cld |
703 | cld |
704 | rep movsd |
704 | rep movsd |
705 | popa |
705 | popa |
706 | sub eax, OS_BASE |
706 | sub eax, OS_BASE |
707 | mov dx, [IDEContrRegsBaseAddr] |
707 | mov dx, [IDEContrRegsBaseAddr] |
708 | cmp [hdbase], 0x1F0 |
708 | cmp [hdbase], 0x1F0 |
709 | jz @f |
709 | jz @f |
710 | add edx, 8 |
710 | add edx, 8 |
711 | @@: |
711 | @@: |
712 | push edx |
712 | push edx |
713 | add edx, 4 |
713 | add edx, 4 |
714 | out dx, eax |
714 | out dx, eax |
715 | pop edx |
715 | pop edx |
716 | mov al, 0 |
716 | mov al, 0 |
717 | out dx, al |
717 | out dx, al |
718 | add edx, 2 |
718 | add edx, 2 |
719 | mov al, 6 |
719 | mov al, 6 |
720 | out dx, al |
720 | out dx, al |
721 | call wait_for_hd_idle |
721 | call wait_for_hd_idle |
722 | cmp [hd_error], 0 |
722 | cmp [hd_error], 0 |
723 | jnz hd_write_error_dma |
723 | jnz hd_write_error_dma |
724 | call disable_ide_int |
724 | call disable_ide_int |
725 | xor eax, eax |
725 | xor eax, eax |
726 | mov edx, [hdbase] |
726 | mov edx, [hdbase] |
727 | inc edx |
727 | inc edx |
728 | out dx, al |
728 | out dx, al |
729 | inc edx |
729 | inc edx |
730 | mov al, [cache_chain_size] |
730 | mov al, [cache_chain_size] |
731 | out dx, al |
731 | out dx, al |
732 | inc edx |
732 | inc edx |
733 | mov esi, [cache_chain_ptr] |
733 | mov esi, [cache_chain_ptr] |
734 | mov eax, [esi] |
734 | mov eax, [esi] |
735 | out dx, al |
735 | out dx, al |
736 | shr eax, 8 |
736 | shr eax, 8 |
737 | inc edx |
737 | inc edx |
738 | out dx, al |
738 | out dx, al |
739 | shr eax, 8 |
739 | shr eax, 8 |
740 | inc edx |
740 | inc edx |
741 | out dx, al |
741 | out dx, al |
742 | shr eax, 8 |
742 | shr eax, 8 |
743 | inc edx |
743 | inc edx |
744 | and al, 0xF |
744 | and al, 0xF |
745 | add al, byte [hdid] |
745 | add al, byte [hdid] |
746 | add al, 11100000b |
746 | add al, 11100000b |
747 | out dx, al |
747 | out dx, al |
748 | inc edx |
748 | inc edx |
749 | mov al, 0xCA |
749 | mov al, 0xCA |
750 | out dx, al |
750 | out dx, al |
751 | mov dx, [IDEContrRegsBaseAddr] |
751 | mov dx, [IDEContrRegsBaseAddr] |
752 | cmp [hdbase], 0x1F0 |
752 | cmp [hdbase], 0x1F0 |
753 | jz @f |
753 | jz @f |
754 | add dx, 8 |
754 | add dx, 8 |
755 | @@: |
755 | @@: |
756 | mov al, 1 |
756 | mov al, 1 |
757 | out dx, al |
757 | out dx, al |
758 | mov eax, [CURRENT_TASK] |
758 | mov eax, [CURRENT_TASK] |
759 | mov [dma_process], eax |
759 | mov [dma_process], eax |
760 | mov eax, [TASK_BASE] |
760 | mov eax, [TASK_BASE] |
761 | mov [dma_slot_ptr], eax |
761 | mov [dma_slot_ptr], eax |
762 | cmp [hdbase], 0x1F0 |
762 | cmp [hdbase], 0x1F0 |
763 | jnz .ide1 |
763 | jnz .ide1 |
764 | mov [irq14_func], hdd_irq14 |
764 | mov [irq14_func], hdd_irq14 |
765 | jmp @f |
765 | jmp @f |
766 | .ide1: |
766 | .ide1: |
767 | mov [irq15_func], hdd_irq15 |
767 | mov [irq15_func], hdd_irq15 |
768 | @@: |
768 | @@: |
769 | call enable_ide_int |
769 | call enable_ide_int |
770 | mov [dma_cur_sector], not 0x40 |
770 | mov [dma_cur_sector], not 0x40 |
771 | cmp [hdbase], 0x1F0 |
771 | cmp [hdbase], 0x1F0 |
772 | jnz .wait_ide1 |
772 | jnz .wait_ide1 |
773 | call wait_for_sector_dma_ide0 |
773 | call wait_for_sector_dma_ide0 |
774 | jmp @f |
774 | jmp @f |
775 | .wait_ide1: |
775 | .wait_ide1: |
776 | call wait_for_sector_dma_ide1 |
776 | call wait_for_sector_dma_ide1 |
777 | @@: |
777 | @@: |
778 | cmp [hd_error], 0 |
778 | cmp [hd_error], 0 |
779 | jnz hd_write_error_dma |
779 | jnz hd_write_error_dma |
780 | pop esi |
780 | pop esi |
781 | ret |
781 | ret |
782 | 782 | ||
783 | uglobal |
783 | uglobal |
784 | IDEContrRegsBaseAddr dw ? |
784 | IDEContrRegsBaseAddr dw ? |
785 | endg |
785 | endg |
786 | ; \end{Mario79} |
786 | ; \end{Mario79} |
787 | 787 | ||
788 | ; \begin{diamond} |
788 | ; \begin{diamond} |
789 | uglobal |
789 | uglobal |
790 | bios_hdpos dd 0 ; 0 is invalid value for [hdpos] |
790 | bios_hdpos dd 0 ; 0 is invalid value for [hdpos] |
791 | bios_cur_sector dd ? |
791 | bios_cur_sector dd ? |
792 | bios_read_len dd ? |
792 | bios_read_len dd ? |
793 | endg |
793 | endg |
794 | bd_read: |
794 | bd_read: |
795 | push eax |
795 | push eax |
796 | push edx |
796 | push edx |
797 | mov edx, [bios_hdpos] |
797 | mov edx, [bios_hdpos] |
798 | cmp edx, [hdpos] |
798 | cmp edx, [hdpos] |
799 | jne .notread |
799 | jne .notread |
800 | mov edx, [bios_cur_sector] |
800 | mov edx, [bios_cur_sector] |
801 | cmp eax, edx |
801 | cmp eax, edx |
802 | jb .notread |
802 | jb .notread |
803 | add edx, [bios_read_len] |
803 | add edx, [bios_read_len] |
804 | dec edx |
804 | dec edx |
805 | cmp eax, edx |
805 | cmp eax, edx |
806 | ja .notread |
806 | ja .notread |
807 | sub eax, [bios_cur_sector] |
807 | sub eax, [bios_cur_sector] |
808 | shl eax, 9 |
808 | shl eax, 9 |
809 | add eax, (OS_BASE+0x9C000) |
809 | add eax, (OS_BASE+0x9C000) |
810 | push ecx esi edi |
810 | push ecx esi edi |
811 | mov esi, eax |
811 | mov esi, eax |
812 | shl edi, 9 |
812 | shl edi, 9 |
813 | ; add edi, HD_CACHE+0x10000 |
813 | ; add edi, HD_CACHE+0x10000 |
814 | push eax |
814 | push eax |
815 | call calculate_cache_2 |
815 | call calculate_cache_2 |
816 | add edi,eax |
816 | add edi,eax |
817 | pop eax |
817 | pop eax |
818 | 818 | ||
819 | mov ecx, 512/4 |
819 | mov ecx, 512/4 |
820 | cld |
820 | cld |
821 | rep movsd |
821 | rep movsd |
822 | pop edi esi ecx |
822 | pop edi esi ecx |
823 | pop edx |
823 | pop edx |
824 | pop eax |
824 | pop eax |
825 | ret |
825 | ret |
826 | .notread: |
826 | .notread: |
827 | push ecx |
827 | push ecx |
828 | mov dl, 42h |
828 | mov dl, 42h |
829 | mov ecx, 16 |
829 | mov ecx, 16 |
830 | call int13_call |
830 | call int13_call |
831 | pop ecx |
831 | pop ecx |
832 | test eax, eax |
832 | test eax, eax |
833 | jnz .v86err |
833 | jnz .v86err |
834 | test edx, edx |
834 | test edx, edx |
835 | jz .readerr |
835 | jz .readerr |
836 | mov [bios_read_len], edx |
836 | mov [bios_read_len], edx |
837 | mov edx, [hdpos] |
837 | mov edx, [hdpos] |
838 | mov [bios_hdpos], edx |
838 | mov [bios_hdpos], edx |
839 | pop edx |
839 | pop edx |
840 | pop eax |
840 | pop eax |
841 | mov [bios_cur_sector], eax |
841 | mov [bios_cur_sector], eax |
842 | jmp bd_read |
842 | jmp bd_read |
843 | .readerr: |
843 | .readerr: |
844 | .v86err: |
844 | .v86err: |
845 | mov [hd_error], 1 |
845 | mov [hd_error], 1 |
846 | jmp hd_read_error |
846 | jmp hd_read_error |
847 | 847 | ||
848 | bd_write_cache_chain: |
848 | bd_write_cache_chain: |
849 | pusha |
849 | pusha |
850 | mov esi, [cache_chain_pos] |
850 | mov esi, [cache_chain_pos] |
851 | shl esi, 9 |
851 | shl esi, 9 |
852 | call calculate_cache_2 |
852 | call calculate_cache_2 |
853 | add esi, eax |
853 | add esi, eax |
854 | mov edi, OS_BASE + 0x9C000 |
854 | mov edi, OS_BASE + 0x9C000 |
855 | movzx ecx, [cache_chain_size] |
855 | movzx ecx, [cache_chain_size] |
856 | push ecx |
856 | push ecx |
857 | shl ecx, 9-2 |
857 | shl ecx, 9-2 |
858 | rep movsd |
858 | rep movsd |
859 | pop ecx |
859 | pop ecx |
860 | mov dl, 43h |
860 | mov dl, 43h |
861 | mov eax, [cache_chain_ptr] |
861 | mov eax, [cache_chain_ptr] |
862 | mov eax, [eax] |
862 | mov eax, [eax] |
863 | call int13_call |
863 | call int13_call |
864 | test eax, eax |
864 | test eax, eax |
865 | jnz .v86err |
865 | jnz .v86err |
866 | cmp edx, ecx |
866 | cmp edx, ecx |
867 | jnz .writeerr |
867 | jnz .writeerr |
868 | popa |
868 | popa |
869 | ret |
869 | ret |
870 | .v86err: |
870 | .v86err: |
871 | .writeerr: |
871 | .writeerr: |
872 | popa |
872 | popa |
873 | mov [hd_error], 1 |
873 | mov [hd_error], 1 |
874 | jmp hd_write_error |
874 | jmp hd_write_error |
875 | 875 | ||
876 | uglobal |
876 | uglobal |
877 | int13_regs_in rb v86_regs.size |
877 | int13_regs_in rb v86_regs.size |
878 | int13_regs_out rb v86_regs.size |
878 | int13_regs_out rb v86_regs.size |
879 | endg |
879 | endg |
880 | 880 | ||
881 | int13_call: |
881 | int13_call: |
882 | ; Because this code uses fixed addresses, |
882 | ; Because this code uses fixed addresses, |
883 | ; it can not be run simultaniously by many threads. |
883 | ; it can not be run simultaniously by many threads. |
884 | ; In current implementation it is protected by common mutex 'hd1_status' |
884 | ; In current implementation it is protected by common mutex 'hd1_status' |
885 | mov word [BOOT_VAR + 510h], 10h ; packet length |
885 | mov word [BOOT_VAR + 510h], 10h ; packet length |
886 | mov word [BOOT_VAR + 512h], cx ; number of sectors |
886 | mov word [BOOT_VAR + 512h], cx ; number of sectors |
887 | mov dword [BOOT_VAR + 514h], 9C000000h ; buffer 9C00:0000 |
887 | mov dword [BOOT_VAR + 514h], 9C000000h ; buffer 9C00:0000 |
888 | mov dword [BOOT_VAR + 518h], eax |
888 | mov dword [BOOT_VAR + 518h], eax |
889 | and dword [BOOT_VAR + 51Ch], 0 |
889 | and dword [BOOT_VAR + 51Ch], 0 |
890 | push ebx ecx esi edi |
890 | push ebx ecx esi edi |
891 | mov ebx, int13_regs_in |
891 | mov ebx, int13_regs_in |
892 | mov edi, ebx |
892 | mov edi, ebx |
893 | mov ecx, v86_regs.size/4 |
893 | mov ecx, v86_regs.size/4 |
894 | xor eax, eax |
894 | xor eax, eax |
895 | rep stosd |
895 | rep stosd |
896 | mov byte [ebx+v86_regs.eax+1], dl |
896 | mov byte [ebx+v86_regs.eax+1], dl |
897 | mov eax, [hdpos] |
897 | mov eax, [hdpos] |
898 | lea eax, [BiosDisksData+(eax-80h)*4] |
898 | lea eax, [BiosDisksData+(eax-80h)*4] |
899 | mov dl, [eax] |
899 | mov dl, [eax] |
900 | mov byte [ebx+v86_regs.edx], dl |
900 | mov byte [ebx+v86_regs.edx], dl |
901 | movzx edx, byte [eax+1] |
901 | movzx edx, byte [eax+1] |
902 | ; mov dl, 5 |
902 | ; mov dl, 5 |
903 | test edx, edx |
903 | test edx, edx |
904 | jnz .hasirq |
904 | jnz .hasirq |
905 | dec edx |
905 | dec edx |
906 | jmp @f |
906 | jmp @f |
907 | .hasirq: |
907 | .hasirq: |
908 | pushad |
908 | pushad |
909 | stdcall enable_irq, edx |
909 | stdcall enable_irq, edx |
910 | popad |
910 | popad |
911 | @@: |
911 | @@: |
912 | mov word [ebx+v86_regs.esi], 510h |
912 | mov word [ebx+v86_regs.esi], 510h |
- | 913 | mov word [ebx+v86_regs.ss], 9000h |
|
913 | mov word [ebx+v86_regs.esp], 900h |
914 | mov word [ebx+v86_regs.esp], 0C000h |
914 | mov word [ebx+v86_regs.eip], 500h |
915 | mov word [ebx+v86_regs.eip], 500h |
915 | mov [ebx+v86_regs.eflags], 20200h |
916 | mov [ebx+v86_regs.eflags], 20200h |
916 | mov esi, [sys_v86_machine] |
917 | mov esi, [sys_v86_machine] |
917 | mov ecx, 0x502 |
918 | mov ecx, 0x502 |
918 | call v86_start |
919 | call v86_start |
919 | and [bios_hdpos], 0 |
920 | and [bios_hdpos], 0 |
920 | pop edi esi ecx ebx |
921 | pop edi esi ecx ebx |
921 | movzx edx, byte [BOOT_VAR + 512h] |
922 | movzx edx, byte [BOOT_VAR + 512h] |
922 | test byte [int13_regs_out+v86_regs.eflags], 1 |
923 | test byte [int13_regs_out+v86_regs.eflags], 1 |
923 | jnz @f |
924 | jnz @f |
924 | mov edx, ecx |
925 | mov edx, ecx |
925 | @@: |
926 | @@: |
926 | ret |
927 | ret |
927 | ; \end{diamond} |
928 | ; \end{diamond} |