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