166,20 → 166,6 |
mov [IDE_Channel_2],0 |
ret |
;******************************************** |
clear_hd_cache: |
|
push eax ecx edi |
mov edi,0x600000 |
mov ecx,16384 |
xor eax,eax |
cld |
rep stosd ; clear hd cache with 0 |
mov [cache_search_start],eax |
mov [fat_in_cache],-1 |
mov [fat_change],0 |
pop edi ecx eax |
ret |
|
problem_partition db 0 ; used for partitions search |
|
include 'part_set.inc' |
1926,451 → 1912,6 |
update_disk_acces_denied: |
ret |
|
|
;************************************************************************** |
; |
; 0x600008 - first entry in cache list |
; |
; +0 - lba sector |
; +4 - state of cache sector |
; 0 = empty |
; 1 = used for read ( same as in hd ) |
; 2 = used for write ( differs from hd ) |
; |
; +65536 - cache entries |
; |
;************************************************************************** |
|
|
hd_read: |
;----------------------------------------------------------- |
; input : eax = block to read |
; ebx = destination |
;----------------------------------------------------------- |
push ecx esi edi ; scan cache |
|
mov ecx,cache_max ; entries in cache |
mov esi,0x600000+8 |
mov edi,1 |
|
hdreadcache: |
|
cmp dword [esi+4],0 ; empty |
je nohdcache |
|
cmp [esi],eax ; correct sector |
je yeshdcache |
|
nohdcache: |
|
add esi,8 |
inc edi |
dec ecx |
jnz hdreadcache |
|
call find_empty_slot ; ret in edi |
cmp [hd_error],0 |
jne return_01 |
|
push eax edx |
|
call disable_ide_int |
|
call wait_for_hd_idle |
cmp [hd_error],0 |
jne hd_read_error |
|
; cli |
xor eax,eax |
mov edx,[hdbase] |
inc edx |
out dx,al ; ATAFeatures ॣ¨áâà "®á®¡¥®á⥩" |
inc edx |
inc eax |
out dx,al ; ATASectorCount áç¥â稪 ᥪâ®à®¢ |
inc edx |
mov eax,[esp+4] |
out dx,al ; ATASectorNumber ॣ¨áâà ®¬¥à ᥪâ®à |
shr eax,8 |
inc edx |
out dx,al ; ATACylinder ®¬¥à 樫¨¤à (¬« ¤è¨© ¡ ©â) |
shr eax,8 |
inc edx |
out dx,al ; ®¬¥à 樫¨¤à (áâ à訩 ¡ ©â) |
shr eax,8 |
inc edx |
and al,1+2+4+8 |
add al,byte [hdid] |
add al,128+64+32 |
out dx,al ; ®¬¥à £®«®¢ª¨/®¬¥à ¤¨áª |
inc edx |
mov al,20h |
out dx,al ; ATACommand ॣ¨áâà ª®¬ ¤ |
; sti |
|
call wait_for_sector_buffer |
|
cmp [hd_error],0 |
jne hd_read_error |
|
; cli |
push edi |
shl edi,9 |
add edi,0x600000+65536 |
mov ecx,256 |
mov edx,[hdbase] |
cld |
rep insw |
pop edi |
; sti |
|
call enable_ide_int |
|
pop edx eax |
blok_read_2: |
lea esi,[edi*8+0x600000] |
mov [esi],eax ; sector number |
mov dword [esi+4],1 ; hd read - mark as same as in hd |
|
yeshdcache: |
|
mov esi,edi |
shl esi,9 |
add esi,0x600000+65536 |
mov edi,ebx |
mov ecx,512/4 |
cld |
rep movsd ; move data |
return_01: |
pop edi esi ecx |
ret |
|
disable_ide_int: |
mov edx,[hdbase] |
add edx,0x206 |
mov al,2 |
out dx,al |
ret |
|
enable_ide_int: |
mov edx,[hdbase] |
add edx,0x206 |
mov al,0 |
out dx,al |
ret |
|
hd_write: |
;----------------------------------------------------------- |
; input : eax = block |
; ebx = pointer to memory |
;----------------------------------------------------------- |
push ecx esi edi |
|
; check if the cache already has the sector and overwrite it |
|
mov ecx,cache_max |
mov esi,0x600000+8 |
mov edi,1 |
|
hdwritecache: |
|
cmp dword [esi+4],0 ; if cache slot is empty |
je not_in_cache_write |
|
cmp [esi],eax ; if the slot has the sector |
je yes_in_cache_write |
|
not_in_cache_write: |
|
add esi,8 |
inc edi |
dec ecx |
jnz hdwritecache |
|
; sector not found in cache |
; write the block to a new location |
|
call find_empty_slot ; ret in edi |
cmp [hd_error],0 |
jne hd_write_access_denied |
|
lea esi,[edi*8+0x600000] |
mov [esi],eax ; sector number |
|
yes_in_cache_write: |
|
mov dword [esi+4],2 ; write - differs from hd |
|
shl edi,9 |
add edi,0x600000+65536 |
mov esi,ebx |
mov ecx,512/4 |
cld |
rep movsd ; move data |
hd_write_access_denied: |
pop edi esi ecx |
ret |
|
|
write_cache: |
;----------------------------------------------------------- |
; write all changed sectors to disk |
;----------------------------------------------------------- |
push eax ecx edx esi edi |
|
; write difference ( 2 ) from cache to hd |
|
mov ecx,cache_max |
mov esi,0x600000+8 |
mov edi,1 |
|
write_cache_more: |
|
cmp dword [esi+4],2 ; if cache slot is not different |
jne does_not_need_writing |
|
mov dword [esi+4],1 ; same as in hd |
mov eax,[esi] ; eax = sector to write |
|
cmp eax,[PARTITION_START] |
jb danger |
cmp eax,[PARTITION_END] |
ja danger |
|
call disable_ide_int |
|
call wait_for_hd_idle |
cmp [hd_error],0 |
jne hd_write_error |
|
; cli |
xor eax,eax |
mov edx,[hdbase] |
inc edx |
out dx,al |
inc edx |
inc eax |
out dx,al |
inc edx |
mov eax,[esi] ; eax = sector to write |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
and al,1+2+4+8 |
add al,byte [hdid] |
add al,128+64+32 |
out dx,al |
inc edx |
mov al,30h |
out dx,al |
; sti |
|
call wait_for_sector_buffer |
|
cmp [hd_error],0 |
jne hd_write_error |
|
push ecx esi |
|
; cli |
mov esi,edi |
shl esi,9 |
add esi,0x600000+65536 ; esi = from memory position |
mov ecx,256 |
mov edx,[hdbase] |
cld |
rep outsw |
; sti |
|
pop esi ecx |
|
call enable_ide_int |
|
danger: |
does_not_need_writing: |
|
add esi,8 |
inc edi |
dec ecx |
jnz write_cache_more |
return_02: |
pop edi esi edx ecx eax |
ret |
|
|
find_empty_slot: |
;----------------------------------------------------------- |
; find empty or read slot, flush cache if next 10% is used by write |
; output : edi = cache slot |
;----------------------------------------------------------- |
push ecx esi |
|
search_again: |
|
mov ecx,cache_max*10/100 |
mov edi,[cache_search_start] |
|
search_for_empty: |
|
inc edi |
cmp edi,cache_max |
jbe inside_cache |
mov edi,1 |
|
inside_cache: |
|
cmp dword [edi*8+0x600000+4],2 ; get cache slot info |
jb found_slot ; it's empty or read |
dec ecx |
jnz search_for_empty |
|
call write_cache ; no empty slots found, write all |
cmp [hd_error],0 |
jne found_slot_access_denied |
|
jmp search_again ; and start again |
|
found_slot: |
|
mov [cache_search_start],edi |
found_slot_access_denied: |
pop esi ecx |
ret |
|
|
save_hd_wait_timeout: |
|
push eax |
mov eax,[timer_ticks];[0xfdf0] |
add eax,300 ; 3 sec timeout |
mov [hd_wait_timeout],eax |
pop eax |
ret |
|
|
check_hd_wait_timeout: |
|
push eax |
mov eax,[hd_wait_timeout] |
cmp [timer_ticks], eax ;[0xfdf0],eax |
jg hd_timeout_error |
pop eax |
mov [hd_error],0 |
ret |
|
iglobal |
hd_timeout_str db 'K : FS - HD timeout',13,10,0 |
hd_read_str db 'K : FS - HD read error',13,10,0 |
hd_write_str db 'K : FS - HD write error',13,10,0 |
hd_lba_str db 'K : FS - HD LBA error',13,10,0 |
endg |
|
hd_timeout_error: |
|
call clear_hd_cache |
call clear_application_table_status |
mov esi,hd_timeout_str |
call sys_msg_board_str |
; jmp $ |
mov [hd_error],1 |
pop eax |
ret |
|
hd_read_error: |
|
call clear_hd_cache |
call clear_application_table_status |
mov esi,hd_read_str |
call sys_msg_board_str |
pop edx eax |
jmp return_01 |
; jmp $ |
|
hd_write_error: |
|
call clear_hd_cache |
call clear_application_table_status |
mov esi,hd_write_str |
call sys_msg_board_str |
jmp return_02 |
; jmp $ |
|
hd_lba_error: |
call clear_hd_cache |
call clear_application_table_status |
mov esi,hd_lba_str |
call sys_msg_board_str |
jmp LBA_read_ret |
|
|
wait_for_hd_idle: |
|
push eax edx |
|
call save_hd_wait_timeout |
|
mov edx,[hdbase] |
add edx,0x7 |
|
wfhil1: |
|
call check_hd_wait_timeout |
cmp [hd_error],0 |
jne @f |
|
in al,dx |
test al,128 |
jnz wfhil1 |
|
@@: |
|
pop edx eax |
ret |
|
|
|
wait_for_sector_buffer: |
|
push eax edx |
|
mov edx,[hdbase] |
add edx,0x7 |
|
call save_hd_wait_timeout |
|
hdwait_sbuf: ; wait for sector buffer to be ready |
|
call check_hd_wait_timeout |
cmp [hd_error],0 |
jne @f |
|
in al,dx |
test al,8 |
jz hdwait_sbuf |
|
mov [hd_error],0 |
|
cmp [hd_setup],1 ; do not mark error for setup request |
je buf_wait_ok |
|
test al,1 ; previous command ended up with an error |
jz buf_wait_ok |
@@: |
mov [hd_error],1 |
|
buf_wait_ok: |
|
pop edx eax |
ret |
|
|
|
read_hd_file: |
;----------------------------------------------------------------- |
; |