Rev 4465 | Rev 5095 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4465 | Rev 5089 | ||
---|---|---|---|
Line 3... | Line 3... | ||
3 | ;; Copyright (C) KolibriOS team 2011-2014. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2011-2014. 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 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 7... | Line 7... | ||
7 | 7 | ||
Line 8... | Line 8... | ||
8 | $Revision: 4465 $ |
8 | $Revision: 5089 $ |
9 | 9 | ||
10 | ; Read/write functions try to do large operations, |
10 | ; Read/write functions try to do large operations, |
11 | ; it is significantly faster than several small operations. |
11 | ; it is significantly faster than several small operations. |
Line 116... | Line 116... | ||
116 | mov eax, dword [ebp+PARTITION.FirstSector] |
116 | mov eax, dword [ebp+PARTITION.FirstSector] |
117 | mov edx, dword [ebp+PARTITION.FirstSector+4] |
117 | mov edx, dword [ebp+PARTITION.FirstSector+4] |
118 | add [.sector_lo], eax |
118 | add [.sector_lo], eax |
119 | adc [.sector_hi], edx |
119 | adc [.sector_hi], edx |
120 | ; 5. If the cache is disabled, pass the request directly to the driver. |
120 | ; 5. If the cache is disabled, pass the request directly to the driver. |
121 | mov edi, [.buffer] |
- | |
122 | cmp [ebx+DISKCACHE.pointer], 0 |
121 | cmp [ebx+DISKCACHE.pointer], 0 |
123 | jz .nocache |
122 | jz .nocache |
124 | ; 6. Look for sectors in the cache, sequentially from the beginning. |
123 | ; 6. Look for sectors in the cache, sequentially from the beginning. |
125 | ; Stop at the first sector that is not in the cache |
124 | ; Stop at the first sector that is not in the cache |
126 | ; or when all sectors were read from the cache. |
125 | ; or when all sectors were read from the cache. |
Line 135... | Line 134... | ||
135 | call cache_lookup_read |
134 | call cache_lookup_read |
136 | ; 6c. If it has failed, the sector is not in cache; |
135 | ; 6c. If it has failed, the sector is not in cache; |
137 | ; release the lock and go to 7. |
136 | ; release the lock and go to 7. |
138 | jc .not_found_in_cache |
137 | jc .not_found_in_cache |
139 | ; The sector is found in cache. |
138 | ; The sector is found in cache. |
140 | ; 6d. Copy data for the caller. |
139 | ; 6d. Copy data for the caller, advance [.buffer]. |
- | 140 | mov esi, edi |
|
141 | ; Note that buffer in edi is advanced automatically. |
141 | mov edi, [.buffer] |
142 | mov esi, ecx |
142 | mov eax, 1 |
143 | shl esi, 9 |
143 | shl eax, cl |
144 | add esi, [ebx+DISKCACHE.data] |
144 | mov ecx, eax |
145 | mov ecx, 512/4 |
145 | shr ecx, 2 |
146 | rep movsd |
146 | rep movsd |
- | 147 | mov [.buffer], edi |
|
147 | ; 6e. Advance the sector. |
148 | ; 6e. Advance the sector. |
148 | add [.sector_lo], 1 |
149 | add [.sector_lo], 1 |
149 | adc [.sector_hi], 0 |
150 | adc [.sector_hi], 0 |
150 | ; 6f. Decrement number of sectors left. |
151 | ; 6f. Decrement number of sectors left. |
151 | ; If all sectors were read, release the lock and return. |
152 | ; If all sectors were read, release the lock and return. |
Line 175... | Line 176... | ||
175 | ; 7. Allocate buffer for operations. |
176 | ; 7. Allocate buffer for operations. |
176 | ; Normally, create buffer that is sufficient for all remaining data. |
177 | ; Normally, create buffer that is sufficient for all remaining data. |
177 | ; However, for extra-large requests make an upper limit: |
178 | ; However, for extra-large requests make an upper limit: |
178 | ; do not use more than half of the free memory |
179 | ; do not use more than half of the free memory |
179 | ; or more than CACHE_MAX_ALLOC_SIZE bytes. |
180 | ; or more than CACHE_MAX_ALLOC_SIZE bytes. |
- | 181 | mov ecx, [ebx+DISKCACHE.sector_size_log] |
|
180 | mov ebx, [pg_data.pages_free] |
182 | mov ebx, [pg_data.pages_free] |
181 | shr ebx, 1 |
183 | shr ebx, 1 |
182 | jz .nomemory |
184 | jz .nomemory |
183 | cmp ebx, CACHE_MAX_ALLOC_SIZE shr 12 |
185 | cmp ebx, CACHE_MAX_ALLOC_SIZE shr 12 |
184 | jbe @f |
186 | jbe @f |
185 | mov ebx, CACHE_MAX_ALLOC_SIZE shr 12 |
187 | mov ebx, CACHE_MAX_ALLOC_SIZE shr 12 |
186 | @@: |
188 | @@: |
187 | shl ebx, 12 - 9 |
189 | shl ebx, 12 |
- | 190 | shr ebx, cl |
|
- | 191 | jz .nomemory |
|
188 | cmp ebx, [.num_sectors] |
192 | cmp ebx, [.num_sectors] |
189 | jbe @f |
193 | jbe @f |
190 | mov ebx, [.num_sectors] |
194 | mov ebx, [.num_sectors] |
191 | @@: |
195 | @@: |
192 | mov eax, ebx |
196 | mov eax, ebx |
193 | shl eax, 9 |
197 | shl eax, cl |
194 | stdcall kernel_alloc, eax |
198 | stdcall kernel_alloc, eax |
195 | ; If failed, return the appropriate error code. |
199 | ; If failed, return the appropriate error code. |
196 | test eax, eax |
200 | test eax, eax |
197 | jz .nomemory |
201 | jz .nomemory |
198 | mov esi, eax |
202 | mov esi, eax |
Line 231... | Line 235... | ||
231 | ; If failed, save error code. |
235 | ; If failed, save error code. |
232 | test eax, eax |
236 | test eax, eax |
233 | jz @f |
237 | jz @f |
234 | mov [.error_code+.local_vars2_size], eax |
238 | mov [.error_code+.local_vars2_size], eax |
235 | @@: |
239 | @@: |
236 | ; 11. Copy data for the caller. |
240 | ; 11. Copy data for the caller, advance .buffer. |
237 | ; Note that buffer in edi is advanced automatically. |
- | |
238 | cmp [.current_num_sectors], 0 |
241 | cmp [.current_num_sectors], 0 |
239 | jz .copy_done |
242 | jz .copy_done |
- | 243 | mov ebx, [.cache+.local_vars2_size] |
|
240 | mov ecx, [.current_num_sectors] |
244 | mov eax, [.current_num_sectors] |
- | 245 | mov ecx, [ebx+DISKCACHE.sector_size_log] |
|
241 | shl ecx, 9-2 |
246 | shl eax, cl |
242 | mov esi, [.allocated_buffer] |
247 | mov esi, [.allocated_buffer] |
- | 248 | mov edi, [.buffer+.local_vars2_size] |
|
- | 249 | mov ecx, eax |
|
- | 250 | shr ecx, 2 |
|
243 | rep movsd |
251 | rep movsd |
- | 252 | mov [.buffer+.local_vars2_size], edi |
|
244 | ; 12. Copy data to the cache. |
253 | ; 12. Copy data to the cache. |
245 | ; 12a. Acquire the lock. |
254 | ; 12a. Acquire the lock. |
246 | mov ebx, [.cache+.local_vars2_size] |
- | |
247 | mov ecx, [ebp+PARTITION.Disk] |
255 | mov ecx, [ebp+PARTITION.Disk] |
248 | add ecx, DISK.CacheLock |
256 | add ecx, DISK.CacheLock |
249 | call mutex_lock |
257 | call mutex_lock |
250 | ; 12b. Prepare for the loop: save edi and create a local variable that |
258 | ; 12b. Prepare for the loop: create a local variable that |
251 | ; stores number of sectors to be copied. |
259 | ; stores number of sectors to be copied. |
252 | push edi |
- | |
253 | push [.current_num_sectors+4] |
260 | push [.current_num_sectors] |
254 | .store_to_cache: |
261 | .store_to_cache: |
255 | ; 12c. For each sector, call the lookup function with adding to the cache, if not yet. |
262 | ; 12c. For each sector, call the lookup function with adding to the cache, if not yet. |
256 | mov eax, [.sector_lo+.local_vars2_size+8] |
263 | mov eax, [.sector_lo+.local_vars2_size+4] |
257 | mov edx, [.sector_hi+.local_vars2_size+8] |
264 | mov edx, [.sector_hi+.local_vars2_size+4] |
258 | call cache_lookup_write |
265 | call cache_lookup_write |
259 | test eax, eax |
266 | test eax, eax |
260 | jnz .cache_error |
267 | jnz .cache_error |
261 | ; 12d. If the sector was already present in the cache as modified, |
268 | ; 12d. If the sector was already present in the cache as modified, |
262 | ; data that were read at step 10 for this sector are obsolete, |
269 | ; data that were read at step 10 for this sector are obsolete, |
263 | ; so rewrite data for the caller from the cache. |
270 | ; so rewrite data for the caller from the cache. |
264 | cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED |
271 | cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED |
265 | jnz .not_modified |
272 | jnz .not_modified |
266 | mov esi, ecx |
273 | mov esi, edi |
- | 274 | mov edi, [.buffer+.local_vars2_size+4] |
|
267 | shl esi, 9 |
275 | mov eax, [esp] |
268 | add esi, [ebx+DISKCACHE.data] |
276 | shl eax, cl |
269 | mov edi, [esp+4] |
277 | sub edi, eax |
270 | mov ecx, [esp] |
278 | mov eax, 1 |
271 | shl ecx, 9-2 |
279 | shl eax, cl |
272 | sub edi, ecx |
280 | mov ecx, eax |
273 | mov ecx, 512/4 |
281 | shr ecx, 2 |
274 | rep movsd |
282 | rep movsd |
275 | add [.current_buffer+8], 512 |
283 | add [.current_buffer+4], eax |
276 | jmp .sector_done |
284 | jmp .sector_done |
277 | .not_modified: |
285 | .not_modified: |
278 | ; 12e. For each not-modified sector, |
286 | ; 12e. For each not-modified sector, |
279 | ; copy data, mark the item as not-modified copy of the disk, |
287 | ; copy data, mark the item as not-modified copy of the disk, |
280 | ; advance .current_buffer and .sector_hi:.sector_lo to the next sector. |
288 | ; advance .current_buffer and .sector_hi:.sector_lo to the next sector. |
281 | mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY |
289 | mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY |
282 | mov esi, [.current_buffer+8] |
290 | mov eax, 1 |
283 | mov edi, ecx |
291 | shl eax, cl |
284 | shl edi, 9 |
292 | mov esi, [.current_buffer+4] |
285 | add edi, [ebx+DISKCACHE.data] |
293 | mov ecx, eax |
286 | mov ecx, 512/4 |
294 | shr ecx, 2 |
287 | rep movsd |
295 | rep movsd |
288 | mov [.current_buffer+8], esi |
296 | mov [.current_buffer+4], esi |
289 | .sector_done: |
297 | .sector_done: |
290 | add [.sector_lo+.local_vars2_size+8], 1 |
298 | add [.sector_lo+.local_vars2_size+4], 1 |
291 | adc [.sector_hi+.local_vars2_size+8], 0 |
299 | adc [.sector_hi+.local_vars2_size+4], 0 |
292 | ; 12f. Continue the loop 12c-12e until all sectors are read. |
300 | ; 12f. Continue the loop 12c-12e until all sectors are read. |
293 | dec dword [esp] |
301 | dec dword [esp] |
294 | jnz .store_to_cache |
302 | jnz .store_to_cache |
295 | .cache_error: |
303 | .cache_error: |
296 | ; 12g. Restore after the loop: pop the local variable and restore edi. |
304 | ; 12g. Restore after the loop: pop the local variable. |
297 | pop ecx |
305 | pop ecx |
298 | pop edi |
- | |
299 | ; 12h. Release the lock. |
306 | ; 12h. Release the lock. |
300 | mov ecx, [ebp+PARTITION.Disk] |
307 | mov ecx, [ebp+PARTITION.Disk] |
301 | add ecx, DISK.CacheLock |
308 | add ecx, DISK.CacheLock |
302 | call mutex_unlock |
309 | call mutex_unlock |
303 | .copy_done: |
310 | .copy_done: |
Line 326... | Line 333... | ||
326 | ; sees that cache is disabled: pass corrected request to the driver |
333 | ; sees that cache is disabled: pass corrected request to the driver |
327 | lea eax, [.num_sectors] |
334 | lea eax, [.num_sectors] |
328 | push eax ; numsectors |
335 | push eax ; numsectors |
329 | push [.sector_hi+4] ; startsector |
336 | push [.sector_hi+4] ; startsector |
330 | push [.sector_lo+8] ; startsector |
337 | push [.sector_lo+8] ; startsector |
331 | push edi ; buffer |
338 | push [.buffer+12] ; buffer |
332 | mov esi, [ebp+PARTITION.Disk] |
339 | mov esi, [ebp+PARTITION.Disk] |
333 | mov al, DISKFUNC.read |
340 | mov al, DISKFUNC.read |
334 | call disk_call_driver |
341 | call disk_call_driver |
335 | test eax, eax |
342 | test eax, eax |
336 | jnz @f |
343 | jnz @f |
Line 438... | Line 445... | ||
438 | test eax, eax |
445 | test eax, eax |
439 | jnz .cache_error |
446 | jnz .cache_error |
440 | ; 6c. For each sector, copy data, mark the item as modified and not saved, |
447 | ; 6c. For each sector, copy data, mark the item as modified and not saved, |
441 | ; advance .current_buffer to the next sector. |
448 | ; advance .current_buffer to the next sector. |
442 | mov [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED |
449 | mov [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED |
- | 450 | mov eax, 1 |
|
- | 451 | shl eax, cl |
|
443 | mov esi, [.cur_buffer] |
452 | mov esi, [.cur_buffer] |
444 | mov edi, ecx |
453 | mov ecx, eax |
445 | shl edi, 9 |
454 | shr ecx, 2 |
446 | add edi, [ebx+DISKCACHE.data] |
- | |
447 | mov ecx, 512/4 |
- | |
448 | rep movsd |
455 | rep movsd |
449 | mov [.cur_buffer], esi |
456 | mov [.cur_buffer], esi |
450 | ; 6d. Remove the sector from the other cache. |
457 | ; 6d. Remove the sector from the other cache. |
451 | ; Normally it should not be there, but prefetching could put to the app cache |
458 | ; Normally it should not be there, but prefetching could put to the app cache |
452 | ; data that normally should belong to the sys cache and vice versa. |
459 | ; data that normally should belong to the sys cache and vice versa. |
Line 590... | Line 597... | ||
590 | call cache_lookup_read |
597 | call cache_lookup_read |
591 | ; If not found, go to 5. |
598 | ; If not found, go to 5. |
592 | jc .not_found_in_cache |
599 | jc .not_found_in_cache |
593 | .found_in_cache: |
600 | .found_in_cache: |
594 | ; 4c. Copy the data. |
601 | ; 4c. Copy the data. |
- | 602 | mov esi, edi |
|
595 | mov edi, [.buffer] |
603 | mov edi, [.buffer] |
596 | mov esi, ecx |
604 | mov eax, 1 |
597 | shl esi, 9 |
605 | shl eax, cl |
598 | add esi, [ebx+DISKCACHE.data] |
606 | mov ecx, eax |
599 | mov ecx, 512/4 |
607 | shr ecx, 2 |
600 | rep movsd |
608 | rep movsd |
601 | ; 4d. Release the lock and return success. |
609 | ; 4d. Release the lock and return success. |
602 | mov ecx, [ebp+PARTITION.Disk] |
610 | mov ecx, [ebp+PARTITION.Disk] |
603 | add ecx, DISK.CacheLock |
611 | add ecx, DISK.CacheLock |
604 | call mutex_unlock |
612 | call mutex_unlock |
Line 625... | Line 633... | ||
625 | ; 6. Release the lock acquired at step 4a. |
633 | ; 6. Release the lock acquired at step 4a. |
626 | mov ecx, [ebp+PARTITION.Disk] |
634 | mov ecx, [ebp+PARTITION.Disk] |
627 | add ecx, DISK.CacheLock |
635 | add ecx, DISK.CacheLock |
628 | call mutex_unlock |
636 | call mutex_unlock |
629 | ; 7. Allocate buffer for CACHE_LEGACY_READ_SIZE sectors. |
637 | ; 7. Allocate buffer for CACHE_LEGACY_READ_SIZE sectors. |
630 | stdcall kernel_alloc, CACHE_LEGACY_READ_SIZE shl 9 |
638 | mov eax, CACHE_LEGACY_READ_SIZE |
- | 639 | mov ecx, [ebx+DISKCACHE.sector_size_log] |
|
- | 640 | shl eax, cl |
|
- | 641 | stdcall kernel_alloc, eax |
|
631 | ; If failed, return the corresponding error code. |
642 | ; If failed, return the corresponding error code. |
632 | test eax, eax |
643 | test eax, eax |
633 | jz .nomemory |
644 | jz .nomemory |
634 | ; 8. Create second portion of local variables. |
645 | ; 8. Create second portion of local variables. |
635 | push eax eax |
646 | push eax eax |
Line 654... | Line 665... | ||
654 | cmp [.num_sectors], 0 |
665 | cmp [.num_sectors], 0 |
655 | jz .read_error |
666 | jz .read_error |
656 | ; 10. Copy data for the caller. |
667 | ; 10. Copy data for the caller. |
657 | mov esi, [.allocated_buffer] |
668 | mov esi, [.allocated_buffer] |
658 | mov edi, [.buffer+.local_vars2_size] |
669 | mov edi, [.buffer+.local_vars2_size] |
- | 670 | mov ecx, [ebx+DISKCACHE.sector_size_log] |
|
- | 671 | mov eax, 1 |
|
- | 672 | shl eax, cl |
|
659 | mov ecx, 512/4 |
673 | mov ecx, eax |
- | 674 | shr ecx, 2 |
|
660 | rep movsd |
675 | rep movsd |
661 | ; 11. Store all sectors that were successfully read to the cache. |
676 | ; 11. Store all sectors that were successfully read to the cache. |
662 | ; 11a. Acquire the lock. |
677 | ; 11a. Acquire the lock. |
663 | mov ecx, [ebp+PARTITION.Disk] |
678 | mov ecx, [ebp+PARTITION.Disk] |
664 | add ecx, DISK.CacheLock |
679 | add ecx, DISK.CacheLock |
Line 669... | Line 684... | ||
669 | mov edx, [.sector_hi+.local_vars2_size] |
684 | mov edx, [.sector_hi+.local_vars2_size] |
670 | call cache_lookup_write |
685 | call cache_lookup_write |
671 | test eax, eax |
686 | test eax, eax |
672 | jnz .cache_error |
687 | jnz .cache_error |
673 | ; 11c. Ignore sectors marked as modified: for them the cache is more recent that disk data. |
688 | ; 11c. Ignore sectors marked as modified: for them the cache is more recent that disk data. |
- | 689 | mov eax, 1 |
|
- | 690 | shl eax, cl |
|
674 | cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED |
691 | cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED |
675 | jnz .not_modified |
692 | jnz .not_modified |
676 | add [.current_buffer], 512 |
693 | add [.current_buffer], eax |
677 | jmp .sector_done |
694 | jmp .sector_done |
678 | .not_modified: |
695 | .not_modified: |
679 | ; 11d. For each sector, copy data, mark the item as not-modified copy of the disk, |
696 | ; 11d. For each sector, copy data, mark the item as not-modified copy of the disk, |
680 | ; advance .current_buffer and .sector_hi:.sector_lo to the next sector. |
697 | ; advance .current_buffer and .sector_hi:.sector_lo to the next sector. |
681 | mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY |
698 | mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY |
682 | mov esi, [.current_buffer] |
699 | mov esi, [.current_buffer] |
683 | mov edi, ecx |
700 | mov ecx, eax |
684 | shl edi, 9 |
701 | shr ecx, 2 |
685 | add edi, [ebx+DISKCACHE.data] |
- | |
686 | mov ecx, 512/4 |
- | |
687 | rep movsd |
702 | rep movsd |
688 | mov [.current_buffer], esi |
703 | mov [.current_buffer], esi |
689 | .sector_done: |
704 | .sector_done: |
690 | add [.sector_lo+.local_vars2_size], 1 |
705 | add [.sector_lo+.local_vars2_size], 1 |
691 | adc [.sector_hi+.local_vars2_size], 0 |
706 | adc [.sector_hi+.local_vars2_size], 0 |
Line 719... | Line 734... | ||
719 | ; We are still holding the lock acquired at step 4a. |
734 | ; We are still holding the lock acquired at step 4a. |
720 | ; 13. Call the lookup function adding sector to the cache. |
735 | ; 13. Call the lookup function adding sector to the cache. |
721 | call cache_lookup_write |
736 | call cache_lookup_write |
722 | test eax, eax |
737 | test eax, eax |
723 | jnz .floppy_cache_error |
738 | jnz .floppy_cache_error |
724 | push ecx |
739 | push esi |
Line 725... | Line 740... | ||
725 | 740 | ||
726 | ; 14. Call the driver to read one sector. |
741 | ; 14. Call the driver to read one sector. |
727 | push 1 |
742 | push 1 |
728 | push esp |
743 | push esp |
729 | push edx |
744 | push edx |
730 | push [.sector_lo+16] |
- | |
731 | shl ecx, 9 |
- | |
732 | add ecx, [ebx+DISKCACHE.data] |
745 | push [.sector_lo+16] |
733 | push ecx |
746 | push edi |
734 | mov esi, [ebp+PARTITION.Disk] |
747 | mov esi, [ebp+PARTITION.Disk] |
735 | mov al, DISKFUNC.read |
748 | mov al, DISKFUNC.read |
736 | call disk_call_driver |
749 | call disk_call_driver |
737 | pop ecx |
750 | pop ecx |
738 | dec ecx |
751 | dec ecx |
739 | jnz .floppy_read_error |
752 | jnz .floppy_read_error |
740 | ; 15. Get the slot and pointer to the cache item, |
753 | ; 15. Get the slot and pointer to the cache item, |
741 | ; change the status to not-modified copy of the disk |
754 | ; change the status to not-modified copy of the disk |
742 | ; and go to 4c. |
755 | ; and go to 4c. |
743 | pop ecx |
- | |
744 | lea esi, [ecx*sizeof.CACHE_ITEM/4] |
- | |
745 | shl esi, 2 |
- | |
746 | add esi, [ebx+DISKCACHE.pointer] |
756 | pop esi |
747 | mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY |
757 | mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY |
Line 748... | Line 758... | ||
748 | jmp .found_in_cache |
758 | jmp .found_in_cache |
749 | 759 | ||
Line 793... | Line 803... | ||
793 | ; If the sector is not present, return error. |
803 | ; If the sector is not present, return error. |
794 | ; The caller must acquire the cache lock. |
804 | ; The caller must acquire the cache lock. |
795 | ; in: edx:eax = sector |
805 | ; in: edx:eax = sector |
796 | ; in: ebx -> DISKCACHE structure |
806 | ; in: ebx -> DISKCACHE structure |
797 | ; out: CF set if sector is not in cache |
807 | ; out: CF set if sector is not in cache |
798 | ; out: ecx = index in cache |
808 | ; out: ecx = sector_size_log |
799 | ; out: esi -> sector:status |
809 | ; out: esi -> sector:status |
- | 810 | ; out: edi -> sector data |
|
800 | proc cache_lookup_read |
811 | proc cache_lookup_read |
801 | mov esi, [ebx+DISKCACHE.pointer] |
812 | mov esi, [ebx+DISKCACHE.pointer] |
802 | add esi, sizeof.CACHE_ITEM |
813 | add esi, sizeof.CACHE_ITEM |
Line 803... | Line 814... | ||
803 | 814 | ||
Line 804... | Line 815... | ||
804 | mov ecx, 1 |
815 | mov edi, 1 |
Line 805... | Line 816... | ||
805 | 816 | ||
806 | .hdreadcache: |
817 | .hdreadcache: |
Line 807... | Line 818... | ||
807 | 818 | ||
808 | cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY |
819 | cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY |
809 | je .nohdcache |
820 | je .nohdcache |
810 | 821 | ||
- | 822 | cmp [esi+CACHE_ITEM.SectorLo], eax |
|
- | 823 | jne .nohdcache |
|
- | 824 | cmp [esi+CACHE_ITEM.SectorHi], edx |
|
811 | cmp [esi+CACHE_ITEM.SectorLo], eax |
825 | jne .nohdcache |
812 | jne .nohdcache |
826 | mov ecx, [ebx+DISKCACHE.sector_size_log] |
Line 813... | Line 827... | ||
813 | cmp [esi+CACHE_ITEM.SectorHi], edx |
827 | shl edi, cl |
Line 814... | Line 828... | ||
814 | jne .nohdcache |
828 | add edi, [ebx+DISKCACHE.data] |
815 | clc |
829 | clc |
816 | ret |
830 | ret |
817 | 831 | ||
818 | .nohdcache: |
832 | .nohdcache: |
819 | 833 | ||
820 | add esi, sizeof.CACHE_ITEM |
834 | add esi, sizeof.CACHE_ITEM |
Line 830... | Line 844... | ||
830 | ; possibly flushing data. |
844 | ; possibly flushing data. |
831 | ; in: edx:eax = sector |
845 | ; in: edx:eax = sector |
832 | ; in: ebx -> DISKCACHE structure |
846 | ; in: ebx -> DISKCACHE structure |
833 | ; in: ebp -> PARTITION structure |
847 | ; in: ebp -> PARTITION structure |
834 | ; out: eax = error code |
848 | ; out: eax = error code |
835 | ; out: ecx = index in cache |
- | |
836 | ; out: esi -> sector:status |
849 | ; out: esi -> sector:status |
- | 850 | ; out: edi -> sector data |
|
837 | proc cache_lookup_write |
851 | proc cache_lookup_write |
838 | call cache_lookup_read |
852 | call cache_lookup_read |
839 | jnc .return0 |
853 | jnc .return0 |
840 | push edx eax |
854 | push edx eax |
841 | ;----------------------------------------------------------- |
855 | ;----------------------------------------------------------- |
Line 872... | Line 886... | ||
872 | .found_slot: |
886 | .found_slot: |
873 | mov [ebx+DISKCACHE.search_start], ecx |
887 | mov [ebx+DISKCACHE.search_start], ecx |
874 | popd [esi+CACHE_ITEM.SectorLo] |
888 | popd [esi+CACHE_ITEM.SectorLo] |
875 | popd [esi+CACHE_ITEM.SectorHi] |
889 | popd [esi+CACHE_ITEM.SectorHi] |
876 | mov [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY |
890 | mov [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY |
- | 891 | mov edi, ecx |
|
- | 892 | mov ecx, [ebx+DISKCACHE.sector_size_log] |
|
- | 893 | shl edi, cl |
|
- | 894 | add edi, [ebx+DISKCACHE.data] |
|
877 | .return0: |
895 | .return0: |
878 | xor eax, eax ; success |
896 | xor eax, eax ; success |
879 | ret |
897 | ret |
880 | .found_slot_access_denied: |
898 | .found_slot_access_denied: |
881 | add esp, 8 |
899 | add esp, 8 |
Line 900... | Line 918... | ||
900 | ; one chain describes a sequential interval of sectors, |
918 | ; one chain describes a sequential interval of sectors, |
901 | ; they can be sequential or scattered in the cache. |
919 | ; they can be sequential or scattered in the cache. |
902 | .sequential dd ? |
920 | .sequential dd ? |
903 | ; boolean variable, 1 if the current chain is sequential in the cache, |
921 | ; boolean variable, 1 if the current chain is sequential in the cache, |
904 | ; 0 if additional buffer is needed to perform the operation |
922 | ; 0 if additional buffer is needed to perform the operation |
905 | .chain_start_pos dd ? ; slot of chain start item |
923 | .chain_start_pos dd ? ; data of chain start item |
906 | .chain_start_ptr dd ? ; pointer to chain start item |
924 | .chain_start_ptr dd ? ; pointer to chain start item |
907 | .chain_size dd ? ; chain size (thanks, C.O.) |
925 | .chain_size dd ? ; chain size (thanks, C.O.) |
908 | .iteration_size dd ? |
926 | .iteration_size dd ? |
909 | ; If the chain size is too large, split the operation to several iterations. |
927 | ; If the chain size is too large, split the operation to several iterations. |
910 | ; This is size in sectors for one iterations. |
928 | ; This is size in sectors for one iterations. |
Line 949... | Line 967... | ||
949 | ; Initialize chain as sequential zero-length starting at the current item. |
967 | ; Initialize chain as sequential zero-length starting at the current item. |
950 | mov [.chain_start_ptr], esi |
968 | mov [.chain_start_ptr], esi |
951 | mov eax, [ebx+DISKCACHE.sad_size] |
969 | mov eax, [ebx+DISKCACHE.sad_size] |
952 | sub eax, [.size_left] |
970 | sub eax, [.size_left] |
953 | inc eax |
971 | inc eax |
- | 972 | mov ecx, [ebx+DISKCACHE.sector_size_log] |
|
- | 973 | shl eax, cl |
|
- | 974 | add eax, [ebx+DISKCACHE.data] |
|
954 | mov [.chain_start_pos], eax |
975 | mov [.chain_start_pos], eax |
955 | mov [.chain_size], 0 |
976 | mov [.chain_size], 0 |
956 | mov [.sequential], 1 |
977 | mov [.sequential], 1 |
957 | ; 6. Expand the chain backward. |
978 | ; 6. Expand the chain backward. |
958 | ; Note: the main loop in step 2 looks for items sequentially, |
979 | ; Note: the main loop in step 2 looks for items sequentially, |
Line 976... | Line 997... | ||
976 | ; It makes the chain non-sequential. |
997 | ; It makes the chain non-sequential. |
977 | ; Normally, sectors come in sequential blocks, so try to look at previous items |
998 | ; Normally, sectors come in sequential blocks, so try to look at previous items |
978 | ; before returning to 6b; if there is a sequential block indeed, this saves some |
999 | ; before returning to 6b; if there is a sequential block indeed, this saves some |
979 | ; time instead of many full-fledged lookups. |
1000 | ; time instead of many full-fledged lookups. |
980 | mov [.sequential], 0 |
1001 | mov [.sequential], 0 |
981 | mov [.chain_start_pos], ecx |
1002 | mov [.chain_start_pos], edi |
982 | .look_backward: |
1003 | .look_backward: |
983 | ; 6e. For each sector, update chain start pos/ptr, decrement sector number, |
1004 | ; 6e. For each sector, update chain start pos/ptr, decrement sector number, |
984 | ; look at the previous item. |
1005 | ; look at the previous item. |
985 | mov [.chain_start_ptr], esi |
1006 | mov [.chain_start_ptr], esi |
986 | inc [.chain_size] |
1007 | inc [.chain_size] |
Line 999... | Line 1020... | ||
999 | cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED |
1020 | cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED |
1000 | jnz .found_chain_start |
1021 | jnz .found_chain_start |
1001 | ; ...expand the chain one sector backwards and continue the loop at 6e. |
1022 | ; ...expand the chain one sector backwards and continue the loop at 6e. |
1002 | ; Otherwise, advance to step 7 if the previous item describes the correct sector |
1023 | ; Otherwise, advance to step 7 if the previous item describes the correct sector |
1003 | ; but is not modified, and return to step 6b otherwise. |
1024 | ; but is not modified, and return to step 6b otherwise. |
- | 1025 | mov edi, 1 |
|
- | 1026 | shl edi, cl |
|
1004 | dec [.chain_start_pos] |
1027 | sub [.chain_start_pos], edi |
1005 | jmp .look_backward |
1028 | jmp .look_backward |
1006 | .found_chain_start: |
1029 | .found_chain_start: |
1007 | ; 7. Expand the chain forward. |
1030 | ; 7. Expand the chain forward. |
1008 | ; 7a. Prepare for the loop at 7b: |
1031 | ; 7a. Prepare for the loop at 7b: |
1009 | ; set esi = pointer to current item, edx:eax = current sector. |
1032 | ; set esi = pointer to current item, edx:eax = current sector. |
Line 1044... | Line 1067... | ||
1044 | jz .write_non_sequential |
1067 | jz .write_non_sequential |
1045 | .write_sequential: |
1068 | .write_sequential: |
1046 | ; 9. Write a sequential chain to disk. |
1069 | ; 9. Write a sequential chain to disk. |
1047 | ; 9a. Pass the entire chain to the driver. |
1070 | ; 9a. Pass the entire chain to the driver. |
1048 | mov eax, [.chain_start_ptr] |
1071 | mov eax, [.chain_start_ptr] |
1049 | mov edx, [.chain_start_pos] |
- | |
1050 | shl edx, 9 |
- | |
1051 | add edx, [ebx+DISKCACHE.data] |
- | |
1052 | lea ecx, [.chain_size] |
1072 | lea ecx, [.chain_size] |
1053 | push ecx ; numsectors |
1073 | push ecx ; numsectors |
1054 | pushd [eax+CACHE_ITEM.SectorHi] ; startsector |
1074 | pushd [eax+CACHE_ITEM.SectorHi] ; startsector |
1055 | pushd [eax+CACHE_ITEM.SectorLo] ; startsector |
1075 | pushd [eax+CACHE_ITEM.SectorLo] ; startsector |
1056 | push edx ; buffer |
1076 | push [.chain_start_pos+12] ; buffer |
1057 | mov esi, [ebp+PARTITION.Disk] |
1077 | mov esi, [ebp+PARTITION.Disk] |
1058 | mov al, DISKFUNC.write |
1078 | mov al, DISKFUNC.write |
1059 | call disk_call_driver |
1079 | call disk_call_driver |
1060 | ; 9b. If failed, pass the error code to the driver. |
1080 | ; 9b. If failed, pass the error code to the driver. |
1061 | test eax, eax |
1081 | test eax, eax |
Line 1086... | Line 1106... | ||
1086 | jz .nomemory |
1106 | jz .nomemory |
1087 | cmp eax, CACHE_MAX_ALLOC_SIZE shr 12 |
1107 | cmp eax, CACHE_MAX_ALLOC_SIZE shr 12 |
1088 | jbe @f |
1108 | jbe @f |
1089 | mov eax, CACHE_MAX_ALLOC_SIZE shr 12 |
1109 | mov eax, CACHE_MAX_ALLOC_SIZE shr 12 |
1090 | @@: |
1110 | @@: |
1091 | shl eax, 12 - 9 |
1111 | shl eax, 12 |
- | 1112 | shr eax, cl |
|
- | 1113 | jz .nomemory |
|
1092 | cmp eax, [.chain_size] |
1114 | cmp eax, [.chain_size] |
1093 | jbe @f |
1115 | jbe @f |
1094 | mov eax, [.chain_size] |
1116 | mov eax, [.chain_size] |
1095 | @@: |
1117 | @@: |
1096 | mov [.iteration_size], eax |
1118 | mov [.iteration_size], eax |
1097 | shl eax, 9 |
1119 | shl eax, cl |
1098 | stdcall kernel_alloc, eax |
1120 | stdcall kernel_alloc, eax |
1099 | test eax, eax |
1121 | test eax, eax |
1100 | jz .nomemory |
1122 | jz .nomemory |
1101 | mov [.iteration_buffer], eax |
1123 | mov [.iteration_buffer], eax |
1102 | .write_non_sequential_iteration: |
1124 | .write_non_sequential_iteration: |
Line 1121... | Line 1143... | ||
1121 | push [.iteration_size+20] ; temporary variable |
1143 | push [.iteration_size+20] ; temporary variable |
1122 | .copy_loop: |
1144 | .copy_loop: |
1123 | ; 13b. For each sector, copy the data. |
1145 | ; 13b. For each sector, copy the data. |
1124 | ; Note that edi is advanced automatically. |
1146 | ; Note that edi is advanced automatically. |
1125 | mov esi, [.chain_start_pos+24] |
1147 | mov esi, [.chain_start_pos+24] |
- | 1148 | mov ecx, [ebx+DISKCACHE.sector_size_log] |
|
- | 1149 | mov eax, 1 |
|
1126 | shl esi, 9 |
1150 | shl eax, cl |
1127 | add esi, [ebx+DISKCACHE.data] |
1151 | mov ecx, eax |
1128 | mov ecx, 512/4 |
1152 | shr ecx, 2 |
1129 | rep movsd |
1153 | rep movsd |
- | 1154 | mov ecx, eax ; keep for 13e |
|
1130 | ; 13c. Mark the item as not-modified. |
1155 | ; 13c. Mark the item as not-modified. |
1131 | mov esi, [.chain_start_ptr+24] |
1156 | mov esi, [.chain_start_ptr+24] |
1132 | mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY |
1157 | mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY |
1133 | ; 13d. Check whether the next sector continues the chain. |
1158 | ; 13d. Check whether the next sector continues the chain. |
1134 | ; If so, advance to 13e. Otherwise, go to 13f. |
1159 | ; If so, advance to 13e. Otherwise, go to 13f. |
Line 1143... | Line 1168... | ||
1143 | jnz .no_forward |
1168 | jnz .no_forward |
1144 | cmp [esi+CACHE_ITEM.SectorHi], edx |
1169 | cmp [esi+CACHE_ITEM.SectorHi], edx |
1145 | jnz .no_forward |
1170 | jnz .no_forward |
1146 | ; 13e. Increment position/pointer to the chain and |
1171 | ; 13e. Increment position/pointer to the chain and |
1147 | ; continue the loop. |
1172 | ; continue the loop. |
1148 | inc [.chain_start_pos+24] |
1173 | add [.chain_start_pos+24], ecx |
1149 | mov [.chain_start_ptr+24], esi |
1174 | mov [.chain_start_ptr+24], esi |
1150 | dec dword [esp] |
1175 | dec dword [esp] |
1151 | jnz .copy_loop |
1176 | jnz .copy_loop |
1152 | jmp .copy_done |
1177 | jmp .copy_done |
1153 | .no_forward: |
1178 | .no_forward: |
1154 | ; 13f. Call the lookup function without adding to the cache. |
1179 | ; 13f. Call the lookup function without adding to the cache. |
1155 | ; Update position/pointer with returned value. |
1180 | ; Update position/pointer with returned value. |
1156 | ; Note: for the last sector in the chain, ecx/esi may contain |
1181 | ; Note: for the last sector in the chain, edi/esi may contain |
1157 | ; garbage; we are not going to use them in this case. |
1182 | ; garbage; we are not going to use them in this case. |
- | 1183 | push edi |
|
1158 | call cache_lookup_read |
1184 | call cache_lookup_read |
1159 | mov [.chain_start_pos+24], ecx |
1185 | mov [.chain_start_pos+28], edi |
1160 | mov [.chain_start_ptr+24], esi |
1186 | mov [.chain_start_ptr+28], esi |
- | 1187 | pop edi |
|
1161 | dec dword [esp] |
1188 | dec dword [esp] |
1162 | jnz .copy_loop |
1189 | jnz .copy_loop |
1163 | .copy_done: |
1190 | .copy_done: |
1164 | ; 13g. Restore the stack after 13a. |
1191 | ; 13g. Restore the stack after 13a. |
1165 | pop ecx |
1192 | pop ecx |
Line 1201... | Line 1228... | ||
1201 | ; driver can adjust the size. In particular, setting size to zero disables |
1228 | ; driver can adjust the size. In particular, setting size to zero disables |
1202 | ; caching: there is no sense in a cache for a ramdisk. In fact, such action |
1229 | ; caching: there is no sense in a cache for a ramdisk. In fact, such action |
1203 | ; is most useful example of a non-trivial adjustment. |
1230 | ; is most useful example of a non-trivial adjustment. |
1204 | ; esi = pointer to DISK structure |
1231 | ; esi = pointer to DISK structure |
1205 | disk_init_cache: |
1232 | disk_init_cache: |
- | 1233 | ; 1. Verify sector size. The code requires it to be a power of 2 not less than 4. |
|
- | 1234 | ; In the name of sanity check that sector size is not too small or too large. |
|
- | 1235 | bsf ecx, [esi+DISK.MediaInfo.SectorSize] |
|
- | 1236 | jz .invalid_sector_size |
|
- | 1237 | mov eax, 1 |
|
- | 1238 | shl eax, cl |
|
- | 1239 | cmp eax, [esi+DISK.MediaInfo.SectorSize] |
|
- | 1240 | jnz .invalid_sector_size |
|
- | 1241 | cmp ecx, 6 |
|
- | 1242 | jb .invalid_sector_size |
|
- | 1243 | cmp ecx, 14 |
|
- | 1244 | jbe .normal_sector_size |
|
- | 1245 | .invalid_sector_size: |
|
- | 1246 | DEBUGF 1,'K : sector size %x is invalid\n',[esi+DISK.MediaInfo.SectorSize] |
|
- | 1247 | xor eax, eax |
|
- | 1248 | ret |
|
- | 1249 | .normal_sector_size: |
|
- | 1250 | mov [esi+DISK.SysCache.sector_size_log], ecx |
|
- | 1251 | mov [esi+DISK.AppCache.sector_size_log], ecx |
|
1206 | ; 1. Calculate the suggested cache size. |
1252 | ; 2. Calculate the suggested cache size. |
1207 | ; 1a. Get the size of free physical memory in pages. |
1253 | ; 2a. Get the size of free physical memory in pages. |
1208 | mov eax, [pg_data.pages_free] |
1254 | mov eax, [pg_data.pages_free] |
1209 | ; 1b. Use the value to calculate the size. |
1255 | ; 2b. Use the value to calculate the size. |
1210 | shl eax, 12 - 5 ; 1/32 of it in bytes |
1256 | shl eax, 12 - 5 ; 1/32 of it in bytes |
1211 | and eax, -8*4096 ; round down to the multiple of 8 pages |
1257 | and eax, -8*4096 ; round down to the multiple of 8 pages |
1212 | ; 1c. Force lower and upper limits. |
1258 | ; 2c. Force lower and upper limits. |
1213 | cmp eax, 1024*1024 |
1259 | cmp eax, 1024*1024 |
1214 | jb @f |
1260 | jb @f |
1215 | mov eax, 1024*1024 |
1261 | mov eax, 1024*1024 |
1216 | @@: |
1262 | @@: |
1217 | cmp eax, 128*1024 |
1263 | cmp eax, 128*1024 |
1218 | ja @f |
1264 | ja @f |
1219 | mov eax, 128*1024 |
1265 | mov eax, 128*1024 |
1220 | @@: |
1266 | @@: |
1221 | ; 1d. Give a chance to the driver to adjust the size. |
1267 | ; 2d. Give a chance to the driver to adjust the size. |
1222 | push eax |
1268 | push eax |
1223 | mov al, DISKFUNC.adjust_cache_size |
1269 | mov al, DISKFUNC.adjust_cache_size |
1224 | call disk_call_driver |
1270 | call disk_call_driver |
1225 | ; Cache size calculated. |
1271 | ; Cache size calculated. |
1226 | mov [esi+DISK.cache_size], eax |
1272 | mov [esi+DISK.cache_size], eax |
1227 | test eax, eax |
1273 | test eax, eax |
1228 | jz .nocache |
1274 | jz .nocache |
1229 | ; 2. Allocate memory for the cache. |
1275 | ; 3. Allocate memory for the cache. |
1230 | ; 2a. Call the allocator. |
1276 | ; 3a. Call the allocator. |
1231 | stdcall kernel_alloc, eax |
1277 | stdcall kernel_alloc, eax |
1232 | test eax, eax |
1278 | test eax, eax |
1233 | jnz @f |
1279 | jnz @f |
1234 | ; 2b. If it failed, say a message and return with eax = 0. |
1280 | ; 3b. If it failed, say a message and return with eax = 0. |
1235 | dbgstr 'no memory for disk cache' |
1281 | dbgstr 'no memory for disk cache' |
1236 | jmp .nothing |
1282 | jmp .nothing |
1237 | @@: |
1283 | @@: |
1238 | ; 3. Fill two DISKCACHE structures. |
1284 | ; 4. Fill two DISKCACHE structures. |
1239 | mov [esi+DISK.SysCache.pointer], eax |
1285 | mov [esi+DISK.SysCache.pointer], eax |
1240 | lea ecx, [esi+DISK.CacheLock] |
1286 | lea ecx, [esi+DISK.CacheLock] |
1241 | call mutex_init |
1287 | call mutex_init |
1242 | ; The following code is inherited from getcache.inc. |
1288 | ; The following code is inherited from getcache.inc. |
1243 | mov edx, [esi+DISK.SysCache.pointer] |
1289 | mov edx, [esi+DISK.SysCache.pointer] |
Line 1250... | Line 1296... | ||
1250 | imul eax, 7 |
1296 | imul eax, 7 |
1251 | mov [esi+DISK.AppCache.data_size], eax |
1297 | mov [esi+DISK.AppCache.data_size], eax |
1252 | mov [esi+DISK.AppCache.pointer], edx |
1298 | mov [esi+DISK.AppCache.pointer], edx |
Line 1253... | Line 1299... | ||
1253 | 1299 | ||
1254 | mov eax, [esi+DISK.SysCache.data_size] |
- | |
1255 | push ebx |
1300 | mov eax, [esi+DISK.SysCache.data_size] |
1256 | call calculate_for_hd64 |
- | |
1257 | pop ebx |
1301 | call calculate_cache_slots |
1258 | add eax, [esi+DISK.SysCache.pointer] |
1302 | add eax, [esi+DISK.SysCache.pointer] |
1259 | mov [esi+DISK.SysCache.data], eax |
1303 | mov [esi+DISK.SysCache.data], eax |
Line 1260... | Line 1304... | ||
1260 | mov [esi+DISK.SysCache.sad_size], ecx |
1304 | mov [esi+DISK.SysCache.sad_size], ecx |
Line 1265... | Line 1309... | ||
1265 | xor eax, eax |
1309 | xor eax, eax |
1266 | rep stosd |
1310 | rep stosd |
1267 | pop edi |
1311 | pop edi |
Line 1268... | Line 1312... | ||
1268 | 1312 | ||
1269 | mov eax, [esi+DISK.AppCache.data_size] |
- | |
1270 | push ebx |
1313 | mov eax, [esi+DISK.AppCache.data_size] |
1271 | call calculate_for_hd64 |
- | |
1272 | pop ebx |
1314 | call calculate_cache_slots |
1273 | add eax, [esi+DISK.AppCache.pointer] |
1315 | add eax, [esi+DISK.AppCache.pointer] |
1274 | mov [esi+DISK.AppCache.data], eax |
1316 | mov [esi+DISK.AppCache.data], eax |
Line 1275... | Line 1317... | ||
1275 | mov [esi+DISK.AppCache.sad_size], ecx |
1317 | mov [esi+DISK.AppCache.sad_size], ecx |
Line 1279... | Line 1321... | ||
1279 | lea ecx, [(ecx+1)*3] |
1321 | lea ecx, [(ecx+1)*3] |
1280 | xor eax, eax |
1322 | xor eax, eax |
1281 | rep stosd |
1323 | rep stosd |
1282 | pop edi |
1324 | pop edi |
Line 1283... | Line 1325... | ||
1283 | 1325 | ||
1284 | ; 4. Return with nonzero al. |
1326 | ; 5. Return with nonzero al. |
1285 | mov al, 1 |
1327 | mov al, 1 |
1286 | ; 5. Return. |
1328 | ; 6. Return. |
1287 | .nothing: |
1329 | .nothing: |
1288 | ret |
1330 | ret |
1289 | ; No caching is required for this driver. Zero cache pointers and return with |
1331 | ; No caching is required for this driver. Zero cache pointers and return with |
1290 | ; nonzero al. |
1332 | ; nonzero al. |
1291 | .nocache: |
1333 | .nocache: |
1292 | mov [esi+DISK.SysCache.pointer], eax |
1334 | mov [esi+DISK.SysCache.pointer], eax |
1293 | mov [esi+DISK.AppCache.pointer], eax |
1335 | mov [esi+DISK.AppCache.pointer], eax |
1294 | mov al, 1 |
1336 | mov al, 1 |
Line 1295... | Line 1337... | ||
1295 | ret |
1337 | ret |
1296 | 1338 | ||
1297 | calculate_for_hd64: |
1339 | calculate_cache_slots: |
1298 | push eax |
1340 | push eax |
1299 | mov ebx, eax |
1341 | mov ecx, [esi+DISK.MediaInfo.SectorSize] |
1300 | shr eax, 9 |
1342 | add ecx, sizeof.CACHE_ITEM |
1301 | lea eax, [eax*3] |
1343 | xor edx, edx |
1302 | shl eax, 2 |
1344 | div ecx |
1303 | sub ebx, eax |
1345 | mov ecx, eax |
1304 | shr ebx, 9 |
- | |
1305 | mov ecx, ebx |
1346 | imul eax, [esi+DISK.MediaInfo.SectorSize] |
1306 | shl ebx, 9 |
- | |
1307 | pop eax |
1347 | sub [esp], eax |
1308 | sub eax, ebx |
1348 | pop eax |
Line 1309... | Line 1349... | ||
1309 | dec ecx |
1349 | dec ecx |