2005-10-06 19:56:22 +02:00
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;; ;;
|
|
|
|
|
;; FAT32.INC ;;
|
|
|
|
|
;; ;;
|
|
|
|
|
;; FAT16/32 functions for MenuetOS ;;
|
|
|
|
|
;; ;;
|
|
|
|
|
;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;;
|
|
|
|
|
;; ;;
|
|
|
|
|
;; See file COPYING for details ;;
|
|
|
|
|
;; ;;
|
|
|
|
|
;; 15.01.2005 get file size/attr/date, file_append - ATV ;;
|
|
|
|
|
;; 04.12.2004 skip volume label, file delete bug fixed - ATV ;;
|
|
|
|
|
;; 29.11.2004 get_free_FAT changed, append dir bug fixed - ATV ;;
|
|
|
|
|
;; 23.11.2004 don't allow overwrite dir with file - ATV ;;
|
|
|
|
|
;; 18.11.2004 get_disk_info and more error codes - ATV ;;
|
|
|
|
|
;; 17.11.2004 set_FAT/get_FAT and disk cache rewritten - ATV ;;
|
|
|
|
|
;; 10.11.2004 removedir clear whole directory structure - ATV ;;
|
|
|
|
|
;; 08.11.2004 rename - ATV ;;
|
|
|
|
|
;; 30.10.2004 file_read return also dirsize in bytes - ATV ;;
|
|
|
|
|
;; 20.10.2004 Makedir/Removedir - ATV ;;
|
|
|
|
|
;; 14.10.2004 Partition chain/Fat16 - ATV (thanks drh3xx) ;;
|
|
|
|
|
;; 06.9.2004 Fix free space by Mario79 added - MH ;;
|
|
|
|
|
;; 24.5.2004 Write back buffer for File_write -VT ;;
|
|
|
|
|
;; 20.5.2004 File_read function to work with syscall 58 - VT ;;
|
|
|
|
|
;; 30.3.2004 Error parameters at function return - VT ;;
|
|
|
|
|
;; 01.5.2002 Bugfix in device write - VT ;;
|
|
|
|
|
;; 20.5.2002 Hd status check - VT ;;
|
|
|
|
|
;; 29.6.2002 Improved fat32 verification - VT ;;
|
|
|
|
|
;; ;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
cache_max equ 1919 ; max. is 1919*512+0x610000=0x6ffe00
|
|
|
|
|
|
2006-03-04 12:58:09 +01:00
|
|
|
|
ERROR_SUCCESS = 0
|
|
|
|
|
ERROR_DISK_BASE = 1
|
|
|
|
|
ERROR_UNSUPPORTED_FS = 2
|
|
|
|
|
ERROR_UNKNOWN_FS = 3
|
|
|
|
|
ERROR_PARTITION = 4
|
|
|
|
|
ERROR_FILE_NOT_FOUND = 5
|
|
|
|
|
ERROR_END_OF_FILE = 6
|
|
|
|
|
ERROR_MEMORY_POINTER = 7
|
|
|
|
|
ERROR_DISK_FULL = 8
|
|
|
|
|
ERROR_FAT_TABLE = 9
|
|
|
|
|
ERROR_ACCESS_DENIED = 10
|
2005-10-06 19:56:22 +02:00
|
|
|
|
|
|
|
|
|
PUSHAD_EAX equ [esp+28]
|
|
|
|
|
PUSHAD_ECX equ [esp+24]
|
|
|
|
|
PUSHAD_EDX equ [esp+20]
|
|
|
|
|
PUSHAD_EBX equ [esp+16]
|
|
|
|
|
PUSHAD_EBP equ [esp+8]
|
|
|
|
|
PUSHAD_ESI equ [esp+4]
|
|
|
|
|
PUSHAD_EDI equ [esp+0]
|
|
|
|
|
|
|
|
|
|
align 4
|
|
|
|
|
;******************************************************
|
|
|
|
|
; Please do not change this place - variables in text
|
|
|
|
|
; Mario79
|
|
|
|
|
; START place
|
|
|
|
|
;******************************************************
|
|
|
|
|
PARTITION_START dd 0x3f
|
|
|
|
|
PARTITION_END dd 0
|
|
|
|
|
SECTORS_PER_FAT dd 0x1f3a
|
|
|
|
|
NUMBER_OF_FATS dd 0x2
|
|
|
|
|
SECTORS_PER_CLUSTER dd 0x8
|
|
|
|
|
BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes
|
|
|
|
|
ROOT_CLUSTER dd 2 ; first rootdir cluster
|
|
|
|
|
FAT_START dd 0 ; start of fat table
|
|
|
|
|
ROOT_START dd 0 ; start of rootdir (only fat16)
|
|
|
|
|
ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16)
|
|
|
|
|
DATA_START dd 0 ; start of data area (=first cluster 2)
|
|
|
|
|
LAST_CLUSTER dd 0 ; last availabe cluster
|
|
|
|
|
ADR_FSINFO dd 0 ; used only by fat32
|
|
|
|
|
|
|
|
|
|
fatRESERVED dd 0x0FFFFFF6
|
|
|
|
|
fatBAD dd 0x0FFFFFF7
|
|
|
|
|
fatEND dd 0x0FFFFFF8
|
|
|
|
|
fatMASK dd 0x0FFFFFFF
|
|
|
|
|
|
|
|
|
|
fat_type db 0 ; 0=none, 16=fat16, 32=fat32
|
|
|
|
|
;***************************************************************************
|
|
|
|
|
; End place
|
|
|
|
|
; Mario79
|
|
|
|
|
;***************************************************************************
|
|
|
|
|
cluster dd 0 ; used by file_write,makedir,append
|
|
|
|
|
partition_count dd 0 ; partitions found by set_FAT32_variables
|
|
|
|
|
longname_sec1 dd 0 ; used by analyze_directory to save 2 previous
|
|
|
|
|
longname_sec2 dd 0 ; directory sectors for delete long filename
|
|
|
|
|
|
|
|
|
|
hd_error dd 0 ; set by wait_for_sector_buffer
|
|
|
|
|
hd_setup dd 0
|
|
|
|
|
hd_wait_timeout dd 0
|
|
|
|
|
|
|
|
|
|
cluster_tmp dd 0 ; used by analyze_directory
|
|
|
|
|
; and analyze_directory_to_write
|
|
|
|
|
|
|
|
|
|
file_size dd 0 ; used by file_read
|
|
|
|
|
|
|
|
|
|
sector_tmp dd 0 ; used by rename,append,file_write
|
|
|
|
|
entry_pos dd 0 ; used by rename,append,file_write
|
|
|
|
|
|
|
|
|
|
old_filesize dd 0 ; used by append
|
|
|
|
|
new_filepos dd 0 ; used by append
|
|
|
|
|
bytes2write dd 0 ; used by append
|
|
|
|
|
|
|
|
|
|
cache_search_start dd 0 ; used by find_empty_slot
|
|
|
|
|
|
|
|
|
|
fat_in_cache dd -1
|
|
|
|
|
fat_cache: times 512 db 0
|
|
|
|
|
|
|
|
|
|
uglobal
|
|
|
|
|
Sector512: ; label for dev_hdcd.inc
|
|
|
|
|
buffer: times 512 db 0
|
|
|
|
|
deltree_buffer: times 512 db 0
|
|
|
|
|
endg
|
|
|
|
|
|
|
|
|
|
iglobal
|
|
|
|
|
NewDirEntry1 db ". ",0x10
|
|
|
|
|
times 20 db 0
|
|
|
|
|
NewDirEntry2 db ".. ",0x10
|
|
|
|
|
times 20 db 0
|
|
|
|
|
endg
|
|
|
|
|
|
|
|
|
|
uglobal
|
|
|
|
|
dir_entry: times 32 db 0
|
|
|
|
|
|
|
|
|
|
startpath: times 255 db 0
|
|
|
|
|
|
|
|
|
|
fat16_root db 0 ; flag for fat16 rootdir
|
|
|
|
|
f_del db 0 ; 1=overwrite fat entry
|
|
|
|
|
fat_change db 0 ; 1=fat has changed
|
|
|
|
|
|
|
|
|
|
endg
|
|
|
|
|
|
|
|
|
|
iglobal
|
|
|
|
|
partition_types: ; list of fat16/32 partitions
|
|
|
|
|
db 0x04 ; DOS: fat16 <32M
|
|
|
|
|
db 0x06 ; DOS: fat16 >32M
|
|
|
|
|
db 0x0b ; WIN95: fat32
|
|
|
|
|
db 0x0c ; WIN95: fat32, LBA-mapped
|
|
|
|
|
db 0x0e ; WIN95: fat16, LBA-mapped
|
|
|
|
|
db 0x14 ; Hidden DOS: fat16 <32M
|
|
|
|
|
db 0x16 ; Hidden DOS: fat16 >32M
|
|
|
|
|
db 0x1b ; Hidden WIN95: fat32
|
|
|
|
|
db 0x1c ; Hidden WIN95: fat32, LBA-mapped
|
|
|
|
|
db 0x1e ; Hidden WIN95: fat16, LBA-mapped
|
|
|
|
|
db 0xc4 ; DRDOS/secured: fat16 <32M
|
|
|
|
|
db 0xc6 ; DRDOS/secured: fat16 >32M
|
|
|
|
|
db 0xcb ; DRDOS/secured: fat32
|
|
|
|
|
db 0xcc ; DRDOS/secured: fat32, LBA-mapped
|
|
|
|
|
db 0xce ; DRDOS/secured: fat16, LBA-mapped
|
|
|
|
|
db 0xd4 ; Old Multiuser DOS secured: fat16 <32M
|
|
|
|
|
db 0xd6 ; Old Multiuser DOS secured: fat16 >32M
|
|
|
|
|
partition_types_end:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extended_types: ; list of extended partitions
|
|
|
|
|
db 0x05 ; DOS: extended partition
|
|
|
|
|
db 0x0f ; WIN95: extended partition, LBA-mapped
|
|
|
|
|
db 0xc5 ; DRDOS/secured: extended partition
|
|
|
|
|
db 0xd5 ; Old Multiuser DOS secured: extended partition
|
|
|
|
|
extended_types_end:
|
|
|
|
|
|
|
|
|
|
endg
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
reserve_hd1:
|
|
|
|
|
|
|
|
|
|
cli
|
|
|
|
|
cmp [hd1_status],0
|
|
|
|
|
je reserve_ok1
|
|
|
|
|
|
|
|
|
|
sti
|
|
|
|
|
call change_task
|
|
|
|
|
jmp reserve_hd1
|
|
|
|
|
|
|
|
|
|
reserve_ok1:
|
|
|
|
|
|
|
|
|
|
push eax
|
|
|
|
|
mov eax,[0x3000]
|
|
|
|
|
shl eax,5
|
|
|
|
|
mov eax,[eax+0x3000+4]
|
|
|
|
|
mov [hd1_status],eax
|
|
|
|
|
pop eax
|
|
|
|
|
sti
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
; Partition chain used:
|
|
|
|
|
; MBR ; PARTITION2 ; PARTITION3 ; PARTITION4
|
|
|
|
|
;==========================================================
|
|
|
|
|
; fat16/32 +-- fat16/32 +-- fat16/32 +-- fat16/32 +--
|
|
|
|
|
; extended --+ extended --+ extended --+ extended --+
|
|
|
|
|
; 0 0 0 0
|
|
|
|
|
; 0 0 0 0
|
|
|
|
|
; Notes:
|
|
|
|
|
; - extended partition need to be in second entry on table
|
|
|
|
|
; - it will skip over removed partitions
|
|
|
|
|
|
|
|
|
|
set_FAT32_variables:
|
|
|
|
|
mov [0xfe10],dword 0 ; entries in hd cache
|
|
|
|
|
mov [problem_partition],0
|
|
|
|
|
call reserve_hd1
|
|
|
|
|
call clear_hd_cache
|
|
|
|
|
|
|
|
|
|
cmp dword [hdpos],0
|
|
|
|
|
je problem_hd
|
|
|
|
|
|
|
|
|
|
pushad
|
|
|
|
|
xor ecx,ecx ; partition count
|
|
|
|
|
mov edx,-1 ; flag for partition
|
|
|
|
|
xor eax,eax ; read MBR
|
|
|
|
|
xor ebp,ebp ; extended partition start
|
|
|
|
|
|
|
|
|
|
new_partition:
|
|
|
|
|
test ebp,ebp ; is there extended partition?
|
|
|
|
|
jnz extended_already_set ; yes
|
|
|
|
|
xchg ebp,eax ; no. set it now
|
|
|
|
|
|
|
|
|
|
extended_already_set:
|
|
|
|
|
add eax,ebp ; mbr=mbr+0, ext_part=ext_start+relat_start
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_read
|
|
|
|
|
|
|
|
|
|
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
|
|
|
|
|
jnz end_partition_chain
|
|
|
|
|
cmp dword [ebx+0x1be+0xc],0 ; skip over empty partition
|
|
|
|
|
jz next_partition
|
|
|
|
|
|
|
|
|
|
push eax ecx
|
|
|
|
|
mov edi,partition_types
|
|
|
|
|
mov ecx,partition_types_end-partition_types
|
|
|
|
|
mov al,[ebx+0x1be+4] ; get partition type
|
|
|
|
|
cld
|
|
|
|
|
repne scasb ; is partition type ok?
|
|
|
|
|
pop ecx eax
|
|
|
|
|
jnz next_partition ; no. skip over
|
|
|
|
|
|
|
|
|
|
inc ecx
|
|
|
|
|
cmp ecx,[fat32part] ; is it wanted partition?
|
|
|
|
|
jnz next_partition ; no
|
|
|
|
|
|
|
|
|
|
mov edx,eax ; start sector
|
|
|
|
|
add edx,[ebx+0x1be+8] ; add relative start
|
|
|
|
|
|
|
|
|
|
next_partition:
|
|
|
|
|
push ecx
|
|
|
|
|
mov edi,extended_types
|
|
|
|
|
mov ecx,extended_types_end-extended_types
|
|
|
|
|
mov al,[ebx+0x1be+4+16] ; get second partition type
|
|
|
|
|
cld
|
|
|
|
|
repne scasb ; is it extended partition?
|
|
|
|
|
pop ecx
|
|
|
|
|
jnz end_partition_chain ; no. end chain
|
|
|
|
|
|
|
|
|
|
mov eax,[ebx+0x1be+8+16] ; get start of extended partition
|
|
|
|
|
test eax,eax ; is there extended partition?
|
|
|
|
|
jnz new_partition ; yes. read it
|
|
|
|
|
|
|
|
|
|
end_partition_chain:
|
|
|
|
|
mov [partition_count],ecx
|
|
|
|
|
|
|
|
|
|
cmp edx,-1 ; found wanted partition?
|
|
|
|
|
jnz hd_and_partition_ok ; yes. install it
|
|
|
|
|
jmp problem_partition_or_fat
|
|
|
|
|
|
|
|
|
|
problem_fat_dec_count: ; bootsector is missing or another problem
|
|
|
|
|
dec [partition_count] ; remove it from partition_count
|
|
|
|
|
|
|
|
|
|
problem_partition_or_fat:
|
|
|
|
|
popad
|
|
|
|
|
|
|
|
|
|
problem_hd:
|
|
|
|
|
mov [fat_type],0
|
|
|
|
|
mov [hd1_status],0 ; free
|
|
|
|
|
mov [problem_partition],1
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
hd_and_partition_ok:
|
|
|
|
|
mov eax,edx
|
|
|
|
|
mov [PARTITION_START],eax
|
|
|
|
|
|
|
|
|
|
mov [hd_setup],1
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_read ; read boot sector of partition
|
|
|
|
|
mov [hd_setup],0
|
|
|
|
|
|
|
|
|
|
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
|
|
|
|
|
jnz problem_fat_dec_count
|
|
|
|
|
|
|
|
|
|
movzx eax,word [ebx+0xe] ; sectors reserved
|
|
|
|
|
add eax,[PARTITION_START]
|
|
|
|
|
mov [FAT_START],eax ; fat_start = partition_start + reserved
|
|
|
|
|
|
|
|
|
|
movzx eax,byte [ebx+0xd] ; sectors per cluster
|
|
|
|
|
mov [SECTORS_PER_CLUSTER],eax
|
|
|
|
|
|
|
|
|
|
movzx ecx,word [ebx+0xb] ; bytes per sector
|
|
|
|
|
mov [BYTES_PER_SECTOR],ecx
|
|
|
|
|
|
|
|
|
|
movzx eax,word [ebx+0x11] ; count of rootdir entries (=0 fat32)
|
|
|
|
|
mov edx,32
|
|
|
|
|
mul edx
|
|
|
|
|
dec ecx
|
|
|
|
|
add eax,ecx ; round up if not equal count
|
|
|
|
|
inc ecx ; bytes per sector
|
|
|
|
|
div ecx
|
|
|
|
|
mov [ROOT_SECTORS],eax ; count of rootdir sectors
|
|
|
|
|
|
|
|
|
|
movzx eax,word [ebx+0x16] ; sectors per fat <65536
|
|
|
|
|
test eax,eax
|
|
|
|
|
jnz fat16_fatsize
|
|
|
|
|
mov eax,[ebx+0x24] ; sectors per fat
|
|
|
|
|
fat16_fatsize:
|
|
|
|
|
mov [SECTORS_PER_FAT],eax
|
|
|
|
|
|
|
|
|
|
movzx eax,byte [ebx+0x10] ; number of fats
|
|
|
|
|
test eax,eax ; if 0 it's not fat partition
|
|
|
|
|
jz problem_fat_dec_count
|
|
|
|
|
mov [NUMBER_OF_FATS],eax
|
|
|
|
|
imul eax,[SECTORS_PER_FAT]
|
|
|
|
|
add eax,[FAT_START]
|
|
|
|
|
mov [ROOT_START],eax ; rootdir = fat_start + fat_size * fat_count
|
|
|
|
|
add eax,[ROOT_SECTORS] ; rootdir sectors should be 0 on fat32
|
|
|
|
|
mov [DATA_START],eax ; data area = rootdir + rootdir_size
|
|
|
|
|
|
|
|
|
|
movzx eax,word [ebx+0x13] ; total sector count <65536
|
|
|
|
|
test eax,eax
|
|
|
|
|
jnz fat16_total
|
|
|
|
|
mov eax,[ebx+0x20] ; total sector count
|
|
|
|
|
fat16_total:
|
|
|
|
|
add eax,[PARTITION_START]
|
|
|
|
|
dec eax
|
|
|
|
|
mov [PARTITION_END],eax
|
|
|
|
|
inc eax
|
|
|
|
|
sub eax,[DATA_START] ; eax = count of data sectors
|
|
|
|
|
xor edx,edx
|
|
|
|
|
div dword [SECTORS_PER_CLUSTER]
|
|
|
|
|
inc eax
|
|
|
|
|
mov [LAST_CLUSTER],eax
|
|
|
|
|
dec eax ; cluster count
|
|
|
|
|
|
|
|
|
|
; limits by Microsoft Hardware White Paper v1.03
|
|
|
|
|
cmp eax,4085 ; 0xff5
|
|
|
|
|
jb problem_fat_dec_count ; fat12 not supported
|
|
|
|
|
cmp eax,65525 ; 0xfff5
|
|
|
|
|
jb fat16_partition
|
|
|
|
|
|
|
|
|
|
fat32_partition:
|
|
|
|
|
mov eax,[ebx+0x2c] ; rootdir cluster
|
|
|
|
|
mov [ROOT_CLUSTER],eax
|
|
|
|
|
movzx eax,word [ebx+0x30] ; fs info sector
|
|
|
|
|
add eax,[PARTITION_START]
|
|
|
|
|
mov [ADR_FSINFO],eax
|
|
|
|
|
|
|
|
|
|
popad
|
|
|
|
|
|
|
|
|
|
mov [fatRESERVED],0x0FFFFFF6
|
|
|
|
|
mov [fatBAD],0x0FFFFFF7
|
|
|
|
|
mov [fatEND],0x0FFFFFF8
|
|
|
|
|
mov [fatMASK],0x0FFFFFFF
|
|
|
|
|
mov [fat_type],32 ; Fat32
|
|
|
|
|
mov [hd1_status],0 ; free
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
fat16_partition:
|
|
|
|
|
xor eax,eax
|
|
|
|
|
mov [ROOT_CLUSTER],eax
|
|
|
|
|
|
|
|
|
|
popad
|
|
|
|
|
|
|
|
|
|
mov [fatRESERVED],0x0000FFF6
|
|
|
|
|
mov [fatBAD],0x0000FFF7
|
|
|
|
|
mov [fatEND],0x0000FFF8
|
|
|
|
|
mov [fatMASK],0x0000FFFF
|
|
|
|
|
mov [fat_type],16 ; Fat16
|
|
|
|
|
mov [hd1_status],0 ; free
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
set_FAT:
|
|
|
|
|
;--------------------------------
|
|
|
|
|
; input : EAX = cluster
|
|
|
|
|
; EDX = value to save
|
|
|
|
|
; output : EDX = old value
|
|
|
|
|
;--------------------------------
|
|
|
|
|
push eax ebx esi
|
|
|
|
|
|
|
|
|
|
cmp eax,2
|
|
|
|
|
jb sfc_error
|
|
|
|
|
cmp eax,[LAST_CLUSTER]
|
|
|
|
|
ja sfc_error
|
|
|
|
|
cmp [fat_type],16
|
|
|
|
|
je sfc_1
|
|
|
|
|
add eax,eax
|
|
|
|
|
sfc_1:
|
|
|
|
|
add eax,eax
|
|
|
|
|
mov esi,511
|
|
|
|
|
and esi,eax ; esi = position in fat sector
|
|
|
|
|
shr eax,9 ; eax = fat sector
|
|
|
|
|
add eax,[FAT_START]
|
|
|
|
|
mov ebx,fat_cache
|
|
|
|
|
|
|
|
|
|
cmp eax,[fat_in_cache] ; is fat sector already in memory?
|
|
|
|
|
je sfc_in_cache ; yes
|
|
|
|
|
|
|
|
|
|
cmp [fat_change],0 ; is fat changed?
|
|
|
|
|
je sfc_no_change ; no
|
|
|
|
|
call write_fat_sector ; yes. write it into disk
|
|
|
|
|
|
|
|
|
|
sfc_no_change:
|
|
|
|
|
mov [fat_in_cache],eax ; save fat sector
|
|
|
|
|
call hd_read
|
|
|
|
|
|
|
|
|
|
sfc_in_cache:
|
|
|
|
|
cmp [fat_type],16
|
|
|
|
|
jne sfc_test32
|
|
|
|
|
|
|
|
|
|
cmp [f_del],1 ; overwrite previous value?
|
|
|
|
|
je sfc_set16 ; yes
|
|
|
|
|
cmp word [ebx+esi],0 ; is cluster free?
|
|
|
|
|
je sfc_set16 ; yes
|
|
|
|
|
mov dword [8*0x100000],0xffffff
|
|
|
|
|
mov edx,[ebx+esi] ; get old value
|
|
|
|
|
jmp sfc_nonzero
|
|
|
|
|
|
|
|
|
|
sfc_set16:
|
|
|
|
|
xchg [ebx+esi],dx ; save new value and get old value
|
|
|
|
|
jmp sfc_write
|
|
|
|
|
|
|
|
|
|
sfc_test32:
|
|
|
|
|
mov eax,[fatMASK]
|
|
|
|
|
cmp [f_del],1 ; overwrite previous value?
|
|
|
|
|
je sfc_set32 ; yes
|
|
|
|
|
test eax,[ebx+esi] ; is cluster free?
|
|
|
|
|
je sfc_set32 ; yes
|
|
|
|
|
mov dword [8*0x100000],0xffffff
|
|
|
|
|
mov edx,[ebx+esi] ; get old value
|
|
|
|
|
jmp sfc_nonzero
|
|
|
|
|
|
|
|
|
|
sfc_set32:
|
|
|
|
|
and edx,eax
|
|
|
|
|
xor eax,-1 ; mask for high bits
|
|
|
|
|
and eax,[ebx+esi] ; get high 4 bits
|
|
|
|
|
or eax,edx
|
|
|
|
|
mov edx,[ebx+esi] ; get old value
|
|
|
|
|
mov [ebx+esi],eax ; save new value
|
|
|
|
|
|
|
|
|
|
sfc_write:
|
|
|
|
|
mov [fat_change],1 ; fat has changed
|
|
|
|
|
|
|
|
|
|
sfc_nonzero:
|
|
|
|
|
and edx,[fatMASK]
|
|
|
|
|
|
|
|
|
|
sfc_error:
|
|
|
|
|
pop esi ebx eax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_FAT:
|
|
|
|
|
;--------------------------------
|
|
|
|
|
; input : EAX = cluster
|
|
|
|
|
; output : EAX = next cluster
|
|
|
|
|
;--------------------------------
|
|
|
|
|
push ebx esi
|
|
|
|
|
|
|
|
|
|
cmp [fat_type],16
|
|
|
|
|
je gfc_1
|
|
|
|
|
add eax,eax
|
|
|
|
|
gfc_1:
|
|
|
|
|
add eax,eax
|
|
|
|
|
mov esi,511
|
|
|
|
|
and esi,eax ; esi = position in fat sector
|
|
|
|
|
shr eax,9 ; eax = fat sector
|
|
|
|
|
add eax,[FAT_START]
|
|
|
|
|
mov ebx,fat_cache
|
|
|
|
|
|
|
|
|
|
cmp eax,[fat_in_cache] ; is fat sector already in memory?
|
|
|
|
|
je gfc_in_cache
|
|
|
|
|
|
|
|
|
|
cmp [fat_change],0 ; is fat changed?
|
|
|
|
|
je gfc_no_change ; no
|
|
|
|
|
call write_fat_sector ; yes. write it into disk
|
|
|
|
|
|
|
|
|
|
gfc_no_change:
|
|
|
|
|
mov [fat_in_cache],eax
|
|
|
|
|
call hd_read
|
|
|
|
|
|
|
|
|
|
gfc_in_cache:
|
|
|
|
|
mov eax,[ebx+esi]
|
|
|
|
|
and eax,[fatMASK]
|
|
|
|
|
pop esi ebx
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_free_FAT:
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
; input : EAX = # cluster for start the searching
|
|
|
|
|
; output : if CARRY=0 EAX = # first cluster found free
|
|
|
|
|
; if CARRY=1 disk full
|
|
|
|
|
; Note : for more speed need to use fat_cache directly
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
push ecx
|
|
|
|
|
mov ecx,[LAST_CLUSTER] ; counter for full disk
|
|
|
|
|
sub ecx,2
|
|
|
|
|
|
|
|
|
|
gff_test:
|
|
|
|
|
cmp eax,[LAST_CLUSTER] ; if above last cluster start at cluster 2
|
|
|
|
|
jbe gff_in_range
|
|
|
|
|
mov eax,2
|
|
|
|
|
|
|
|
|
|
gff_in_range:
|
|
|
|
|
push eax
|
|
|
|
|
call get_FAT ; get cluster state
|
|
|
|
|
test eax,eax ; is it free?
|
|
|
|
|
pop eax
|
|
|
|
|
je gff_found ; yes
|
|
|
|
|
inc eax ; next cluster
|
|
|
|
|
dec ecx ; is all checked?
|
|
|
|
|
jns gff_test ; no
|
|
|
|
|
|
|
|
|
|
gff_not_found:
|
|
|
|
|
pop ecx ; yes. disk is full
|
|
|
|
|
stc
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
gff_found:
|
|
|
|
|
pop ecx
|
|
|
|
|
clc
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
write_fat_sector:
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
; write changed fat to disk
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
push eax ebx ecx
|
|
|
|
|
|
|
|
|
|
mov [fat_change],0
|
|
|
|
|
mov eax,[fat_in_cache]
|
|
|
|
|
cmp eax,-1
|
|
|
|
|
jz write_fat_not_used
|
|
|
|
|
mov ebx,fat_cache
|
|
|
|
|
mov ecx,[NUMBER_OF_FATS]
|
|
|
|
|
|
|
|
|
|
write_next_fat:
|
|
|
|
|
call hd_write
|
|
|
|
|
add eax,[SECTORS_PER_FAT]
|
|
|
|
|
dec ecx
|
|
|
|
|
jnz write_next_fat
|
|
|
|
|
|
|
|
|
|
write_fat_not_used:
|
|
|
|
|
pop ecx ebx eax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
analyze_directory:
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
; input : EAX = first cluster of the directory
|
|
|
|
|
; EBX = pointer to filename
|
|
|
|
|
; output : IF CARRY=0 EAX = sector where th file is found
|
|
|
|
|
; EBX = pointer in buffer
|
|
|
|
|
; [buffer .. buffer+511]
|
|
|
|
|
; ECX,EDX,ESI,EDI not changed
|
|
|
|
|
; IF CARRY=1 filename not found
|
|
|
|
|
; Note : if cluster=0 it's changed to read rootdir
|
|
|
|
|
; save 2 previous directory sectors in longname_sec
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
push ecx edx esi edi ebx ; ebx = [esp+0]
|
|
|
|
|
mov [longname_sec1],0
|
|
|
|
|
mov [longname_sec2],0
|
|
|
|
|
|
|
|
|
|
adr_new_cluster:
|
|
|
|
|
mov [cluster_tmp],eax
|
|
|
|
|
mov [fat16_root],0
|
|
|
|
|
cmp eax,[LAST_CLUSTER]
|
|
|
|
|
ja adr_not_found ; too big cluster number, something is wrong
|
|
|
|
|
cmp eax,2
|
|
|
|
|
jnb adr_data_cluster
|
|
|
|
|
|
|
|
|
|
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir
|
|
|
|
|
cmp [fat_type],16
|
|
|
|
|
jne adr_data_cluster
|
|
|
|
|
mov eax,[ROOT_START]
|
|
|
|
|
mov edx,[ROOT_SECTORS]
|
|
|
|
|
mov [fat16_root],1 ; flag for fat16 rootdir
|
|
|
|
|
jmp adr_new_sector
|
|
|
|
|
|
|
|
|
|
adr_data_cluster:
|
|
|
|
|
sub eax,2
|
|
|
|
|
mov edx,[SECTORS_PER_CLUSTER]
|
|
|
|
|
imul eax,edx
|
|
|
|
|
add eax,[DATA_START]
|
|
|
|
|
|
|
|
|
|
adr_new_sector:
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_read
|
|
|
|
|
mov ecx,512/32 ; count of dir entrys per sector = 16
|
|
|
|
|
|
|
|
|
|
adr_analyze:
|
|
|
|
|
mov edi,[ebx+11] ; file attribute
|
|
|
|
|
and edi,0xf
|
|
|
|
|
cmp edi,0xf
|
|
|
|
|
je adr_long_filename
|
|
|
|
|
test edi,0x8 ; skip over volume label
|
|
|
|
|
jne adr_long_filename ; Note: label can be same name as file/dir
|
|
|
|
|
|
|
|
|
|
mov esi,[esp+0] ; filename need to be uppercase
|
|
|
|
|
mov edi,ebx
|
|
|
|
|
push ecx
|
|
|
|
|
mov ecx,11
|
|
|
|
|
cld
|
|
|
|
|
rep cmpsb ; compare 8+3 filename
|
|
|
|
|
pop ecx
|
|
|
|
|
je adr_found
|
|
|
|
|
|
|
|
|
|
adr_long_filename:
|
|
|
|
|
add ebx,32 ; position of next dir entry
|
|
|
|
|
dec ecx
|
|
|
|
|
jnz adr_analyze
|
|
|
|
|
|
|
|
|
|
mov ecx,[longname_sec1] ; save 2 previous directory sectors
|
|
|
|
|
mov [longname_sec1],eax ; for delete long filename
|
|
|
|
|
mov [longname_sec2],ecx
|
|
|
|
|
inc eax ; next sector
|
|
|
|
|
dec edx
|
|
|
|
|
jne adr_new_sector
|
|
|
|
|
cmp [fat16_root],1 ; end of fat16 rootdir
|
|
|
|
|
je adr_not_found
|
|
|
|
|
|
|
|
|
|
adr_next_cluster:
|
|
|
|
|
mov eax,[cluster_tmp]
|
|
|
|
|
call get_FAT ; get next cluster
|
|
|
|
|
cmp eax,2 ; incorrect fat chain?
|
|
|
|
|
jb adr_not_found ; yes
|
|
|
|
|
cmp eax,[fatRESERVED] ; is it end of directory?
|
|
|
|
|
jb adr_new_cluster ; no. analyse it
|
|
|
|
|
|
|
|
|
|
adr_not_found:
|
|
|
|
|
pop edi edi esi edx ecx ; first edi will remove ebx
|
|
|
|
|
stc ; file not found
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
adr_found:
|
|
|
|
|
pop edi edi esi edx ecx ; first edi will remove ebx
|
|
|
|
|
clc ; file found
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
analyze_directory_to_write:
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
; input : EAX = first cluster of the directory
|
|
|
|
|
; output : IF CARRY=0 EAX = sector where the empty pos is found
|
|
|
|
|
; EBX = pointer in buffer
|
|
|
|
|
; [buffer .. buffer+511]
|
|
|
|
|
; ECX,EDX,ESI,EDI not changed
|
|
|
|
|
; IF CARRY=1 disk full or fat corrupted
|
|
|
|
|
; Note : if cluster=0 it's changed to read rootdir
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
push ecx edx edi
|
|
|
|
|
|
|
|
|
|
adw_new_cluster:
|
|
|
|
|
mov [cluster_tmp],eax
|
|
|
|
|
mov [fat16_root],0
|
|
|
|
|
cmp eax,[LAST_CLUSTER]
|
|
|
|
|
ja adw_not_found ; too big cluster number, something is wrong
|
|
|
|
|
cmp eax,2
|
|
|
|
|
jnb adw_data_cluster
|
|
|
|
|
|
|
|
|
|
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir
|
|
|
|
|
cmp [fat_type],16
|
|
|
|
|
jne adw_data_cluster
|
|
|
|
|
mov eax,[ROOT_START]
|
|
|
|
|
mov edx,[ROOT_SECTORS]
|
|
|
|
|
mov [fat16_root],1 ; flag for fat16 rootdir
|
|
|
|
|
jmp adw_new_sector
|
|
|
|
|
|
|
|
|
|
adw_data_cluster:
|
|
|
|
|
sub eax,2
|
|
|
|
|
mov edx,[SECTORS_PER_CLUSTER]
|
|
|
|
|
imul eax,edx
|
|
|
|
|
add eax,[DATA_START]
|
|
|
|
|
|
|
|
|
|
adw_new_sector:
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_read
|
|
|
|
|
mov ecx,512/32 ; count of dir entrys per sector = 16
|
|
|
|
|
|
|
|
|
|
adw_analyze:
|
|
|
|
|
cmp byte [ebx],0x00 ; is free entry?
|
|
|
|
|
je adw_found ; yes
|
|
|
|
|
cmp byte [ebx],0xe5 ; is deleted entry?
|
|
|
|
|
je adw_found ; yes
|
|
|
|
|
add ebx,32 ; position of next dir entry
|
|
|
|
|
dec ecx
|
|
|
|
|
jnz adw_analyze
|
|
|
|
|
|
|
|
|
|
inc eax ; next sector
|
|
|
|
|
dec edx
|
|
|
|
|
jne adw_new_sector
|
|
|
|
|
cmp [fat16_root],1 ; end of fat16 rootdir
|
|
|
|
|
je adw_not_found
|
|
|
|
|
|
|
|
|
|
mov eax,[cluster_tmp]
|
|
|
|
|
call get_FAT ; get next cluster
|
|
|
|
|
cmp eax,2 ; incorrect fat chain?
|
|
|
|
|
jb adw_not_found ; yes
|
|
|
|
|
cmp eax,[fatRESERVED] ; is it end of directory?
|
|
|
|
|
jb adw_new_cluster ; no. analyse it
|
|
|
|
|
|
|
|
|
|
mov eax,2 ; this block of code add a new cluster
|
|
|
|
|
call get_free_FAT ; for the directory because the directory
|
|
|
|
|
jc adw_not_found ; is full
|
|
|
|
|
|
|
|
|
|
mov edx,[fatEND] ; new end for directory
|
|
|
|
|
call set_FAT
|
|
|
|
|
|
|
|
|
|
push eax ; save new cluster
|
|
|
|
|
mov edx,eax
|
|
|
|
|
mov eax,[cluster_tmp] ; change last cluster to point new cluster
|
|
|
|
|
mov [f_del],1
|
|
|
|
|
call set_FAT
|
|
|
|
|
mov [f_del],0
|
|
|
|
|
|
|
|
|
|
mov ecx,-1 ; remove 1 cluster from free disk space
|
|
|
|
|
call add_disk_free_space
|
|
|
|
|
|
|
|
|
|
mov ecx,512/4
|
|
|
|
|
xor eax,eax
|
|
|
|
|
mov edi,buffer
|
|
|
|
|
cld
|
|
|
|
|
rep stosd ; clear new directory cluster
|
|
|
|
|
pop eax
|
|
|
|
|
|
|
|
|
|
sub eax,2
|
|
|
|
|
mov ecx,[SECTORS_PER_CLUSTER]
|
|
|
|
|
imul eax,ecx
|
|
|
|
|
add eax,[DATA_START]
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
push eax ; save sector number
|
|
|
|
|
|
|
|
|
|
adw_set_empty_directory:
|
|
|
|
|
call hd_write
|
|
|
|
|
inc eax ; next sector
|
|
|
|
|
dec ecx
|
|
|
|
|
jnz adw_set_empty_directory
|
|
|
|
|
|
|
|
|
|
pop eax
|
|
|
|
|
|
|
|
|
|
adw_found:
|
|
|
|
|
pop edi edx ecx
|
|
|
|
|
clc ; free space found
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
adw_not_found:
|
|
|
|
|
pop edi edx ecx
|
|
|
|
|
stc ; free space not found
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_data_cluster:
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
; input : EAX = cluster
|
|
|
|
|
; EBX = pointer to buffer
|
|
|
|
|
; EDX = # blocks to read in buffer
|
|
|
|
|
; ESI = # blocks to skip over
|
|
|
|
|
; output : if CARRY=0 ok EBX/EDX/ESI updated
|
|
|
|
|
; if CARRY=1 cluster out of range
|
|
|
|
|
; Note : if cluster=0 it's changed to read rootdir
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
push eax ecx
|
|
|
|
|
|
|
|
|
|
mov [fat16_root],0
|
|
|
|
|
cmp eax,[LAST_CLUSTER]
|
|
|
|
|
ja gdc_error ; too big cluster number, something is wrong
|
|
|
|
|
cmp eax,2
|
|
|
|
|
jnb gdc_cluster
|
|
|
|
|
|
|
|
|
|
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir
|
|
|
|
|
cmp [fat_type],16
|
|
|
|
|
jne gdc_cluster
|
|
|
|
|
mov eax,[ROOT_START]
|
|
|
|
|
mov ecx,[ROOT_SECTORS] ; Note: not cluster size
|
|
|
|
|
mov [fat16_root],1 ; flag for fat16 rootdir
|
|
|
|
|
jmp gdc_read
|
|
|
|
|
|
|
|
|
|
gdc_cluster:
|
|
|
|
|
sub eax,2
|
|
|
|
|
mov ecx,[SECTORS_PER_CLUSTER]
|
|
|
|
|
imul eax,ecx
|
|
|
|
|
add eax,[DATA_START]
|
|
|
|
|
|
|
|
|
|
gdc_read:
|
|
|
|
|
test esi,esi ; first wanted block
|
|
|
|
|
je gdcl1 ; yes, skip count is 0
|
|
|
|
|
dec esi
|
|
|
|
|
jmp gdcl2
|
|
|
|
|
|
|
|
|
|
gdcl1:
|
|
|
|
|
call hd_read
|
|
|
|
|
add ebx,512 ; update pointer
|
|
|
|
|
dec edx
|
|
|
|
|
|
|
|
|
|
gdcl2:
|
|
|
|
|
test edx,edx ; is all read?
|
|
|
|
|
je out_of_read
|
|
|
|
|
|
|
|
|
|
inc eax ; next sector
|
|
|
|
|
dec ecx
|
|
|
|
|
jnz gdc_read
|
|
|
|
|
|
|
|
|
|
out_of_read:
|
|
|
|
|
pop ecx eax
|
|
|
|
|
clc
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
gdc_error:
|
|
|
|
|
pop ecx eax
|
|
|
|
|
stc
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
set_data_cluster:
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
; input : EAX = cluster
|
|
|
|
|
; EBX = pointer to buffer
|
|
|
|
|
; output : if CARRY=0 ok
|
|
|
|
|
; if CARRY=1 cluster out of range
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
push eax ebx edx
|
|
|
|
|
|
|
|
|
|
cmp eax,[LAST_CLUSTER]
|
|
|
|
|
ja sdc_error ; too big cluster number, something is wrong
|
|
|
|
|
sub eax,2
|
|
|
|
|
jb sdc_error ; don't allow rootdir write
|
|
|
|
|
|
|
|
|
|
mov edx,[SECTORS_PER_CLUSTER]
|
|
|
|
|
imul eax,edx
|
|
|
|
|
add eax,[DATA_START]
|
|
|
|
|
|
|
|
|
|
sdc_write:
|
|
|
|
|
call hd_write
|
|
|
|
|
add ebx,512 ; update pointer
|
|
|
|
|
inc eax
|
|
|
|
|
dec edx
|
|
|
|
|
jnz sdc_write
|
|
|
|
|
pop edx ebx eax
|
|
|
|
|
clc
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
sdc_error:
|
|
|
|
|
pop edx ebx eax
|
|
|
|
|
stc
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_cluster_of_a_path:
|
|
|
|
|
;---------------------------------------------------------
|
|
|
|
|
; input : EBX = pointer to a path string
|
|
|
|
|
; (example: the path "/files/data/document" become
|
|
|
|
|
; "files......data.......document...0"
|
|
|
|
|
; '.' = space char
|
|
|
|
|
; '0' = char(0) (ASCII=0) !!! )
|
|
|
|
|
; output : if (CARRY=1) -> ERROR in the PATH
|
|
|
|
|
; if (CARRY=0) -> EAX=cluster
|
|
|
|
|
;---------------------------------------------------------
|
|
|
|
|
push ebx edx
|
|
|
|
|
|
|
|
|
|
mov eax,[ROOT_CLUSTER]
|
|
|
|
|
mov edx,ebx
|
|
|
|
|
|
|
|
|
|
search_end_of_path:
|
|
|
|
|
cmp byte [edx],0
|
|
|
|
|
je found_end_of_path
|
|
|
|
|
|
|
|
|
|
inc edx ; '/'
|
|
|
|
|
mov ebx,edx
|
|
|
|
|
call analyze_directory
|
|
|
|
|
jc directory_not_found
|
|
|
|
|
|
|
|
|
|
mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field
|
|
|
|
|
mov ax,[ebx+26] ; read the LOW 16bit cluster field
|
|
|
|
|
and eax,[fatMASK]
|
|
|
|
|
add edx,11 ; 8+3 (name+extension)
|
|
|
|
|
jmp search_end_of_path
|
|
|
|
|
|
|
|
|
|
found_end_of_path:
|
|
|
|
|
pop edx ebx
|
|
|
|
|
clc ; no errors
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
directory_not_found:
|
|
|
|
|
pop edx ebx
|
|
|
|
|
stc ; errors occour
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bcd2bin:
|
|
|
|
|
;----------------------------------
|
|
|
|
|
; input : AL=BCD number (eg. 0x11)
|
|
|
|
|
; output : AH=0
|
|
|
|
|
; AL=decimal number (eg. 11)
|
|
|
|
|
;----------------------------------
|
|
|
|
|
xor ah,ah
|
|
|
|
|
shl ax,4
|
|
|
|
|
shr al,4
|
|
|
|
|
aad
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_date_for_file:
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
; Get date from CMOS and pack day,month,year in AX
|
|
|
|
|
; DATE bits 0..4 : day of month 0..31
|
|
|
|
|
; 5..8 : month of year 1..12
|
|
|
|
|
; 9..15 : count of years from 1980
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
mov al,0x7 ;day
|
|
|
|
|
out 0x70,al
|
|
|
|
|
in al,0x71
|
|
|
|
|
call bcd2bin
|
|
|
|
|
ror eax,5
|
|
|
|
|
|
|
|
|
|
mov al,0x8 ;month
|
|
|
|
|
out 0x70,al
|
|
|
|
|
in al,0x71
|
|
|
|
|
call bcd2bin
|
|
|
|
|
ror eax,4
|
|
|
|
|
|
|
|
|
|
mov al,0x9 ;year
|
|
|
|
|
out 0x70,al
|
|
|
|
|
in al,0x71
|
|
|
|
|
call bcd2bin
|
|
|
|
|
add ax,20 ;because CMOS return only the two last
|
|
|
|
|
;digit (eg. 2000 -> 00 , 2001 -> 01) and we
|
|
|
|
|
rol eax,9 ;need the difference with 1980 (eg. 2001-1980)
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_time_for_file:
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
; Get time from CMOS and pack hour,minute,second in AX
|
|
|
|
|
; TIME bits 0..4 : second (the low bit is lost)
|
|
|
|
|
; 5..10 : minute 0..59
|
|
|
|
|
; 11..15 : hour 0..23
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
mov al,0x0 ;second
|
|
|
|
|
out 0x70,al
|
|
|
|
|
in al,0x71
|
|
|
|
|
call bcd2bin
|
|
|
|
|
ror eax,6
|
|
|
|
|
|
|
|
|
|
mov al,0x2 ;minute
|
|
|
|
|
out 0x70,al
|
|
|
|
|
in al,0x71
|
|
|
|
|
call bcd2bin
|
|
|
|
|
ror eax,6
|
|
|
|
|
|
|
|
|
|
mov al,0x4 ;hour
|
|
|
|
|
out 0x70,al
|
|
|
|
|
in al,0x71
|
|
|
|
|
call bcd2bin
|
|
|
|
|
rol eax,11
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
set_current_time_for_entry:
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
; Set current time/date for file entry
|
|
|
|
|
; input : ebx = file entry pointer
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
push eax
|
|
|
|
|
call get_time_for_file ; update files date/time
|
|
|
|
|
mov [ebx+22],ax
|
|
|
|
|
call get_date_for_file
|
|
|
|
|
mov [ebx+24],ax
|
|
|
|
|
pop eax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
makedir:
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
; input : eax = directory name
|
|
|
|
|
; edx = path
|
|
|
|
|
; output : eax = 0 - ok
|
|
|
|
|
; 3 - unknown FS
|
|
|
|
|
; 5 - file not found
|
|
|
|
|
; 8 - disk full
|
|
|
|
|
; 10 - access denied
|
|
|
|
|
; Note : can only make one directory at time
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
cmp [fat_type],0
|
|
|
|
|
jnz make_dir_fat_ok
|
|
|
|
|
mov eax,ERROR_UNKNOWN_FS
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
make_dir_fat_ok:
|
|
|
|
|
; call reserve_hd1
|
|
|
|
|
|
|
|
|
|
pushad
|
|
|
|
|
|
|
|
|
|
mov ebx,edx
|
|
|
|
|
call get_cluster_of_a_path
|
|
|
|
|
jnc make_dir_found_path
|
|
|
|
|
|
|
|
|
|
make_dir_path_not_found:
|
|
|
|
|
popad
|
|
|
|
|
call update_disk ; write all of cache and fat to hd
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
mov eax,ERROR_FILE_NOT_FOUND
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
make_dir_disk_full:
|
|
|
|
|
popad
|
|
|
|
|
call update_disk ; write all of cache and fat to hd
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
mov eax,ERROR_DISK_FULL
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
make_dir_already_exist:
|
|
|
|
|
mov eax,[cluster] ; directory cluster
|
|
|
|
|
xor edx,edx ; free
|
|
|
|
|
mov [f_del],1
|
|
|
|
|
call set_FAT
|
|
|
|
|
mov [f_del],0
|
|
|
|
|
|
|
|
|
|
popad
|
|
|
|
|
call update_disk ; write all of cache and fat to hd
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
mov eax,ERROR_ACCESS_DENIED
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
make_dir_found_path:
|
|
|
|
|
cmp eax,[ROOT_CLUSTER]
|
|
|
|
|
jnz make_dir_not_root
|
|
|
|
|
xor eax,eax
|
|
|
|
|
|
|
|
|
|
make_dir_not_root:
|
|
|
|
|
mov ecx,eax ; directorys start cluster
|
|
|
|
|
mov word [NewDirEntry2+26],cx ; 16 bits low of cluster
|
|
|
|
|
shr ecx,16
|
|
|
|
|
mov word [NewDirEntry2+20],cx ; 16 bits high of cluster (=0 fat16)
|
|
|
|
|
|
|
|
|
|
push eax ; save parent directory cluster
|
|
|
|
|
mov eax,2
|
|
|
|
|
call get_free_FAT
|
|
|
|
|
mov [cluster],eax ; first free cluster
|
|
|
|
|
pop eax
|
|
|
|
|
jc make_dir_disk_full
|
|
|
|
|
|
|
|
|
|
push eax
|
|
|
|
|
mov eax,[cluster] ; directory cluster
|
|
|
|
|
mov edx,[fatEND] ; end for directory
|
|
|
|
|
call set_FAT
|
|
|
|
|
pop eax
|
|
|
|
|
|
|
|
|
|
mov ebx,PUSHAD_EAX ; dir name
|
|
|
|
|
push eax
|
|
|
|
|
call analyze_directory ; check if directory already exist
|
|
|
|
|
pop eax
|
|
|
|
|
jnc make_dir_already_exist ; need to free allocated cluster!
|
|
|
|
|
|
|
|
|
|
call analyze_directory_to_write
|
|
|
|
|
jc make_dir_already_exist ; need to free allocated cluster!
|
|
|
|
|
|
|
|
|
|
mov esi,PUSHAD_EAX ; dir name
|
|
|
|
|
mov edi,ebx ; pointer in buffer
|
|
|
|
|
mov ecx,11
|
|
|
|
|
cld
|
|
|
|
|
rep movsb
|
|
|
|
|
|
|
|
|
|
mov dword [ebx+28],0 ; dir size is always 0
|
|
|
|
|
mov ecx,[cluster]
|
|
|
|
|
mov [ebx+26],cx ; 16 bits low of cluster
|
|
|
|
|
mov word [NewDirEntry1+26],cx
|
|
|
|
|
shr ecx,16
|
|
|
|
|
mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16)
|
|
|
|
|
mov word [NewDirEntry1+20],cx
|
|
|
|
|
mov byte [ebx+11],0x10 ; attribute = directory
|
|
|
|
|
|
|
|
|
|
call set_current_time_for_entry
|
|
|
|
|
mov ecx,[ebx+22]
|
|
|
|
|
mov dword [NewDirEntry1+22],ecx
|
|
|
|
|
mov dword [NewDirEntry2+22],ecx
|
|
|
|
|
|
|
|
|
|
mov ebx,buffer ; save the directory name,length,cluster
|
|
|
|
|
call hd_write
|
|
|
|
|
|
|
|
|
|
mov ecx,512/4
|
|
|
|
|
xor eax,eax
|
|
|
|
|
mov edi,buffer
|
|
|
|
|
cld
|
|
|
|
|
rep stosd ; clear new directory cluster
|
|
|
|
|
|
|
|
|
|
mov eax,[cluster] ; new directory cluster
|
|
|
|
|
sub eax,2
|
|
|
|
|
mov edx,[SECTORS_PER_CLUSTER]
|
|
|
|
|
imul eax,edx
|
|
|
|
|
add eax,[DATA_START]
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
add eax,edx ; start from last sector
|
|
|
|
|
|
|
|
|
|
dir_set_empty_directory:
|
|
|
|
|
dec eax ; next sector
|
|
|
|
|
cmp edx,1 ; is first directory sector?
|
|
|
|
|
jnz not_first_sector ; no. write empty sector
|
|
|
|
|
mov esi,NewDirEntry1
|
|
|
|
|
mov edi,buffer
|
|
|
|
|
mov ecx,64/4
|
|
|
|
|
cld
|
|
|
|
|
rep movsd ; copy 2 first directory entrys "." and ".."
|
|
|
|
|
|
|
|
|
|
not_first_sector:
|
|
|
|
|
call hd_write
|
|
|
|
|
dec edx
|
|
|
|
|
jnz dir_set_empty_directory
|
|
|
|
|
|
|
|
|
|
mov ecx,-1 ; remove 1 cluster from free disk space
|
|
|
|
|
call add_disk_free_space
|
|
|
|
|
|
|
|
|
|
popad
|
|
|
|
|
call update_disk ; write all of cache and fat to hd
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
xor eax,eax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
removedir:
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
; input : eax = file/directory name
|
|
|
|
|
; edx = path
|
|
|
|
|
; output : eax = 0 - ok
|
|
|
|
|
; 3 - unknown FS
|
|
|
|
|
; 5 - file not found
|
|
|
|
|
; 10 - access denied
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
cmp [fat_type],0
|
|
|
|
|
jnz remove_dir_fat_ok
|
|
|
|
|
mov eax,ERROR_UNKNOWN_FS
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
remove_dir_fat_ok:
|
|
|
|
|
; call reserve_hd1
|
|
|
|
|
|
|
|
|
|
push edi
|
|
|
|
|
mov edi,1 ; allow directory remove
|
|
|
|
|
call file_delete
|
|
|
|
|
pop edi
|
|
|
|
|
|
|
|
|
|
call update_disk ; write all of cache and fat to hd
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
add_disk_free_space:
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
; input : ecx = cluster count
|
|
|
|
|
; Note : negative = remove clusters from free space
|
|
|
|
|
; positive = add clusters to free space
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
test ecx,ecx ; no change
|
|
|
|
|
je add_dfs_no
|
|
|
|
|
cmp [fat_type],32 ; free disk space only used by fat32
|
|
|
|
|
jne add_dfs_no
|
|
|
|
|
|
|
|
|
|
push eax ebx
|
|
|
|
|
mov eax,[ADR_FSINFO]
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_read
|
|
|
|
|
cmp dword [ebx+0x1fc],0xaa550000 ; check sector id
|
|
|
|
|
jne add_not_fs
|
|
|
|
|
|
|
|
|
|
add [ebx+0x1e8],ecx
|
|
|
|
|
call hd_write
|
|
|
|
|
|
|
|
|
|
add_not_fs:
|
|
|
|
|
pop ebx eax
|
|
|
|
|
|
|
|
|
|
add_dfs_no:
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
file_append:
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
; input : eax = file name
|
|
|
|
|
; edx = path
|
|
|
|
|
; ecx = pointer to buffer
|
|
|
|
|
; ebx = bytes to write (0 = truncate file)
|
|
|
|
|
; esi = start position (-1 = end of file)
|
|
|
|
|
; output : eax = 0 - ok
|
|
|
|
|
; 3 - unknown FS
|
|
|
|
|
; 5 - file not found
|
|
|
|
|
; 6 - end of file
|
|
|
|
|
; 8 - disk full
|
|
|
|
|
; 9 - fat table corrupted
|
|
|
|
|
; 10 - access denied
|
|
|
|
|
; ebx = bytes written
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
cmp [fat_type],0
|
|
|
|
|
jnz append_fat_ok
|
|
|
|
|
mov eax,ERROR_UNKNOWN_FS
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
append_fat_ok:
|
|
|
|
|
; call reserve_hd1
|
|
|
|
|
|
|
|
|
|
pushad
|
|
|
|
|
|
|
|
|
|
mov ebx,edx
|
|
|
|
|
call get_cluster_of_a_path
|
|
|
|
|
jc append_not_found
|
|
|
|
|
|
|
|
|
|
mov ebx,PUSHAD_EAX ; file name
|
|
|
|
|
call analyze_directory
|
|
|
|
|
jc append_not_found
|
|
|
|
|
|
|
|
|
|
mov [sector_tmp],eax
|
|
|
|
|
mov [entry_pos],ebx
|
|
|
|
|
|
|
|
|
|
test byte [ebx+11],0x10 ; is it directory?
|
|
|
|
|
jnz append_access ; yes
|
|
|
|
|
|
|
|
|
|
mov ecx,[ebx+28] ; file size
|
|
|
|
|
mov edi,PUSHAD_ESI ; write position
|
|
|
|
|
cmp edi,-1 ; -1 = eof
|
|
|
|
|
jnz append_inside_file
|
|
|
|
|
mov edi,ecx ; file size
|
|
|
|
|
|
|
|
|
|
append_inside_file:
|
|
|
|
|
cmp edi,ecx ; start above old file size?
|
|
|
|
|
ja append_eof ; yes
|
|
|
|
|
|
|
|
|
|
mov [old_filesize],ecx
|
|
|
|
|
mov [new_filepos],edi
|
|
|
|
|
|
|
|
|
|
mov ecx,PUSHAD_EBX ; bytes to write
|
|
|
|
|
test ecx,ecx ; truncate?
|
|
|
|
|
jz append_truncate ; yes
|
|
|
|
|
|
|
|
|
|
mov [bytes2write],ecx ; bytes to write
|
|
|
|
|
mov esi,PUSHAD_ECX ; pointer to buffer
|
|
|
|
|
mov eax,[ebx+20-2] ; FAT entry
|
|
|
|
|
mov ax,[ebx+26]
|
|
|
|
|
and eax,[fatMASK]
|
|
|
|
|
jnz append_find_pos ; first cluster <> 0
|
|
|
|
|
|
|
|
|
|
mov eax,2
|
|
|
|
|
call get_free_FAT
|
|
|
|
|
jc append_disk_full
|
|
|
|
|
mov ecx,eax ; set files first cluster
|
|
|
|
|
mov [ebx+26],cx ; 16 bits low of cluster
|
|
|
|
|
shr ecx,16
|
|
|
|
|
mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16)
|
|
|
|
|
mov edx,[fatEND] ; new end for cluster chain
|
|
|
|
|
call set_FAT
|
|
|
|
|
|
|
|
|
|
push eax ; save first cluster
|
|
|
|
|
mov eax,[sector_tmp]
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_write ; write new file entry back to disk
|
|
|
|
|
pop eax
|
|
|
|
|
|
|
|
|
|
append_remove_free:
|
|
|
|
|
mov ecx,-1 ; remove 1 cluster from free disk space
|
|
|
|
|
call add_disk_free_space ; Note: uses buffer
|
|
|
|
|
|
|
|
|
|
append_found_cluster:
|
|
|
|
|
mov [cluster],eax
|
|
|
|
|
sub eax,2
|
|
|
|
|
mov ecx,[SECTORS_PER_CLUSTER]
|
|
|
|
|
imul eax,ecx
|
|
|
|
|
add eax,[DATA_START]
|
|
|
|
|
xor edi,edi
|
|
|
|
|
|
|
|
|
|
append_new_sector:
|
|
|
|
|
push ecx
|
|
|
|
|
mov ecx,[bytes2write] ; bytes left in buffer
|
|
|
|
|
mov ebx,512
|
|
|
|
|
sub ebx,edi ; bytes left in sector
|
|
|
|
|
cmp ecx,ebx
|
|
|
|
|
jb append_bytes_ok
|
|
|
|
|
mov ecx,ebx
|
|
|
|
|
|
|
|
|
|
append_bytes_ok:
|
|
|
|
|
cmp ecx,512 ; overwrite full sector?
|
|
|
|
|
jz append_full_sector ; yes
|
|
|
|
|
mov ebx,buffer ; overwrite part of sector
|
|
|
|
|
call hd_read ; read old sector
|
|
|
|
|
|
|
|
|
|
append_full_sector:
|
|
|
|
|
sub [bytes2write],ecx
|
|
|
|
|
add [new_filepos],ecx
|
|
|
|
|
add edi,buffer
|
|
|
|
|
cld
|
|
|
|
|
rep movsb
|
|
|
|
|
pop ecx
|
|
|
|
|
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_write
|
|
|
|
|
cmp [bytes2write],0 ; is all done?
|
|
|
|
|
jz append_done
|
|
|
|
|
xor edi,edi
|
|
|
|
|
inc eax
|
|
|
|
|
dec ecx
|
|
|
|
|
jnz append_new_sector
|
|
|
|
|
|
|
|
|
|
mov eax,[cluster]
|
|
|
|
|
call get_FAT
|
|
|
|
|
cmp eax,2
|
|
|
|
|
jb append_fat
|
|
|
|
|
cmp eax,[LAST_CLUSTER]
|
|
|
|
|
jbe append_found_cluster
|
|
|
|
|
|
|
|
|
|
append_alloc_cluster:
|
|
|
|
|
mov eax,2 ; ToDo: use temp array to keep track
|
|
|
|
|
call get_free_FAT ; of last free cluster
|
|
|
|
|
jc append_disk_full
|
|
|
|
|
push eax ; save new cluster
|
|
|
|
|
mov edx,[fatEND] ; new end for cluster chain
|
|
|
|
|
call set_FAT
|
|
|
|
|
mov edx,eax
|
|
|
|
|
mov eax,[cluster]
|
|
|
|
|
mov [f_del],1
|
|
|
|
|
call set_FAT ; update previous cluster
|
|
|
|
|
mov [f_del],0
|
|
|
|
|
pop eax
|
|
|
|
|
jmp append_remove_free
|
|
|
|
|
|
|
|
|
|
append_find_pos:
|
|
|
|
|
call find_filepos
|
|
|
|
|
mov [cluster],ebx
|
|
|
|
|
jnc append_new_sector
|
|
|
|
|
test edi,edi
|
|
|
|
|
jz append_alloc_cluster
|
|
|
|
|
|
|
|
|
|
append_fat:
|
|
|
|
|
mov eax,ERROR_FAT_TABLE
|
|
|
|
|
jmp append_ret_code
|
|
|
|
|
|
|
|
|
|
append_disk_full:
|
|
|
|
|
mov eax,ERROR_DISK_FULL
|
|
|
|
|
jmp append_ret_code
|
|
|
|
|
|
|
|
|
|
append_done:
|
|
|
|
|
xor eax,eax
|
|
|
|
|
|
|
|
|
|
append_ret_code:
|
|
|
|
|
mov PUSHAD_EAX,eax ; return code
|
|
|
|
|
|
|
|
|
|
mov eax,[sector_tmp] ; update directory entry
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_read
|
|
|
|
|
mov ebx,[entry_pos]
|
|
|
|
|
mov ecx,[new_filepos]
|
|
|
|
|
cmp ecx,[old_filesize] ; is file pos above old size?
|
|
|
|
|
jbe append_size_ok ; no
|
|
|
|
|
mov [ebx+28],ecx ; new file size
|
|
|
|
|
|
|
|
|
|
append_size_ok:
|
|
|
|
|
call set_current_time_for_entry
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_write ; write new file entry back to disk
|
|
|
|
|
|
|
|
|
|
sub ecx,PUSHAD_ESI ; start position
|
|
|
|
|
mov PUSHAD_EBX,ecx ; bytes written
|
|
|
|
|
popad
|
|
|
|
|
call update_disk ; write all of cache and fat to hd
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
append_eof:
|
|
|
|
|
popad
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
xor ebx,ebx
|
|
|
|
|
mov eax,ERROR_END_OF_FILE
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
append_not_found:
|
|
|
|
|
popad
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
xor ebx,ebx
|
|
|
|
|
mov eax,ERROR_FILE_NOT_FOUND
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
append_access:
|
|
|
|
|
popad
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
xor ebx,ebx
|
|
|
|
|
mov eax,ERROR_ACCESS_DENIED
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
append_truncate:
|
|
|
|
|
mov edx,[ebx+20-2] ; FAT entry
|
|
|
|
|
mov dx,[ebx+26]
|
|
|
|
|
and edx,[fatMASK]
|
|
|
|
|
mov [ebx+28],edi ; set new file size
|
|
|
|
|
test edi,edi ; 0 length file?
|
|
|
|
|
jnz truncate_save_size ; no
|
|
|
|
|
mov [ebx+20],di ; FAT entry = 0
|
|
|
|
|
mov [ebx+26],di
|
|
|
|
|
|
|
|
|
|
truncate_save_size:
|
|
|
|
|
call set_current_time_for_entry
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_write
|
|
|
|
|
mov eax,edx ; first cluster
|
|
|
|
|
test edi,edi ; 0 length file?
|
|
|
|
|
jz truncate_clear_chain
|
|
|
|
|
|
|
|
|
|
imul esi,[SECTORS_PER_CLUSTER],512 ; esi = cluster size in bytes
|
|
|
|
|
|
|
|
|
|
truncate_new_cluster:
|
|
|
|
|
cmp eax,2 ; incorrect fat chain?
|
|
|
|
|
jb truncate_eof ; yes
|
|
|
|
|
cmp eax,[fatRESERVED] ; is it end of file?
|
|
|
|
|
jnb truncate_eof ; yes
|
|
|
|
|
sub edi,esi
|
|
|
|
|
jbe truncate_pos_found
|
|
|
|
|
call get_FAT ; get next cluster
|
|
|
|
|
jmp truncate_new_cluster
|
|
|
|
|
|
|
|
|
|
truncate_pos_found:
|
|
|
|
|
mov edx,[fatEND] ; new end for cluster chain
|
|
|
|
|
mov [f_del],1
|
|
|
|
|
call set_FAT
|
|
|
|
|
mov [f_del],0
|
|
|
|
|
mov eax,edx ; clear rest of chain
|
|
|
|
|
|
|
|
|
|
truncate_clear_chain:
|
|
|
|
|
call clear_cluster_chain
|
|
|
|
|
|
|
|
|
|
truncate_eof:
|
|
|
|
|
popad
|
|
|
|
|
call update_disk ; write all of cache and fat to hd
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
xor ebx,ebx
|
|
|
|
|
xor eax,eax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
find_filepos:
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
; input : eax = first cluster
|
|
|
|
|
; edi = bytes to skip over (start position)
|
|
|
|
|
; output : if CARRY=0 file position found
|
|
|
|
|
; if CARRY=1 end of file found
|
|
|
|
|
; eax = current file sector
|
|
|
|
|
; ebx = last cluster
|
|
|
|
|
; ecx = sector count in last cluster
|
|
|
|
|
; edi = bytes to skip over (sector position)
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
push esi
|
|
|
|
|
mov ecx,[SECTORS_PER_CLUSTER]
|
|
|
|
|
imul esi,ecx,512 ; esi = cluster size in bytes
|
|
|
|
|
mov ebx,eax
|
|
|
|
|
|
|
|
|
|
filepos_new_cluster:
|
|
|
|
|
cmp eax,2 ; incorrect fat chain?
|
|
|
|
|
jb filepos_eof ; yes
|
|
|
|
|
cmp eax,[fatRESERVED] ; is it end of file?
|
|
|
|
|
jnb filepos_eof ; yes
|
|
|
|
|
|
|
|
|
|
mov ebx,eax
|
|
|
|
|
cmp edi,esi ; skip over full cluster?
|
|
|
|
|
jb filepos_cluster_ok ; no
|
|
|
|
|
|
|
|
|
|
sub edi,esi
|
|
|
|
|
call get_FAT ; get next cluster
|
|
|
|
|
jmp filepos_new_cluster
|
|
|
|
|
|
|
|
|
|
filepos_cluster_ok:
|
|
|
|
|
sub eax,2
|
|
|
|
|
imul eax,ecx
|
|
|
|
|
add eax,[DATA_START]
|
|
|
|
|
|
|
|
|
|
filepos_new_sector:
|
|
|
|
|
cmp edi,512 ; skip over full sector?
|
|
|
|
|
jb filepos_sector_ok ; no
|
|
|
|
|
sub edi,512
|
|
|
|
|
inc eax
|
|
|
|
|
dec ecx
|
|
|
|
|
jnz filepos_new_sector
|
|
|
|
|
|
|
|
|
|
filepos_eof:
|
|
|
|
|
pop esi
|
|
|
|
|
stc
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
filepos_sector_ok:
|
|
|
|
|
pop esi
|
|
|
|
|
clc
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
file_write:
|
|
|
|
|
;--------------------------------------------------------------------------
|
|
|
|
|
; INPUT : user-reg register-in-this meaning symbol-in-this-routine
|
|
|
|
|
;
|
|
|
|
|
; EAX EDI system call to write /
|
|
|
|
|
; EBX EAX (PAR0) pointer to file-name PAR0
|
|
|
|
|
; EDX ECX (PAR1) pointer to buffer PAR1
|
|
|
|
|
; ECX EBX (PAR2) file size PAR2
|
|
|
|
|
; ESI EDX (PAR3) pointer to path PAR3
|
|
|
|
|
;
|
|
|
|
|
; output : eax = 0 - ok
|
|
|
|
|
; 3 - unknown FS
|
|
|
|
|
; 5 - file not found
|
|
|
|
|
; 8 - disk full
|
|
|
|
|
; 10 - access denied
|
|
|
|
|
;--------------------------------------------------------------------------
|
|
|
|
|
cmp [fat_type],0
|
|
|
|
|
jnz fat_ok_for_writing
|
|
|
|
|
mov eax,ERROR_UNKNOWN_FS
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
fat_ok_for_writing:
|
|
|
|
|
; call reserve_hd1
|
|
|
|
|
|
|
|
|
|
pushad
|
|
|
|
|
|
|
|
|
|
xor edi,edi ; don't allow directory remove
|
|
|
|
|
call file_delete ; try to delete the file first
|
|
|
|
|
test eax,eax
|
|
|
|
|
jz old_deleted ; deleted ok
|
|
|
|
|
cmp eax,ERROR_FILE_NOT_FOUND
|
|
|
|
|
jnz exit_write_access ; it exist but can't delete
|
|
|
|
|
|
|
|
|
|
old_deleted:
|
|
|
|
|
mov ebx,PUSHAD_EDX
|
|
|
|
|
call get_cluster_of_a_path
|
|
|
|
|
jnc found_directory_for_writing
|
|
|
|
|
|
|
|
|
|
exit_writing_with_error:
|
|
|
|
|
popad
|
|
|
|
|
call update_disk ; write all of cache and fat to hd
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
mov eax,ERROR_FILE_NOT_FOUND
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
exit_writing_disk_full_clear:
|
|
|
|
|
mov eax,[sector_tmp]
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_read ; read directory sector
|
|
|
|
|
mov edx,[entry_pos]
|
|
|
|
|
mov byte [edx],0xe5 ; mark as deleted
|
|
|
|
|
call hd_write
|
|
|
|
|
mov eax,[edx+20-2] ; FAT entry
|
|
|
|
|
mov ax,[edx+26]
|
|
|
|
|
and eax,[fatMASK]
|
|
|
|
|
call clear_cluster_chain
|
|
|
|
|
|
|
|
|
|
exit_writing_disk_full:
|
|
|
|
|
popad
|
|
|
|
|
call update_disk ; write all of cache and fat to hd
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
mov eax,ERROR_DISK_FULL
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
exit_write_access:
|
|
|
|
|
popad
|
|
|
|
|
call update_disk ; write all of cache and fat to hd
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
mov eax,ERROR_ACCESS_DENIED
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
found_directory_for_writing:
|
|
|
|
|
call analyze_directory_to_write
|
|
|
|
|
jc exit_writing_disk_full
|
|
|
|
|
|
|
|
|
|
mov [sector_tmp],eax
|
|
|
|
|
mov [entry_pos],ebx
|
|
|
|
|
push eax ; save directory sector
|
|
|
|
|
mov eax,2
|
|
|
|
|
call get_free_FAT
|
|
|
|
|
mov [cluster],eax ; first free cluster
|
|
|
|
|
pop eax
|
|
|
|
|
jc exit_writing_disk_full
|
|
|
|
|
|
|
|
|
|
mov esi,PUSHAD_EAX ; file name
|
|
|
|
|
mov edi,ebx ; pointer in buffer
|
|
|
|
|
mov ecx,11
|
|
|
|
|
cld
|
|
|
|
|
rep movsb
|
|
|
|
|
|
|
|
|
|
mov esi,PUSHAD_EBX ; file size (bytes left)
|
|
|
|
|
mov [ebx+28],esi ; file size
|
|
|
|
|
mov ecx,[cluster]
|
|
|
|
|
mov [ebx+26],cx ; 16 bits low of cluster
|
|
|
|
|
shr ecx,16
|
|
|
|
|
mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16)
|
|
|
|
|
mov byte [ebx+11],0x20 ; attribute = archive
|
|
|
|
|
|
|
|
|
|
call set_current_time_for_entry
|
|
|
|
|
|
|
|
|
|
mov ebx,buffer ; save the directory name,length,cluster
|
|
|
|
|
call hd_write
|
|
|
|
|
|
|
|
|
|
imul edi,[SECTORS_PER_CLUSTER],512 ; edi = cluster size in bytes
|
|
|
|
|
xor ecx,ecx ; cluster count
|
|
|
|
|
mov ebx,PUSHAD_ECX ; ebx = buffer
|
|
|
|
|
|
|
|
|
|
hd_new_block_write:
|
|
|
|
|
|
|
|
|
|
mov eax,[cluster] ; eax = block
|
|
|
|
|
call set_data_cluster
|
|
|
|
|
|
|
|
|
|
sub esi,edi ; sub wrote bytes
|
|
|
|
|
jbe file_saved_OK ; end if all done
|
|
|
|
|
add ebx,edi ; update buffer position
|
|
|
|
|
|
|
|
|
|
inc eax
|
|
|
|
|
call get_free_FAT ; next free in FAT
|
|
|
|
|
jc exit_writing_disk_full_clear
|
|
|
|
|
|
|
|
|
|
mov edx,eax
|
|
|
|
|
xchg eax,[cluster] ; get old cluster and save new cluster
|
|
|
|
|
call set_FAT ; add it in cluster chain
|
|
|
|
|
dec ecx ; update cluster count
|
|
|
|
|
jmp hd_new_block_write
|
|
|
|
|
|
|
|
|
|
file_saved_OK:
|
|
|
|
|
|
|
|
|
|
mov edx,[fatEND] ; new end for cluster chain
|
|
|
|
|
call set_FAT
|
|
|
|
|
dec ecx ; update cluster count
|
|
|
|
|
|
|
|
|
|
call add_disk_free_space ; remove clusters from free disk space
|
|
|
|
|
|
|
|
|
|
popad
|
|
|
|
|
call update_disk ; write all of cache and fat to hd
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
xor eax,eax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
file_read:
|
|
|
|
|
;--------------------------------------------------------------------------
|
|
|
|
|
; INPUT : user-register register-in-this meaning symbol-in-this
|
|
|
|
|
;
|
|
|
|
|
; EAX EDI system call to write /
|
|
|
|
|
; EBX EAX (PAR0) pointer to file-name PAR0
|
|
|
|
|
; EDX ECX (PAR1) pointer to buffer PAR1
|
|
|
|
|
; ECX EBX (PAR2) vt file blocks to read PAR2
|
|
|
|
|
; ESI EDX (PAR3) pointer to path PAR3
|
|
|
|
|
; EDI ESI vt first 512 block to read
|
|
|
|
|
; EDI if 0 - read root
|
|
|
|
|
;
|
|
|
|
|
; output : eax = 0 - ok
|
|
|
|
|
; 3 - unknown FS
|
|
|
|
|
; 5 - file not found
|
|
|
|
|
; 6 - end of file
|
|
|
|
|
; 9 - fat table corrupted
|
|
|
|
|
; ebx = size of file/directory
|
|
|
|
|
;--------------------------------------------------------------------------
|
|
|
|
|
cmp [fat_type],0
|
|
|
|
|
jnz fat_ok_for_reading
|
|
|
|
|
xor ebx,ebx
|
|
|
|
|
mov eax,ERROR_UNKNOWN_FS
|
2006-03-21 12:46:13 +01:00
|
|
|
|
mov [hd1_status], ebx
|
2005-10-06 19:56:22 +02:00
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
fat_ok_for_reading:
|
|
|
|
|
; call reserve_hd1
|
|
|
|
|
|
|
|
|
|
pushad
|
|
|
|
|
|
|
|
|
|
mov ebx,edx
|
|
|
|
|
call get_cluster_of_a_path
|
|
|
|
|
jc file_to_read_not_found
|
|
|
|
|
|
|
|
|
|
test edi,edi ; read rootdir
|
|
|
|
|
jne no_read_root
|
|
|
|
|
|
|
|
|
|
xor eax,eax
|
|
|
|
|
call get_dir_size ; return rootdir size
|
|
|
|
|
mov [file_size],eax
|
|
|
|
|
mov eax,[ROOT_CLUSTER]
|
|
|
|
|
jmp file_read_start
|
|
|
|
|
|
|
|
|
|
no_read_root:
|
|
|
|
|
mov ebx,PUSHAD_EAX ; file name
|
|
|
|
|
call analyze_directory
|
|
|
|
|
jc file_to_read_not_found
|
|
|
|
|
|
|
|
|
|
mov eax,[ebx+28] ; file size
|
|
|
|
|
test byte [ebx+11],0x10 ; is it directory?
|
|
|
|
|
jz read_set_size ; no
|
|
|
|
|
|
|
|
|
|
mov eax,[ebx+20-2] ; FAT entry
|
|
|
|
|
mov ax,[ebx+26]
|
|
|
|
|
and eax,[fatMASK]
|
|
|
|
|
call get_dir_size
|
|
|
|
|
|
|
|
|
|
read_set_size:
|
|
|
|
|
mov [file_size],eax
|
|
|
|
|
|
|
|
|
|
mov eax,[ebx+20-2] ; FAT entry
|
|
|
|
|
mov ax,[ebx+26]
|
|
|
|
|
and eax,[fatMASK]
|
|
|
|
|
|
|
|
|
|
file_read_start:
|
|
|
|
|
mov ebx,PUSHAD_ECX ; pointer to buffer
|
|
|
|
|
mov edx,PUSHAD_EBX ; file blocks to read
|
|
|
|
|
mov esi,PUSHAD_ESI ; first 512 block to read
|
|
|
|
|
|
|
|
|
|
file_read_new_cluster:
|
|
|
|
|
call get_data_cluster
|
|
|
|
|
jc file_read_eof ; end of file or cluster out of range
|
|
|
|
|
|
|
|
|
|
test edx,edx ; is all read?
|
|
|
|
|
je file_read_OK ; yes
|
|
|
|
|
|
|
|
|
|
call get_FAT ; get next cluster
|
|
|
|
|
cmp eax,[fatRESERVED] ; end of file
|
|
|
|
|
jnb file_read_eof
|
|
|
|
|
cmp eax,2 ; incorrect fat chain
|
|
|
|
|
jnb file_read_new_cluster
|
|
|
|
|
|
|
|
|
|
popad
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
mov ebx,[file_size]
|
|
|
|
|
mov eax,ERROR_FAT_TABLE
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
file_read_eof:
|
|
|
|
|
popad
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
mov ebx,[file_size]
|
|
|
|
|
mov eax,ERROR_END_OF_FILE
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
file_read_OK:
|
|
|
|
|
popad
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
mov ebx,[file_size]
|
|
|
|
|
xor eax,eax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
file_to_read_not_found:
|
|
|
|
|
popad
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
xor ebx,ebx
|
|
|
|
|
mov eax,ERROR_FILE_NOT_FOUND
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_dir_size:
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
; input : eax = first cluster (0=rootdir)
|
|
|
|
|
; output : eax = directory size in bytes
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
push edx
|
|
|
|
|
xor edx,edx ; count of directory clusters
|
|
|
|
|
test eax,eax
|
|
|
|
|
jnz dir_size_next
|
|
|
|
|
|
|
|
|
|
mov eax,[ROOT_SECTORS]
|
|
|
|
|
shl eax,9 ; fat16 rootdir size in bytes
|
|
|
|
|
cmp [fat_type],16
|
|
|
|
|
je dir_size_ret
|
|
|
|
|
mov eax,[ROOT_CLUSTER]
|
|
|
|
|
|
|
|
|
|
dir_size_next:
|
|
|
|
|
cmp eax,2 ; incorrect fat chain
|
|
|
|
|
jb dir_size_end
|
|
|
|
|
cmp eax,[fatRESERVED] ; end of directory
|
|
|
|
|
ja dir_size_end
|
|
|
|
|
call get_FAT ; get next cluster
|
|
|
|
|
inc edx
|
|
|
|
|
jmp dir_size_next
|
|
|
|
|
|
|
|
|
|
dir_size_end:
|
|
|
|
|
imul eax,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes
|
|
|
|
|
imul eax,edx
|
|
|
|
|
|
|
|
|
|
dir_size_ret:
|
|
|
|
|
pop edx
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
file_delete:
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
; input : eax = file/directory name
|
|
|
|
|
; edx = path
|
|
|
|
|
; edi = 1 - allow directory remove else don't remove directory
|
|
|
|
|
; output : eax = 0 - ok
|
|
|
|
|
; 3 - unknown FS
|
|
|
|
|
; 5 - file not found
|
|
|
|
|
; 10 - access denied
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
cmp [fat_type],0
|
|
|
|
|
jnz file_del_fat_ok
|
|
|
|
|
mov eax,ERROR_UNKNOWN_FS
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
file_del_fat_ok:
|
|
|
|
|
pushad
|
|
|
|
|
|
|
|
|
|
mov ebx,edx
|
|
|
|
|
call get_cluster_of_a_path
|
|
|
|
|
jc file_to_delete_not_found
|
|
|
|
|
|
|
|
|
|
mov ebx,PUSHAD_EAX ; file/directory name
|
|
|
|
|
call analyze_directory
|
|
|
|
|
jc file_to_delete_not_found
|
|
|
|
|
|
|
|
|
|
test byte [ebx+11],0x10 ; is it directory?
|
|
|
|
|
jz delete_notdir ; no. it's file
|
|
|
|
|
cmp edi,1 ; allow directory remove
|
|
|
|
|
jnz delete_no_access ; no
|
|
|
|
|
|
|
|
|
|
push eax ; save directory sector
|
|
|
|
|
mov eax,[ebx+20-2] ; first cluster of file
|
|
|
|
|
mov ax,[ebx+26] ; 0 length files start cluster = 0
|
|
|
|
|
and eax,[fatMASK]
|
|
|
|
|
xor ebp,ebp ; counter for directory deepnes
|
|
|
|
|
call clear_directory
|
|
|
|
|
pop eax
|
|
|
|
|
jc delete_no_access
|
|
|
|
|
|
|
|
|
|
push ebx ; save directory pointer in buffer
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_read ; read directory sector
|
|
|
|
|
pop ebx
|
|
|
|
|
|
|
|
|
|
delete_notdir:
|
|
|
|
|
call delete_entry_name
|
|
|
|
|
mov eax,ecx ; first cluster of file
|
|
|
|
|
call clear_cluster_chain
|
|
|
|
|
popad
|
|
|
|
|
xor eax,eax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
delete_no_access:
|
|
|
|
|
popad
|
|
|
|
|
mov eax,ERROR_ACCESS_DENIED
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
file_to_delete_not_found:
|
|
|
|
|
popad
|
|
|
|
|
mov eax,ERROR_FILE_NOT_FOUND
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
clear_cluster_chain:
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
; input : eax = first cluster
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
push eax ecx edx
|
|
|
|
|
xor ecx,ecx ; cluster count
|
|
|
|
|
mov [f_del],1 ; delete on
|
|
|
|
|
|
|
|
|
|
clean_new_chain:
|
|
|
|
|
cmp eax,[LAST_CLUSTER] ; end of file
|
|
|
|
|
ja delete_OK
|
|
|
|
|
cmp eax,2 ; unfinished fat chain or zero length file
|
|
|
|
|
jb delete_OK
|
|
|
|
|
cmp eax,[ROOT_CLUSTER] ; don't remove root cluster
|
|
|
|
|
jz delete_OK
|
|
|
|
|
|
|
|
|
|
xor edx,edx
|
|
|
|
|
call set_FAT ; clear fat entry
|
|
|
|
|
inc ecx ; update cluster count
|
|
|
|
|
mov eax,edx ; old cluster
|
|
|
|
|
jmp clean_new_chain
|
|
|
|
|
|
|
|
|
|
delete_OK:
|
|
|
|
|
call add_disk_free_space ; add clusters to free disk space
|
|
|
|
|
mov [f_del],0
|
|
|
|
|
pop edx ecx eax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
clear_directory:
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
; input : eax = directory cluster
|
|
|
|
|
; ebp = directory deepnes
|
|
|
|
|
; Note : use recursive call
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
pushad
|
|
|
|
|
inc ebp
|
|
|
|
|
cmp ebp,64 ; if over 63 directory deep
|
|
|
|
|
jnb clear_error ; something must be wrong
|
|
|
|
|
|
|
|
|
|
clear_new_cluster:
|
|
|
|
|
cmp eax,[LAST_CLUSTER]
|
|
|
|
|
ja clear_end
|
|
|
|
|
cmp eax,[ROOT_CLUSTER] ; don't remove root cluster
|
|
|
|
|
jz clear_end
|
|
|
|
|
mov esi,eax ; esi = current directory cluster
|
|
|
|
|
sub eax,2
|
|
|
|
|
jb clear_end
|
|
|
|
|
mov ecx,[SECTORS_PER_CLUSTER]
|
|
|
|
|
imul eax,ecx
|
|
|
|
|
add eax,[DATA_START]
|
|
|
|
|
|
|
|
|
|
clear_new_sector:
|
|
|
|
|
mov edi,eax ; edi = current directory sector
|
|
|
|
|
mov ebx,deltree_buffer
|
|
|
|
|
call hd_read
|
|
|
|
|
mov edx,512/32 ; count of dir entrys per sector = 16
|
|
|
|
|
|
|
|
|
|
clear_analyze:
|
|
|
|
|
mov al,[ebx+11] ; file attribute
|
|
|
|
|
and al,0xf
|
|
|
|
|
cmp al,0xf
|
|
|
|
|
je clear_long_filename
|
|
|
|
|
|
|
|
|
|
cmp byte [ebx],'.' ; parent or current directory
|
|
|
|
|
je clear_next_entry
|
|
|
|
|
cmp byte [ebx],0xe5 ; deleted
|
|
|
|
|
je clear_next_entry
|
|
|
|
|
cmp byte [ebx],0 ; empty
|
|
|
|
|
je clear_write_last
|
|
|
|
|
;je clear_next_entry
|
|
|
|
|
|
|
|
|
|
mov eax,[ebx+20-2] ; first cluster of entry
|
|
|
|
|
mov ax,[ebx+26]
|
|
|
|
|
and eax,[fatMASK]
|
|
|
|
|
|
|
|
|
|
test byte [ebx+11],0x10 ; is it directory?
|
|
|
|
|
jz clear_file ; no
|
|
|
|
|
|
|
|
|
|
push eax ebx
|
|
|
|
|
mov eax,edi
|
|
|
|
|
mov ebx,deltree_buffer ; save buffer over recursive call
|
|
|
|
|
call hd_write ; write directory sector to disk
|
|
|
|
|
pop ebx eax
|
|
|
|
|
|
|
|
|
|
call clear_directory ; recursive call !!!
|
|
|
|
|
jc clear_error ; exit if error found
|
|
|
|
|
|
|
|
|
|
push eax ebx
|
|
|
|
|
mov eax,edi
|
|
|
|
|
mov ebx,deltree_buffer
|
|
|
|
|
call hd_read ; read directory sector again
|
|
|
|
|
pop ebx eax
|
|
|
|
|
|
|
|
|
|
clear_file:
|
|
|
|
|
call clear_cluster_chain
|
|
|
|
|
|
|
|
|
|
clear_long_filename:
|
|
|
|
|
mov byte [ebx],0xe5
|
|
|
|
|
|
|
|
|
|
clear_next_entry:
|
|
|
|
|
add ebx,32 ; position of next dir entry
|
|
|
|
|
dec edx
|
|
|
|
|
jnz clear_analyze
|
|
|
|
|
|
|
|
|
|
mov eax,edi
|
|
|
|
|
mov ebx,deltree_buffer
|
|
|
|
|
call hd_write ; write directory sector to disk
|
|
|
|
|
|
|
|
|
|
inc eax ; next sector
|
|
|
|
|
dec ecx
|
|
|
|
|
jnz clear_new_sector
|
|
|
|
|
|
|
|
|
|
mov eax,esi
|
|
|
|
|
call get_FAT ; get next cluster
|
|
|
|
|
jmp clear_new_cluster ; clear it
|
|
|
|
|
|
|
|
|
|
clear_write_last:
|
|
|
|
|
mov eax,edi
|
|
|
|
|
mov ebx,deltree_buffer
|
|
|
|
|
call hd_write ; write directory sector to disk
|
|
|
|
|
|
|
|
|
|
clear_end:
|
|
|
|
|
popad
|
|
|
|
|
clc
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
clear_error:
|
|
|
|
|
popad
|
|
|
|
|
stc
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
delete_entry_name:
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
; input : eax = directory sector
|
|
|
|
|
; ebx = directory pointer in buffer
|
|
|
|
|
; longname_sec = 2 previous directory sectors
|
|
|
|
|
; output : ecx = first cluster
|
|
|
|
|
; change : eax,ebx,edx
|
|
|
|
|
;-----------------------------------------------------
|
|
|
|
|
mov byte [ebx],0xe5
|
|
|
|
|
mov ecx,[ebx+20-2] ; first cluster of file
|
|
|
|
|
mov cx,[ebx+26] ; 0 length files start cluster = 0
|
|
|
|
|
and ecx,[fatMASK]
|
|
|
|
|
|
|
|
|
|
delete_empty:
|
|
|
|
|
sub ebx,32
|
|
|
|
|
cmp ebx,buffer
|
|
|
|
|
jnb delete_test_long
|
|
|
|
|
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_write ; write directory sector back
|
|
|
|
|
xor eax,eax
|
|
|
|
|
xchg eax,[longname_sec2]
|
|
|
|
|
xchg eax,[longname_sec1]
|
|
|
|
|
test eax,eax ; is there previous directory sector?
|
|
|
|
|
jz delete_name_end ; no
|
|
|
|
|
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_read ; read previous sector
|
|
|
|
|
mov ebx,buffer+0x1e0 ; start from last entry
|
|
|
|
|
|
|
|
|
|
delete_test_long:
|
|
|
|
|
mov dh,[ebx+11] ; file attribute
|
|
|
|
|
and dh,0xf
|
|
|
|
|
cmp dh,0xf
|
|
|
|
|
jne delete_write_buffer
|
|
|
|
|
|
|
|
|
|
cmp byte [ebx],0x40 ; end of long dir entry?
|
|
|
|
|
mov byte [ebx],0xe5
|
|
|
|
|
jb delete_empty
|
|
|
|
|
|
|
|
|
|
delete_write_buffer:
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_write ; write directory sector back
|
|
|
|
|
|
|
|
|
|
delete_name_end:
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rename:
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
; input : eax = source directory name
|
|
|
|
|
; edx = source path
|
|
|
|
|
; ebx = dest directory name
|
|
|
|
|
; edi = dest path
|
|
|
|
|
; output : eax = 0 - ok
|
|
|
|
|
; 3 - unknown FS
|
|
|
|
|
; 5 - file not found
|
|
|
|
|
; 8 - disk full
|
|
|
|
|
; 10 - access denied
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
cmp [fat_type],0
|
|
|
|
|
jnz fat_ok_for_rename
|
|
|
|
|
mov eax,ERROR_UNKNOWN_FS
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
fat_ok_for_rename:
|
|
|
|
|
; call reserve_hd1
|
|
|
|
|
|
|
|
|
|
pushad
|
|
|
|
|
|
|
|
|
|
mov ebx,edx ; source path
|
|
|
|
|
call get_cluster_of_a_path
|
|
|
|
|
jc rename_entry_not_found
|
|
|
|
|
|
|
|
|
|
mov ebx,PUSHAD_EAX ; source directory name
|
|
|
|
|
call analyze_directory
|
|
|
|
|
jc rename_entry_not_found
|
|
|
|
|
|
|
|
|
|
mov [sector_tmp],eax ; save source sector
|
|
|
|
|
mov [entry_pos],ebx
|
|
|
|
|
mov esi,ebx
|
|
|
|
|
mov edi,dir_entry
|
|
|
|
|
mov ecx,32/4
|
|
|
|
|
cld
|
|
|
|
|
rep movsd ; save entry
|
|
|
|
|
|
|
|
|
|
mov ebx,PUSHAD_EDI ; dest path
|
|
|
|
|
call get_cluster_of_a_path
|
|
|
|
|
jc rename_entry_not_found
|
|
|
|
|
|
|
|
|
|
mov edx,eax ; save dest directory cluster
|
|
|
|
|
mov ebx,PUSHAD_EBX ; dest directory name
|
|
|
|
|
push [longname_sec1]
|
|
|
|
|
push [longname_sec2]
|
|
|
|
|
call analyze_directory ; check if entry already exist
|
|
|
|
|
pop [longname_sec2]
|
|
|
|
|
pop [longname_sec1]
|
|
|
|
|
jnc rename_entry_already_exist
|
|
|
|
|
|
|
|
|
|
mov eax,edx
|
|
|
|
|
call analyze_directory_to_write
|
|
|
|
|
jc rename_disk_full
|
|
|
|
|
|
|
|
|
|
mov esi,dir_entry
|
|
|
|
|
mov edi,ebx
|
|
|
|
|
mov ecx,32/4
|
|
|
|
|
cld
|
|
|
|
|
rep movsd ; copy entry
|
|
|
|
|
mov esi,PUSHAD_EBX ; dest directory name
|
|
|
|
|
mov edi,ebx
|
|
|
|
|
mov ecx,11
|
|
|
|
|
rep movsb ; copy name
|
|
|
|
|
|
|
|
|
|
mov ebx,buffer ; save the directory name,length,cluster
|
|
|
|
|
call hd_write
|
|
|
|
|
|
|
|
|
|
test byte [dir_entry+11],0x10 ; is it directory?
|
|
|
|
|
jz rename_not_dir ; no
|
|
|
|
|
mov eax,[dir_entry+20-2] ; FAT entry
|
|
|
|
|
mov ax,[dir_entry+26]
|
|
|
|
|
and eax,[fatMASK]
|
|
|
|
|
call change_2dot_cluster
|
|
|
|
|
|
|
|
|
|
rename_not_dir:
|
|
|
|
|
mov eax,[sector_tmp]
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_read ; read source directory sector
|
|
|
|
|
|
|
|
|
|
mov ebx,[entry_pos]
|
|
|
|
|
call delete_entry_name
|
|
|
|
|
|
|
|
|
|
popad
|
|
|
|
|
call update_disk ; write all of cache and fat to hd
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
xor eax,eax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
rename_entry_not_found:
|
|
|
|
|
popad
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
mov eax,ERROR_FILE_NOT_FOUND
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
rename_entry_already_exist:
|
|
|
|
|
popad
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
mov eax,ERROR_ACCESS_DENIED
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
rename_disk_full:
|
|
|
|
|
popad
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
mov eax,ERROR_DISK_FULL
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
change_2dot_cluster:
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
; input : eax = directory cluster
|
|
|
|
|
; edx = value to save
|
|
|
|
|
; change : eax,ebx,edx
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
cmp eax,[LAST_CLUSTER]
|
|
|
|
|
ja not_2dot ; too big cluster number, something is wrong
|
|
|
|
|
sub eax,2
|
|
|
|
|
jb not_2dot
|
|
|
|
|
|
|
|
|
|
imul eax,[SECTORS_PER_CLUSTER]
|
|
|
|
|
add eax,[DATA_START]
|
|
|
|
|
mov ebx,buffer
|
|
|
|
|
call hd_read
|
|
|
|
|
|
|
|
|
|
cmp dword [ebx+32],'.. '
|
|
|
|
|
jnz not_2dot
|
|
|
|
|
|
|
|
|
|
cmp edx,[ROOT_CLUSTER] ; is rootdir cluster?
|
|
|
|
|
jne not_2dot_root
|
|
|
|
|
xor edx,edx ; yes. set it zero
|
|
|
|
|
|
|
|
|
|
not_2dot_root:
|
|
|
|
|
mov [ebx+32+26],dx ; 16 bits low of cluster
|
|
|
|
|
shr edx,16
|
|
|
|
|
mov [ebx+32+20],dx ; 16 bits high of cluster (=0 fat16)
|
|
|
|
|
call hd_write
|
|
|
|
|
|
|
|
|
|
not_2dot:
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_filesize:
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
; input : eax = file name
|
|
|
|
|
; edx = path
|
|
|
|
|
; edi = if 0 - read rootdir else normal dir/file size
|
|
|
|
|
; output : eax = 0 - ok
|
|
|
|
|
; 3 - unknown FS
|
|
|
|
|
; 5 - file not found
|
|
|
|
|
; ebx = file size
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
cmp [fat_type],0
|
|
|
|
|
jnz get_filesize_fat_ok
|
|
|
|
|
xor ebx,ebx
|
|
|
|
|
mov eax,ERROR_UNKNOWN_FS
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
get_filesize_fat_ok:
|
|
|
|
|
; call reserve_hd1
|
|
|
|
|
|
|
|
|
|
pushad
|
|
|
|
|
xor eax,eax
|
|
|
|
|
test edi,edi ; is read rootdir?
|
|
|
|
|
je get_filesize_dirsize ; yes
|
|
|
|
|
|
|
|
|
|
get_filesize_no_root:
|
|
|
|
|
mov ebx,edx
|
|
|
|
|
call get_cluster_of_a_path
|
|
|
|
|
jc get_filesize_not_found
|
|
|
|
|
|
|
|
|
|
mov ebx,PUSHAD_EAX ; file name
|
|
|
|
|
call analyze_directory
|
|
|
|
|
jc get_filesize_not_found
|
|
|
|
|
|
|
|
|
|
mov eax,[ebx+28] ; file size
|
|
|
|
|
test byte [ebx+11],0x10 ; is it directory?
|
|
|
|
|
jz get_filesize_set_size ; no
|
|
|
|
|
|
|
|
|
|
mov eax,[ebx+20-2] ; FAT entry
|
|
|
|
|
mov ax,[ebx+26]
|
|
|
|
|
and eax,[fatMASK]
|
|
|
|
|
|
|
|
|
|
get_filesize_dirsize:
|
|
|
|
|
call get_dir_size
|
|
|
|
|
|
|
|
|
|
get_filesize_set_size:
|
|
|
|
|
mov PUSHAD_EBX,eax
|
|
|
|
|
popad
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
xor eax,eax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
get_filesize_not_found:
|
|
|
|
|
popad
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
xor ebx,ebx
|
|
|
|
|
mov eax,ERROR_FILE_NOT_FOUND
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_fileattr:
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
; input : eax = file name
|
|
|
|
|
; edx = path
|
|
|
|
|
; output : eax = 0 - ok
|
|
|
|
|
; 3 - unknown FS
|
|
|
|
|
; 5 - file not found
|
|
|
|
|
; ebx = file attribute
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
cmp [fat_type],0
|
|
|
|
|
jnz get_fileattr_fat_ok
|
|
|
|
|
xor ebx,ebx
|
|
|
|
|
mov eax,ERROR_UNKNOWN_FS
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
get_fileattr_fat_ok:
|
|
|
|
|
; call reserve_hd1
|
|
|
|
|
|
|
|
|
|
pushad
|
|
|
|
|
mov ebx,edx
|
|
|
|
|
call get_cluster_of_a_path
|
|
|
|
|
jc get_fileattr_not_found
|
|
|
|
|
|
|
|
|
|
mov ebx,PUSHAD_EAX ; file name
|
|
|
|
|
call analyze_directory
|
|
|
|
|
jc get_fileattr_not_found
|
|
|
|
|
|
|
|
|
|
movzx eax,byte [ebx+11] ; file attribute
|
|
|
|
|
mov PUSHAD_EBX,eax
|
|
|
|
|
popad
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
xor eax,eax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
get_fileattr_not_found:
|
|
|
|
|
popad
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
xor ebx,ebx
|
|
|
|
|
mov eax,ERROR_FILE_NOT_FOUND
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_filedate:
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
; input : eax = file name
|
|
|
|
|
; edx = path
|
|
|
|
|
; output : eax = 0 - ok
|
|
|
|
|
; 3 - unknown FS
|
|
|
|
|
; 5 - file not found
|
|
|
|
|
; ebx = file date/time
|
|
|
|
|
; bits 31..25 = year-1980
|
|
|
|
|
; bits 24..21 = month
|
|
|
|
|
; bits 20..16 = day
|
|
|
|
|
; bits 15..11 = hour
|
|
|
|
|
; bits 10..5 = minute
|
|
|
|
|
; bits 4..0 = second/2
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
cmp [fat_type],0
|
|
|
|
|
jnz get_filedate_fat_ok
|
|
|
|
|
xor ebx,ebx
|
|
|
|
|
mov eax,ERROR_UNKNOWN_FS
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
get_filedate_fat_ok:
|
|
|
|
|
; call reserve_hd1
|
|
|
|
|
|
|
|
|
|
pushad
|
|
|
|
|
mov ebx,edx
|
|
|
|
|
call get_cluster_of_a_path
|
|
|
|
|
jc get_filedate_not_found
|
|
|
|
|
|
|
|
|
|
mov ebx,PUSHAD_EAX ; file name
|
|
|
|
|
call analyze_directory
|
|
|
|
|
jc get_filedate_not_found
|
|
|
|
|
|
|
|
|
|
mov eax,[ebx+22] ; file date/time
|
|
|
|
|
mov PUSHAD_EBX,eax
|
|
|
|
|
popad
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
xor eax,eax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
get_filedate_not_found:
|
|
|
|
|
popad
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
xor ebx,ebx
|
|
|
|
|
mov eax,ERROR_FILE_NOT_FOUND
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_hd_info:
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
; output : eax = 0 - ok
|
|
|
|
|
; 3 - unknown FS
|
|
|
|
|
; edx = cluster size in bytes
|
|
|
|
|
; ebx = total clusters on disk
|
|
|
|
|
; ecx = free clusters on disk
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
cmp [fat_type],0
|
|
|
|
|
jnz info_fat_ok
|
|
|
|
|
xor edx,edx
|
|
|
|
|
xor ebx,ebx
|
|
|
|
|
xor ecx,ecx
|
|
|
|
|
mov eax,ERROR_UNKNOWN_FS
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
info_fat_ok:
|
|
|
|
|
; call reserve_hd1
|
|
|
|
|
|
|
|
|
|
xor ecx,ecx ; count of free clusters
|
|
|
|
|
mov eax,2
|
|
|
|
|
mov ebx,[LAST_CLUSTER]
|
|
|
|
|
|
|
|
|
|
info_cluster:
|
|
|
|
|
push eax
|
|
|
|
|
call get_FAT ; get cluster info
|
|
|
|
|
test eax,eax ; is it free?
|
|
|
|
|
jnz info_used ; no
|
|
|
|
|
inc ecx
|
|
|
|
|
|
|
|
|
|
info_used:
|
|
|
|
|
pop eax
|
|
|
|
|
inc eax
|
|
|
|
|
cmp eax,ebx ; is above last cluster?
|
|
|
|
|
jbe info_cluster ; no. test next cluster
|
|
|
|
|
|
|
|
|
|
dec ebx ; cluster count
|
|
|
|
|
imul edx,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes
|
|
|
|
|
mov [hd1_status],0
|
|
|
|
|
xor eax,eax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
update_disk:
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
; write changed fat and cache to disk
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
cmp [fat_change],0 ; is fat changed?
|
|
|
|
|
je upd_no_change
|
|
|
|
|
|
|
|
|
|
call write_fat_sector
|
|
|
|
|
|
|
|
|
|
upd_no_change:
|
|
|
|
|
|
|
|
|
|
call write_cache
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
call wait_for_hd_idle
|
|
|
|
|
push eax edx
|
|
|
|
|
|
|
|
|
|
cli
|
|
|
|
|
xor eax,eax
|
|
|
|
|
mov edx,[hdbase]
|
|
|
|
|
inc edx
|
|
|
|
|
out dx,al ; ATAFeatures <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
|
|
|
|
|
inc edx
|
|
|
|
|
inc eax
|
|
|
|
|
out dx,al ; ATASectorCount <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
inc edx
|
|
|
|
|
mov eax,[esp+4]
|
|
|
|
|
out dx,al ; ATASectorNumber <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
shr eax,8
|
|
|
|
|
inc edx
|
|
|
|
|
out dx,al ; ATACylinder <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
|
|
|
|
shr eax,8
|
|
|
|
|
inc edx
|
|
|
|
|
out dx,al ; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
|
|
|
|
shr eax,8
|
|
|
|
|
inc edx
|
|
|
|
|
and al,1+2+4+8
|
|
|
|
|
add al,byte [hdid]
|
|
|
|
|
add al,128+64+32
|
|
|
|
|
out dx,al ; <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
inc edx
|
|
|
|
|
mov al,20h
|
|
|
|
|
out dx,al ; ATACommand <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
; blok_read_2:
|
|
|
|
|
pop edi esi ecx
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
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 wait_for_hd_idle
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
danger:
|
|
|
|
|
does_not_need_writing:
|
|
|
|
|
|
|
|
|
|
add esi,8
|
|
|
|
|
inc edi
|
|
|
|
|
dec ecx
|
|
|
|
|
jnz write_cache_more
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
jmp search_again ; and start again
|
|
|
|
|
|
|
|
|
|
found_slot:
|
|
|
|
|
|
|
|
|
|
mov [cache_search_start],edi
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
endg
|
|
|
|
|
|
|
|
|
|
hd_timeout_error:
|
|
|
|
|
|
|
|
|
|
call clear_hd_cache
|
|
|
|
|
call clear_application_table_status
|
|
|
|
|
mov esi,hd_timeout_str
|
|
|
|
|
call sys_msg_board_str
|
|
|
|
|
jmp $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hd_read_error:
|
|
|
|
|
|
|
|
|
|
call clear_hd_cache
|
|
|
|
|
call clear_application_table_status
|
|
|
|
|
mov esi,hd_read_str
|
|
|
|
|
call sys_msg_board_str
|
|
|
|
|
jmp $
|
|
|
|
|
|
|
|
|
|
hd_write_error:
|
|
|
|
|
|
|
|
|
|
call clear_hd_cache
|
|
|
|
|
call clear_application_table_status
|
|
|
|
|
mov esi,hd_write_str
|
|
|
|
|
call sys_msg_board_str
|
|
|
|
|
jmp $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wait_for_hd_idle:
|
|
|
|
|
|
|
|
|
|
push eax edx
|
|
|
|
|
|
|
|
|
|
call save_hd_wait_timeout
|
|
|
|
|
|
|
|
|
|
mov edx,[hdbase]
|
|
|
|
|
add edx,0x7
|
|
|
|
|
|
|
|
|
|
wfhil1:
|
|
|
|
|
|
|
|
|
|
call check_hd_wait_timeout
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
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:
|
|
|
|
|
;-----------------------------------------------------------------
|
|
|
|
|
;
|
|
|
|
|
; Converting old reading function for hd-application start.
|
|
|
|
|
;
|
|
|
|
|
; IN:
|
|
|
|
|
;
|
|
|
|
|
; eax - pointer to file (0 = read only first sector of drive: eg 'label')
|
|
|
|
|
; ebx - file lenght
|
|
|
|
|
; ecx - start 512 byte block number
|
|
|
|
|
; edx - number of blocks to read
|
|
|
|
|
; esi - pointer to return/work area (atleast 20 000 bytes)
|
|
|
|
|
;
|
|
|
|
|
; For new read function
|
|
|
|
|
;
|
|
|
|
|
; EAX (PAR0) pointer to file-name
|
|
|
|
|
; ECX (PAR1) pointer to buffer
|
|
|
|
|
; EBX (PAR2) vt file blocks to read
|
|
|
|
|
; EDX (PAR3) pointer to path
|
|
|
|
|
; ESI vt first 512 block to read
|
|
|
|
|
; EDI if 0 - return root
|
|
|
|
|
;--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
push ecx esi edi
|
|
|
|
|
mov esi,eax
|
|
|
|
|
mov edi,startpath
|
|
|
|
|
mov ecx,250
|
|
|
|
|
cld
|
|
|
|
|
rep movsb
|
|
|
|
|
pop edi esi ecx
|
|
|
|
|
|
|
|
|
|
mov eax,startpath
|
|
|
|
|
mov [eax+ebx-12],byte 0
|
|
|
|
|
|
|
|
|
|
push eax ebx ecx edx esi
|
|
|
|
|
|
|
|
|
|
pop ecx ; pointer to buffer
|
|
|
|
|
add ecx,1024
|
|
|
|
|
pop ebx ; number of blocks to read
|
|
|
|
|
pop esi ; first block to read
|
|
|
|
|
dec esi
|
|
|
|
|
pop eax ; file length
|
|
|
|
|
pop edx ; pointer to path
|
|
|
|
|
|
|
|
|
|
mov edi,12
|
|
|
|
|
lea eax,[eax+edx-12+1]
|
|
|
|
|
call file_read
|
|
|
|
|
|
|
|
|
|
ret
|
|
|
|
|
|