/kernel/trunk/blkdev/rd.inc |
---|
3,6 → 3,7 |
;; RAMDISK functions ;; |
;; (C) 2004 Ville Turjanmaa, License: GPL ;; |
;; Addings by M.Lisovin ;; |
;; LFN support by diamond ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; calculate fat chain |
379,7 → 380,6 |
; find an empty spot for filename in the root dir |
l20ds: |
dec edx |
test edx,edx |
jz frnoreadds |
l21ds: |
cmp [edi],byte 0xE5 |
1076,4 → 1076,522 |
pop ecx edi esi |
ret |
iglobal |
label fat_legal_chars byte |
; 0 = not allowed |
; 1 = allowed only in long names |
; 3 = allowed |
times 32 db 0 |
; ! " # $ % & ' ( ) * + , - . / |
db 1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0 |
; 0 1 2 3 4 5 6 7 8 9 : ; < = > ? |
db 3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0 |
; @ A B C D E F G H I J K L M N O |
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 |
; P Q R S T U V W X Y Z [ \ ] ^ _ |
db 3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3 |
; ` a b c d e f g h i j k l m n o |
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 |
; p q r s t u v w x y z { | } ~ |
db 3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0 |
endg |
fat_name_is_legal: |
; in: esi->(long) name |
; out: CF set <=> legal |
; destroys eax |
push esi |
xor eax, eax |
@@: |
lodsb |
test al, al |
jz .done |
cmp al, 80h |
jae .big |
test [fat_legal_chars+eax], 1 |
jnz @b |
.err: |
pop esi |
clc |
ret |
.big: |
; 0x80-0xAF, 0xE0-0xEF |
cmp al, 0xB0 |
jb @b |
cmp al, 0xE0 |
jb .err |
cmp al, 0xF0 |
jb @b |
jmp .err |
.done: |
sub esi, [esp] |
cmp esi, 257 |
pop esi |
ret |
fat_next_short_name: |
; in: edi->8+3 name |
; out: name corrected |
; CF=1 <=> error |
pushad |
mov ecx, 8 |
mov al, '~' |
std |
push edi |
add edi, 7 |
repnz scasb |
pop edi |
cld |
jz .tilde |
; tilde is not found, insert "~1" at end |
add edi, 6 |
cmp word [edi], ' ' |
jnz .insert_tilde |
@@: dec edi |
cmp byte [edi], ' ' |
jz @b |
inc edi |
.insert_tilde: |
mov word [edi], '~1' |
popad |
; clc ; CF already cleared |
ret |
.tilde: |
push edi |
add edi, 7 |
xor ecx, ecx |
@@: |
; after tilde may be only digits and trailing spaces |
cmp byte [edi], '~' |
jz .break |
cmp byte [edi], ' ' |
jz .space |
cmp byte [edi], '9' |
jnz .found |
dec edi |
jmp @b |
.space: |
dec edi |
inc ecx |
jmp @b |
.found: |
inc byte [edi] |
.succ: |
pop edi |
popad |
clc |
ret |
.break: |
jecxz .noplace |
inc edi |
mov al, '1' |
@@: |
xchg al, [edi] |
inc edi |
cmp al, ' ' |
mov al, '0' |
jnz @b |
jmp .succ |
.noplace: |
dec edi |
cmp edi, [esp] |
jz .err |
add dword [esp], 8 |
mov word [edi], '~1' |
inc edi |
inc edi |
@@: |
mov byte [edi], '0' |
inc edi |
cmp edi, [esp] |
jb @b |
pop edi |
popad |
;clc ; automatically |
ret |
.err: |
pop edi |
popad |
stc |
ret |
fat_gen_short_name: |
; in: esi->long name |
; edi->buffer (8+3=11 chars) |
; out: buffer filled |
pushad |
mov eax, ' ' |
push edi |
stosd |
stosd |
stosd |
pop edi |
xor eax, eax |
push 8 |
pop ebx |
lea ecx, [edi+8] |
.loop: |
lodsb |
test al, al |
jz .done |
call char_toupper |
cmp al, ' ' |
jz .space |
cmp al, 80h |
ja .big |
test [fat_legal_chars+eax], 2 |
jnz .symbol |
.inv_symbol: |
mov al, '_' |
or bh, 1 |
.symbol: |
cmp al, '.' |
jz .dot |
.normal_symbol: |
dec bl |
jns .store |
mov bl, 0 |
.space: |
or bh, 1 |
jmp .loop |
.store: |
stosb |
jmp .loop |
.big: |
cmp al, 0xB0 |
jb .normal_symbol |
cmp al, 0xE0 |
jb .inv_symbol |
cmp al, 0xF0 |
jb .normal_symbol |
jmp .inv_symbol |
.dot: |
test bh, 2 |
jz .firstdot |
pop ebx |
add ebx, edi |
sub ebx, ecx |
push ebx |
cmp edi, ecx |
jbe .skip |
@@: |
dec edi |
mov al, ' ' |
xchg al, [edi] |
dec ebx |
mov [ebx], al |
cmp edi, ecx |
ja @b |
.skip: |
mov bh, 3 |
jmp @f |
.firstdot: |
cmp bl, 8 |
jz .space |
push edi |
or bh, 2 |
@@: |
mov edi, ecx |
mov bl, 3 |
jmp .loop |
.done: |
test bh, 2 |
jz @f |
pop edi |
@@: |
lea edi, [ecx-8] |
test bh, 1 |
jz @f |
call fat_next_short_name |
@@: |
popad |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskRewrite - LFN variant for writing sys floppy |
; |
; esi points to filename |
; ebx ignored (reserved) |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = number of written bytes |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
@@: |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
fs_RamdiskRewrite: |
cmp byte [esi], 0 |
jz @b |
; ramdisk doesn't support folders |
push esi |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
pop esi |
.err5: |
mov eax, 5 ; file not found |
xor ebx, ebx |
ret |
@@: |
pop esi |
; check existence |
push edi |
call rd_find_lfn |
jc .notfound |
; found, delete FAT chain |
push edi |
xor eax, eax |
mov dword [edi+28], eax ; zero size |
xchg ax, word [edi+26] ; start cluster |
test eax, eax |
jz .done1 |
@@: |
cmp eax, 0xFF8 |
jae .done1 |
lea edi, [0x280000 + eax*2] ; position in FAT |
xor eax, eax |
xchg ax, [edi] |
jmp @b |
.done1: |
pop edi |
call get_time_for_file |
mov [edi+22], ax |
call get_date_for_file |
mov [edi+24], ax |
mov [edi+18], ax |
or byte [edi+11], 20h ; set 'archive' attribute |
jmp .doit |
.notfound: |
; file is not found; generate short name |
call fat_name_is_legal |
jc @f |
pop edi |
jmp .err5 |
@@: |
sub esp, 12 |
mov edi, esp |
call fat_gen_short_name |
.test_short_name_loop: |
push esi ecx |
mov esi, 0x100000+512*19 |
.test_short_name_entry: |
cmp byte [esi+11], 0xF |
jz .test_short_name_cont |
mov ecx, 11 |
push esi edi |
repz cmpsb |
pop edi esi |
jz .short_name_found |
.test_short_name_cont: |
add esi, 20h |
cmp esi, 0x100000+512*33 |
jb .test_short_name_entry |
pop ecx esi |
jmp .found |
.short_name_found: |
call fat_next_short_name |
pop ecx esi |
jnc .test_short_name_loop |
.disk_full: |
add esp, 12 |
pop edi |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.found: |
; now find space in directory |
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' |
mov al, '~' |
push ecx edi |
mov ecx, 8 |
repnz scasb |
push 1 |
pop eax ; 1 entry |
jnz .notilde |
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total |
xor eax, eax |
@@: |
cmp byte [esi], 0 |
jz @f |
inc esi |
inc eax |
jmp @b |
@@: |
sub esi, eax |
add eax, 12+13 |
mov ecx, 13 |
push edx |
cdq |
div ecx |
pop edx |
.notilde: |
; find <eax> successive entries in directory |
xor ecx, ecx |
mov edi, 0x100000+512*19 |
.scan_dir: |
cmp byte [edi], 0 |
jz .free |
cmp byte [edi], 0xE5 |
jz .free |
xor ecx, ecx |
.scan_cont: |
add edi, 0x20 |
cmp edi, 0x100000+512*33 |
jb .scan_dir |
pop edi ecx |
jmp .disk_full |
.free: |
inc ecx |
cmp ecx, eax |
jb .scan_cont |
; found! |
; calculate name checksum |
push esi ecx |
mov esi, [esp+8] |
mov ecx, 11 |
xor eax, eax |
@@: |
ror al, 1 |
add al, [esi] |
inc esi |
loop @b |
pop ecx esi |
; edi points to last entry in free chunk |
dec ecx |
jz .nolfn |
push esi |
push edi |
.writelfn: |
sub edi, 20h |
push ecx eax |
mov eax, [esp+8] |
sub eax, edi |
shr eax, 5 |
cmp ecx, 1 |
jnz @f |
or al, 40h |
@@: |
stosb |
mov cl, 5 |
call .read_symbols |
mov ax, 0xF |
stosw |
pop eax |
stosb |
push eax |
mov cl, 6 |
call .read_symbols |
xor eax, eax |
stosw |
mov cl, 2 |
call .read_symbols |
pop eax ecx |
sub edi, 0x20 |
loop .writelfn |
pop edi |
pop esi |
.nolfn: |
xchg esi, [esp] |
mov ecx, 11 |
rep movsb |
mov word [edi], 20h ; attributes |
sub edi, 11 |
pop esi ecx |
add esp, 12 |
mov byte [edi+13], 0 ; tenths of a second at file creation time |
call get_time_for_file |
mov [edi+14], ax ; creation time |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+16], ax ; creation date |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
and word [edi+20], 0 ; high word of cluster |
and word [edi+26], 0 ; low word of cluster - to be filled |
and dword [edi+28], 0 ; file size - to be filled |
.doit: |
push ecx edx |
push ecx |
push edi |
add edi, 26 ; edi points to low word of cluster |
push edi |
jecxz .done |
mov ecx, 2849 |
mov edi, 0x280000 |
.write_loop: |
; allocate new cluster |
xor eax, eax |
repnz scasw |
jnz .disk_full2 |
dec edi |
dec edi |
lea eax, [edi-0x280000] |
shr eax, 1 ; eax = cluster |
mov word [edi], 0xFFF ; mark as last cluster |
xchg edi, [esp] |
stosw |
pop edi |
push edi |
inc ecx |
; write data |
shl eax, 9 |
add eax, 0x100000+31*512 |
mov ebx, edx |
xchg eax, ebx |
push ecx |
mov ecx, 512 |
cmp dword [esp+12], ecx |
jae @f |
mov ecx, [esp+12] |
@@: |
call memmove |
add edx, ecx |
sub [esp+12], ecx |
pop ecx |
jnz .write_loop |
.done: |
mov ebx, edx |
pop edi edi ecx edx ecx |
sub ebx, edx |
mov [edi+28], ebx |
pop edi |
xor eax, eax |
ret |
.disk_full2: |
mov ebx, edx |
pop edi edi ecx edx ecx |
sub ebx, edx |
mov [edi+28], ebx |
pop edi |
push ERROR_DISK_FULL |
pop eax |
ret |
.read_symbol: |
or ax, -1 |
test esi, esi |
jz .retFFFF |
lodsb |
test al, al |
jnz ansi2uni_char |
xor eax, eax |
xor esi, esi |
.retFFFF: |
ret |
.read_symbols: |
call .read_symbol |
stosw |
loop .read_symbols |
ret |
; \end{diamond} |
/kernel/trunk/docs/sysfuncr.txt |
---|
2770,7 → 2770,7 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
¬¥ç ¨ï: |
* â äãªæ¨ï ãáâ ५ ; äãªæ¨ï 58 ¯®§¢®«ï¥â ¢ë¯®«ïâì |
* â äãªæ¨ï ãáâ ५ ; äãªæ¨ï 70 ¯®§¢®«ï¥â ¢ë¯®«ïâì |
⥠¦¥ ¤¥©á⢨ï á à áè¨à¥ë¬¨ ¢®§¬®¦®áâﬨ. |
* ï äãªæ¨ï ¯à¥¤¯®« £ ¥â, çâ® ¢® ¢à¥¬ï ¥ñ ¢ë§®¢ ®¤¨¬ |
¯à¨«®¦¥¨¥¬ ¨ª ª®¥ ¤à㣮¥ ¯à¨«®¦¥¨¥ ¥ à ¡®â ¥â |
2930,6 → 2930,8 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* â äãªæ¨ï ãáâ ५ , ¨á¯®«ì§ã©â¥ ¯®¤äãªæ¨î 2 äãªæ¨¨ 70. |
====================================================================== |
=========== ãªæ¨ï 58, ¯®¤äãªæ¨ï 2 - 㤠«¨âì ä ©«/¯ ¯ªã. =========== |
3085,9 → 3087,6 |
¯®¤äãªæ¨¥© 11 äãªæ¨¨ 21. § âì íâ® ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¥© 11 äãªæ¨¨ 26. |
* LBA-ç⥨¥ ¤¨áª¥âë ¥ ¯®¤¤¥à¦¨¢ ¥âáï. |
* ¡à 饨¥ ª ¥áãé¥áâ¢ãî饬㠦ñá⪮¬ã ¤¨áªã ¬¥à⢮ ¢¥è ¥â ¯®â®ª. |
§ âì, áãé¥áâ¢ã¥â «¨ ¤¨áª, ¬®¦® ¨§ áâàãªâãàë, ¢®§¢à é ¥¬®© |
¯®¤äãªæ¨¥© 11 äãªæ¨¨ 18. |
* ãªæ¨ï áç¨âë¢ ¥â ¤ ë¥ ä¨§¨ç¥áª®£® ¦ñá⪮£® ¤¨áª ; |
¥á«¨ ¯® ª ª¨¬-â® ¯à¨ç¨ ¬ ã¦ë ¤ ë¥ ª®ªà¥â®£® à §¤¥« , |
¯à¨¤ñâáï ®¯à¥¤¥«ïâì ç «ìë© á¥ªâ®à í⮣® à §¤¥« |
4055,8 → 4054,7 |
x - ®¬¥à à §¤¥« ¢ë¡à ®¬ ¢¨ç¥áâ¥à¥, ¨§¬¥ï¥âáï ®â 1 ¤® 255 |
( ª ¦¤®¬ ¨§ ¢¨ç¥áâ¥à®¢ 㬥à æ¨ï ç¨ ¥âáï á 1) |
ਬ¥àë: |
* '/RAMDISK/FIRST/KERNEL.ASM',0 |
'/rd/1/kernel.asm',0 |
* '/rd/1/kernel.asm',0 |
* '/HD0/1/kernel.asm',0 |
* '/hd0/2/menuet/pics/tanzania.bmp',0 |
* '/hd0/1/Program files/NameOfProgram/SomeFile.SomeExtension',0 |
4063,6 → 4061,7 |
®áâã¯ë¥ ¯®¤äãªæ¨¨: |
* ¯®¤äãªæ¨ï 0 - ç⥨¥ ä ©« |
* ¯®¤äãªæ¨ï 1 - ç⥨¥ ¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 2 - ᮧ¤ ¨¥/¯¥à¥§ ¯¨áì ä ©« |
====================================================================== |
= ãªæ¨ï 70, ¯®¤äãªæ¨ï 0 - ç⥨¥ ä ©« á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬ñ. = |
4186,6 → 4185,30 |
¨ä®à¬ 樨 ®¡ ®¡®à㤮¢ ¨¨ - ¯®¤äãªæ¨ï 11 äãªæ¨¨ 18. |
====================================================================== |
====================== ãªæ¨ï 70, ¯®¤äãªæ¨ï 2 ====================== |
======== ®§¤ ¨¥/¯¥à¥§ ¯¨áì ä ©« á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬ñ. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 2 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +12 = +0xC: dword: ᪮«ìª® ¡ ©â ¯¨á âì |
* +16 = +0x10: dword: 㪠§ â¥«ì ¤ ë¥ |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx = ç¨á«® § ¯¨á ëå ¡ ©â (¢®§¬®¦®, 0) |
¬¥ç ¨ï: |
* ᫨ ä ©« á â ª¨¬ ¨¬¥¥¬ ¥ áãé¥á⢮¢ «, ® ᮧ¤ ñâáï; ¥á«¨ |
áãé¥á⢮¢ «, â® ¯¥à¥§ ¯¨áë¢ ¥âáï. |
* ᫨ ᢮¡®¤®£® ¬¥áâ ¤¨áª¥ ¥¤®áâ â®ç®, â® äãªæ¨ï § ¯¨è¥â, |
᪮«ìª® ᬮ¦¥â, ¯®á«¥ 祣® ¢¥àñâ ª®¤ ®è¨¡ª¨ 8. |
====================================================================== |
========== ãªæ¨ï -1 - § ¢¥àè¨âì ¢ë¯®«¥¨¥ ¯®â®ª /¯à®æ¥áá ========= |
====================================================================== |
à ¬¥âàë: |
4254,6 → 4277,7 |
* 8 = ¤¨áª § ¯®«¥ |
* 9 = â ¡«¨æ FAT à §àãè¥ |
* 10 = ¤®áâ㯠§ ¯à¥éñ |
* 11 = ®è¨¡ª ãáâனá⢠|
ਠ§ ¯ã᪥ ¯à®£à ¬¬ë ¢®§¬®¦ë â ª¦¥ á«¥¤ãî騥 ª®¤ë ®è¨¡®ª: |
* 30 = 0x1E = ¥¤®áâ â®ç® ¯ ¬ï⨠|
* 31 = 0x1F = ä ©« ¥ ï¥âáï ¨á¯®«¨¬ë¬ |
/kernel/trunk/fs/fat12.inc |
---|
545,10 → 545,8 |
add ecx,21 |
add edi, ecx ;Advance to next entry |
dec dl |
cmp dl,0 |
jne l.21_2 |
dec dh |
cmp dh,0 |
jne l.20_2 |
jmp frnoreadd_1 |
561,9 → 559,7 |
mov eax,[path_pointer_flp] |
cmp [eax+36],byte 0 |
je fifoundd_2 |
add edi,0xf |
mov eax,[edi] |
and eax,65535 |
movzx eax, word [edi+0xf] |
mov ebx,[path_pointer_flp] |
add ebx,36 |
call get_cluster_of_a_path_flp |
575,10 → 571,7 |
dec [FDD_Sector] |
fifoundd_2_1: |
mov [edi-11],byte 0xE5 ;mark filename deleted |
add edi,0xf |
mov eax,[edi] |
and eax,65535 |
mov edi,eax ;edi = cluster |
movzx edi, word [edi+0xf] ;edi = cluster |
frnewd_1: |
shl edi,1 ;find next cluster from FAT |
add edi,0x282000 |
674,9 → 667,7 |
; find an empty spot for filename in the root dir |
l20ds_1: |
sub edx,1 |
cmp edx,0 |
jnz l21ds_1 |
jmp frnoreadds_1 |
jz frnoreadds_1 |
l21ds_1: |
cmp [edi],byte 0xE5 |
jz fifoundds_1 |
709,10 → 700,8 |
add ecx,21 |
add edi, ecx ;Advance to next entry |
dec dl |
cmp dl,0 |
jne l.21_3 |
dec dh |
cmp dh,0 |
jne l.20_3 |
fdc_status_error_8: |
pop edi esi edx ecx ebx eax |
797,7 → 786,6 |
add edi,0x282000 |
mov eax,[edi] |
and eax,4095 |
cmp eax,0x0 |
jnz frnewds_2 |
mov [edx],bx ; save next cluster pos. to prev cl. |
mov edx,edi ; next save pos abs mem add |
1083,86 → 1071,203 |
ret |
; \begin{diamond} |
fd_find_lfn: |
fat_find_lfn: |
; in: esi->name |
; [esp+4] = next |
; [esp+8] = first |
; [esp+C]... - possibly parameters for first and next |
; out: CF=1 - file not found |
; else CF=0 and edi->direntry |
; else CF=0, esi->next name component, edi->direntry |
pusha |
lea eax, [esp+0Ch+20h] |
call dword [eax-4] |
jc .reterr |
sub esp, 262*2 ; reserve place for LFN |
mov ebp, esp |
push 0 ; for fat_get_name: read ASCII name |
call read_flp_fat |
cmp [FDC_Status], 0 |
jnz .error |
mov eax, 19 |
mov dh, 14 |
.main_loop: |
.20_1: |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .error |
mov edi, 0xD000 |
inc [FDD_Sector] |
push eax |
.21_1: |
.l1: |
call fat_get_name |
jc @f |
jc .l2 |
call fat_compare_name |
jz .found |
@@: |
add edi, 0x20 |
cmp edi, 0xD200 |
jb .21_1 |
pop eax |
inc eax |
dec dh |
js @f |
jnz .20_1 |
.error: |
.l2: |
lea eax, [esp+0Ch+20h+262*2+4] |
call dword [eax-8] |
jnc .l1 |
add esp, 262*2+4 |
.reterr: |
stc |
popa |
stc |
ret |
@@: |
; read next sector from FAT |
mov eax, [(eax-31-1)*2+0x282000] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
jae .error |
add eax, 31 |
jmp .main_loop |
.found: |
pop eax |
; if LFN entry, advance to corresponding short entry |
add esp, 262*2+4 |
; if this is LFN entry, advance to true entry |
cmp byte [edi+11], 0xF |
jnz .entryfound |
jnz @f |
lea eax, [esp+0Ch+20h] |
call dword [eax-8] |
jc .reterr |
@@: |
add esp, 8 ; CF=0 |
push esi |
push edi |
popa |
ret |
flp_root_next: |
cmp edi, 0xD200-0x20 |
jae @f |
add edi, 0x20 |
cmp edi, 0xD200 |
jb .entryfound |
dec dh |
jz .error |
inc eax |
ret ; CF=0 |
@@: |
; read next sector |
inc dword [eax] |
cmp dword [eax], 14 |
jae flp_root_first.readerr |
flp_root_first: |
mov eax, [eax] |
pusha |
add eax, 19 |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .error |
jnz .readerr |
mov edi, 0xD000 |
.entryfound: |
cmp byte [esi], 0 |
jz .done |
test byte [edi+11], 10h ; is a directory? |
jz .error |
movzx eax, word [edi+26] |
ret ; CF=0 |
.readerr: |
stc |
ret |
flp_rootmem_first: |
mov edi, 0x8000 |
clc |
ret |
flp_rootmem_next: |
add edi, 0x20 |
cmp edi, 0x8000+14*0x200 |
cmc |
flp_rootmem_next_write: |
flp_rootmem_begin_write: |
flp_rootmem_end_write: |
ret |
flp_rootmem_extend_dir: |
stc |
ret |
flp_notroot_next: |
cmp edi, 0xD200-0x20 |
jae flp_notroot_next_sector |
add edi, 0x20 |
ret ; CF=0 |
flp_notroot_next_sector: |
push ecx |
mov ecx, [eax] |
mov ecx, [ecx*2+0x282000] |
and ecx, 0xFFF |
cmp ecx, 2849 |
jae flp_notroot_first.err2 |
mov [eax], ecx |
pop ecx |
flp_notroot_first: |
mov eax, [eax] |
cmp eax, 2 |
jb .err |
cmp eax, 2849 |
jae .err |
pusha |
add eax, 31 |
mov dh, 0 |
jmp .main_loop |
.done: |
add esp, 262*2+4+4 |
push edi |
popad |
call read_chs_sector |
popa |
mov edi, 0xD000 |
cmp [FDC_Status], 0 |
jnz .err |
ret ; CF=0 |
.err2: |
pop ecx |
.err: |
stc |
ret |
flp_notroot_begin_write: |
pusha |
mov eax, [eax] |
add eax, 31 |
call read_chs_sector |
popa |
ret |
flp_notroot_end_write: |
pusha |
mov eax, [eax] |
add eax, 31 |
call save_chs_sector |
popa |
ret |
flp_notroot_next_write: |
cmp edi, 0xD200 |
jae @f |
ret |
@@: |
call flp_notroot_end_write |
jmp flp_notroot_next_sector |
flp_notroot_extend_dir: |
; find free cluster in FAT |
pusha |
xor eax, eax |
mov edi, 0x282000 |
mov ecx, 2849 |
repnz scasw |
jnz .notfound |
mov word [edi-2], 0xFFF ; mark as last cluster |
sub edi, 0x282000 |
shr edi, 1 |
dec edi |
mov eax, [esp+28] |
mov ecx, [eax] |
mov [0x282000+ecx*2], di |
mov [eax], edi |
xor eax, eax |
mov edi, 0xD000 |
mov ecx, 128 |
rep stosd |
popa |
call flp_notroot_end_write |
mov edi, 0xD000 |
clc |
ret |
.notfound: |
popa |
stc |
ret |
fd_find_lfn: |
; in: esi->name |
; out: CF=1 - file not found |
; else CF=0 and edi->direntry |
push esi edi |
push 0 |
push flp_root_first |
push flp_root_next |
.loop: |
call fat_find_lfn |
jc .notfound |
cmp byte [esi], 0 |
jz .found |
test byte [edi+11], 10h |
jz .notfound |
movzx eax, word [edi+26] ; cluster |
mov [esp+8], eax |
mov dword [esp+4], flp_notroot_first |
mov dword [esp], flp_notroot_next |
jmp .loop |
.notfound: |
add esp, 12 |
pop edi esi |
stc |
ret |
.found: |
add esp, 16 ; CF=0 |
pop esi |
ret |
;---------------------------------------------------------------- |
; |
; fs_FloppyRead - LFN variant for reading floppy |
1259,7 → 1364,7 |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
mov al, 5 ; may be other error code? |
mov al, 11 |
ret |
;---------------------------------------------------------------- |
1398,4 → 1503,406 |
pop ecx edi edi |
ret |
;---------------------------------------------------------------- |
; |
; fs_FloppyRewrite - LFN variant for writing sys floppy |
; |
; esi points to filename |
; ebx ignored (reserved) |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = number of written bytes |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
@@: |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
fsfrfe2: |
popad |
fsfrfe: |
mov eax, 11 |
xor ebx, ebx |
ret |
fs_FloppyRewrite: |
cmp byte [esi], 0 |
jz @b |
call read_flp_fat |
cmp [FDC_Status], 0 |
jnz fsfrfe |
pushad |
xor ebp, ebp |
push esi |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
lea ebp, [esi-1] |
jmp @b |
@@: |
pop esi |
test ebp, ebp |
jnz .noroot |
call read_flp_root |
cmp [FDC_Status], 0 |
jnz fsfrfe2 |
push flp_rootmem_extend_dir |
push flp_rootmem_end_write |
push flp_rootmem_next_write |
push flp_rootmem_begin_write |
xor ebp, ebp |
push ebp |
push flp_rootmem_first |
push flp_rootmem_next |
jmp .common1 |
.noroot: |
; check existence |
mov byte [ebp], 0 |
call fd_find_lfn |
mov byte [ebp], '/' |
lea esi, [ebp+1] |
jnc @f |
mov eax, ERROR_FILE_NOT_FOUND |
.ret1: |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
@@: |
test byte [edi+11], 0x10 ; must be directory |
mov eax, ERROR_ACCESS_DENIED |
jz .ret1 |
movzx ebp, word [edi+26] ; ebp=cluster |
mov eax, ERROR_FAT_TABLE |
cmp ebp, 2 |
jb .ret1 |
cmp ebp, 2849 |
jae .ret1 |
push flp_notroot_extend_dir |
push flp_notroot_end_write |
push flp_notroot_next_write |
push flp_notroot_begin_write |
push ebp |
push flp_notroot_first |
push flp_notroot_next |
.common1: |
call fat_find_lfn |
jc .notfound |
; found, delete FAT chain |
push edi |
xor eax, eax |
mov dword [edi+28], eax ; zero size |
xchg ax, word [edi+26] ; start cluster |
test eax, eax |
jz .done1 |
@@: |
cmp eax, 0xFF8 |
jae .done1 |
lea edi, [0x282000 + eax*2] ; position in FAT |
xor eax, eax |
xchg ax, [edi] |
jmp @b |
.done1: |
pop edi |
call get_time_for_file |
mov [edi+22], ax |
call get_date_for_file |
mov [edi+24], ax |
mov [edi+18], ax |
or byte [edi+11], 20h ; set 'archive' attribute |
jmp .doit |
.notfound: |
; file is not found; generate short name |
call fat_name_is_legal |
jc @f |
add esp, 28 |
popad |
mov eax, ERROR_FILE_NOT_FOUND |
xor ebx, ebx |
ret |
@@: |
sub esp, 12 |
mov edi, esp |
call fat_gen_short_name |
.test_short_name_loop: |
push esi edi ecx |
mov esi, edi |
lea eax, [esp+12+12+8] |
mov [eax], ebp |
call dword [eax-4] |
jc .found |
.test_short_name_entry: |
cmp byte [edi+11], 0xF |
jz .test_short_name_cont |
mov ecx, 11 |
push esi edi |
repz cmpsb |
pop edi esi |
jz .short_name_found |
.test_short_name_cont: |
lea eax, [esp+12+12+8] |
call dword [eax-8] |
jnc .test_short_name_entry |
jmp .found |
.short_name_found: |
pop ecx edi esi |
call fat_next_short_name |
jnc .test_short_name_loop |
.disk_full: |
add esp, 12+28 |
popa |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.found: |
pop ecx edi esi |
; now find space in directory |
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' |
mov al, '~' |
push ecx edi |
mov ecx, 8 |
repnz scasb |
push 1 |
pop eax ; 1 entry |
jnz .notilde |
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total |
xor eax, eax |
@@: |
cmp byte [esi], 0 |
jz @f |
inc esi |
inc eax |
jmp @b |
@@: |
sub esi, eax |
add eax, 12+13 |
mov ecx, 13 |
push edx |
cdq |
div ecx |
pop edx |
.notilde: |
push -1 |
push -1 |
; find <eax> successive entries in directory |
xor ecx, ecx |
push eax |
lea eax, [esp+12+8+12+8] |
mov [eax], ebp |
call dword [eax-4] |
pop eax |
jnc .scan_dir |
.fsfrfe3: |
add esp, 8+8+12+28 |
popad |
mov eax, 11 |
xor ebx, ebx |
ret |
.scan_dir: |
cmp byte [edi], 0 |
jz .free |
cmp byte [edi], 0xE5 |
jz .free |
xor ecx, ecx |
.scan_cont: |
push eax |
lea eax, [esp+12+8+12+8] |
call dword [eax-8] |
pop eax |
jnc .scan_dir |
cmp [FDC_Status], 0 |
jnz .fsfrfe3 |
push eax |
lea eax, [esp+12+8+12+8] |
call dword [eax+16] ; extend directory |
pop eax |
jnc .scan_dir |
add esp, 8+8+12+28 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.free: |
test ecx, ecx |
jnz @f |
mov [esp], edi |
mov ecx, [esp+8+8+12+8] |
mov [esp+4], ecx |
xor ecx, ecx |
@@: |
inc ecx |
cmp ecx, eax |
jb .scan_cont |
; found! |
; calculate name checksum |
push esi ecx |
mov esi, [esp+8+8] |
mov ecx, 11 |
xor eax, eax |
@@: |
ror al, 1 |
add al, [esi] |
inc esi |
loop @b |
pop ecx esi |
pop edi |
pop dword [esp+8+12+8] |
; edi points to first entry in free chunk |
dec ecx |
jz .nolfn |
push esi |
push eax |
lea eax, [esp+8+8+12+8] |
call dword [eax+4] ; begin write |
mov al, 40h |
.writelfn: |
or al, cl |
mov esi, [esp+4] |
push ecx |
dec ecx |
imul ecx, 13 |
add esi, ecx |
stosb |
mov cl, 5 |
call fs_RamdiskRewrite.read_symbols |
mov ax, 0xF |
stosw |
mov al, [esp+4] |
stosb |
mov cl, 6 |
call fs_RamdiskRewrite.read_symbols |
xor eax, eax |
stosw |
mov cl, 2 |
call fs_RamdiskRewrite.read_symbols |
pop ecx |
lea eax, [esp+8+8+12+8] |
call dword [eax+8] ; next write |
xor eax, eax |
loop .writelfn |
pop eax |
pop esi |
; lea eax, [esp+8+12+8] |
; call dword [eax+12] ; end write |
.nolfn: |
xchg esi, [esp] |
mov ecx, 11 |
rep movsb |
mov word [edi], 20h ; attributes |
sub edi, 11 |
pop esi ecx |
add esp, 12 |
mov byte [edi+13], 0 ; tenths of a second at file creation time |
call get_time_for_file |
mov [edi+14], ax ; creation time |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+16], ax ; creation date |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
and word [edi+20], 0 ; high word of cluster |
and word [edi+26], 0 ; low word of cluster - to be filled |
and dword [edi+28], 0 ; file size - to be filled |
.doit: |
lea eax, [esp+8] |
call dword [eax+12] ; flush directory |
push ecx |
push edi |
add edi, 26 ; edi points to low word of cluster |
push edi |
mov esi, edx |
jecxz .done |
mov ecx, 2849 |
mov edi, 0x282000 |
push 0 ; first cluster |
.write_loop: |
; allocate new cluster |
xor eax, eax |
repnz scasw |
mov al, ERROR_DISK_FULL |
jnz .ret |
dec edi |
dec edi |
lea eax, [edi-0x282000] |
shr eax, 1 ; eax = cluster |
mov word [edi], 0xFFF ; mark as last cluster |
cmp dword [esp], 0 |
jz .first |
xchg edi, [esp+4] |
stosw |
mov edi, [esp+4] |
jmp @f |
.first: |
mov [esp], eax |
@@: |
inc ecx |
; write data |
push ecx edi |
mov ecx, 512 |
cmp dword [esp+20], ecx |
jae @f |
mov ecx, [esp+20] |
@@: |
push ecx |
mov edi, 0xD000 |
rep movsb |
pop ecx |
push ecx |
sub ecx, 512 |
neg ecx |
push eax |
xor eax, eax |
rep stosb |
pop eax |
add eax, 31 |
pusha |
call save_chs_sector |
popa |
pop ecx |
cmp [FDC_Status], 0 |
jnz .diskerr |
sub [esp+20], ecx |
pop edi ecx |
jnz .write_loop |
.done: |
xor eax, eax |
.ret: |
pop ebx edi edi ecx |
mov [esp+28+28], eax |
lea eax, [esp+8] |
call dword [eax+4] |
mov [edi+26], bx |
mov ebx, esi |
sub ebx, edx |
mov [edi+28], ebx |
call dword [eax+12] |
mov [esp+28+16], ebx |
test ebp, ebp |
jnz @f |
call save_flp_root |
@@: |
add esp, 28 |
cmp [FDC_Status], 0 |
jnz .err3 |
call save_flp_fat |
cmp [FDC_Status], 0 |
jnz .err3 |
popa |
ret |
.err3: |
popa |
mov al, 11 |
xor ebx, ebx |
ret |
.diskerr: |
sub esi, ecx |
mov eax, 11 |
pop edi ecx |
jmp .ret |
; \end{diamond} |
/kernel/trunk/fs/fat32.inc |
---|
7,6 → 7,7 |
;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;; |
;; ;; |
;; See file COPYING for details ;; |
;; 27.05.2006 LFN create/rewrite file - diamond ;; |
;; 04.05.2006 LFN read folder - diamond ;; |
;; 29.04.2006 Elimination of hangup after the ;; |
;; expiration hd_wait_timeout - Mario79 ;; |
2934,113 → 2935,37 |
; in: esi->name |
; out: CF=1 - file not found |
; else CF=0 and edi->direntry |
pusha |
sub esp, 262*2 ; allocate space for LFN |
mov ebp, esp |
push 0 ; for fat_get_name: read ASCII name |
mov eax, [ROOT_CLUSTER] ; start from root |
.mainloop: |
.new_cluster: |
mov [cluster_tmp], eax |
mov [fat16_root], 0 |
cmp eax, [LAST_CLUSTER] |
ja .notfound |
cmp eax, 2 |
jae .data_cluster |
cmp [fat_type], 16 |
jnz .notfound |
mov eax, [ROOT_START] |
mov ecx, [ROOT_SECTORS] |
mov [fat16_root], 1 |
jmp .new_sector |
.data_cluster: |
dec eax |
dec eax |
mov ecx, [SECTORS_PER_CLUSTER] |
mul ecx |
add eax, [DATA_START] |
.new_sector: |
mov ebx, buffer |
call hd_read |
cmp [hd_error],0 |
jne .notfound |
mov edi, ebx |
add ebx, 512 |
push eax |
.l1: |
call fat_get_name |
jc .l2 |
call fat_compare_name |
; destroys eax |
push esi edi |
push 0 |
push 0 |
push fat16_root_first |
push fat16_root_next |
mov eax, [ROOT_CLUSTER] |
cmp [fat_type], 32 |
jz .fat32 |
.loop: |
call fat_find_lfn |
jc .notfound |
cmp byte [esi], 0 |
jz .found |
.l2: |
add edi, 0x20 |
cmp edi, ebx |
jb .l1 |
pop eax |
inc eax |
loop .new_sector |
cmp [fat16_root], 0 |
jnz .notfound |
mov eax, [cluster_tmp] |
call get_FAT |
cmp [hd_error],0 |
jne .notfound |
cmp eax, 2 |
jb .notfound |
cmp eax, [fatRESERVED] |
jb .new_cluster |
test byte [edi+11], 10h |
jz .notfound |
and dword [esp+12], 0 |
movzx eax, word [edi+26] ; cluster |
.fat32: |
mov [esp+8], eax |
mov dword [esp+4], fat_notroot_first |
mov dword [esp], fat_notroot_next |
jmp .loop |
.notfound: |
add esp, 262*2+4 |
popa |
add esp, 16 |
pop edi esi |
stc |
ret |
.found: |
pop eax |
; if this is LFN entry, advance to true entry |
cmp byte [edi+11], 0xF |
jnz .entryfound |
add edi, 0x20 |
cmp edi, ebx |
jb .entryfound |
inc eax |
dec ecx |
jnz .read_entry |
cmp [fat16_root], 0 |
jnz .notfound |
mov eax, [cluster_tmp] |
call get_FAT |
cmp [hd_error],0 |
jne .notfound |
cmp eax, 2 |
jb .notfound |
cmp eax, [fatRESERVED] |
jae .notfound |
dec eax |
dec eax |
mul [SECTORS_PER_CLUSTER] |
add eax, [DATA_START] |
.read_entry: |
mov ebx, [buffer] |
call hd_read |
cmp [hd_error],0 |
jne .notfound |
mov edi, ebx |
.entryfound: |
cmp byte [esi], 0 |
jz .done |
test byte [edi+11], 10h ; is a directory? |
jz .notfound |
mov eax, [edi+20-2] |
mov ax, [edi+26] |
jmp .mainloop |
.done: |
add esp, 262*2+4+4 ; CF=0 |
push edi |
popad |
add esp, 20 ; CF=0 |
pop esi |
ret |
;---------------------------------------------------------------- |
3366,4 → 3291,620 |
pop ecx esi edi |
ret |
fat16_root_next: |
cmp edi, buffer+0x200-0x20 |
jae fat16_root_next_sector |
add edi, 0x20 |
ret ; CF=0 |
fat16_root_next_sector: |
; read next sector |
push ecx |
mov ecx, [eax+4] |
inc ecx |
mov [eax+4], ecx |
cmp ecx, [ROOT_SECTORS] |
pop ecx |
jae fat16_root_first.readerr |
fat16_root_first: |
mov eax, [eax+4] |
add eax, [ROOT_START] |
push ebx |
mov edi, buffer |
mov ebx, edi |
call hd_read |
pop ebx |
cmp [hd_error], 0 |
jnz .readerr |
ret ; CF=0 |
.readerr: |
stc |
ret |
fat16_root_begin_write: |
push edi eax |
call fat16_root_first |
pop eax edi |
ret |
fat16_root_end_write: |
pusha |
mov eax, [eax+4] |
add eax, [ROOT_START] |
mov ebx, buffer |
call hd_write |
popa |
ret |
fat16_root_next_write: |
cmp edi, buffer+0x200 |
jae @f |
ret |
@@: |
call fat16_root_end_write |
jmp fat16_root_next_sector |
fat16_root_extend_dir: |
stc |
ret |
fat_notroot_next: |
cmp edi, buffer+0x200-0x20 |
jae fat_notroot_next_sector |
add edi, 0x20 |
ret ; CF=0 |
fat_notroot_next_sector: |
push ecx |
mov ecx, [eax+4] |
inc ecx |
cmp ecx, [SECTORS_PER_CLUSTER] |
jae fat_notroot_next_cluster |
mov [eax+4], ecx |
jmp @f |
fat_notroot_next_cluster: |
push eax |
mov eax, [eax] |
call get_FAT |
mov ecx, eax |
pop eax |
cmp [hd_error], 0 |
jnz fat_notroot_next_err |
cmp ecx, [fatRESERVED] |
jae fat_notroot_next_err |
mov [eax], ecx |
and dword [eax+4], 0 |
@@: |
pop ecx |
fat_notroot_first: |
call fat_get_sector |
push ebx |
mov edi, buffer |
mov ebx, edi |
call hd_read |
pop ebx |
cmp [hd_error], 0 |
jnz @f |
ret ; CF=0 |
fat_notroot_next_err: |
pop ecx |
@@: |
stc |
ret |
fat_notroot_begin_write: |
push eax edi |
call fat_notroot_first |
pop edi eax |
ret |
fat_notroot_end_write: |
call fat_get_sector |
push ebx |
mov ebx, buffer |
call hd_write |
pop ebx |
ret |
fat_notroot_next_write: |
cmp edi, buffer+0x200 |
jae @f |
ret |
@@: |
push eax |
call fat_notroot_end_write |
pop eax |
jmp fat_notroot_next_sector |
fat_notroot_extend_dir: |
push eax |
mov eax, [eax] |
call get_free_FAT |
jnc .found |
pop eax |
ret ; CF=1 |
.found: |
push edx |
mov edx, [fatEND] |
call set_FAT |
mov edx, eax |
mov eax, [esp+4] |
mov eax, [eax] |
push edx |
mov [f_del], 1 |
call set_FAT |
pop edx |
cmp [hd_error], 0 |
jz @f |
pop edx |
pop eax |
stc |
ret |
@@: |
push ecx |
or ecx, -1 |
call add_disk_free_space |
; zero new cluster |
mov ecx, 512/4 |
mov edi, buffer |
push edi |
xor eax, eax |
rep stosd |
pop edi |
pop ecx |
mov eax, [esp+4] |
mov [eax], edx |
and dword [eax+4], 0 |
pop edx |
mov eax, [eax] |
dec eax |
dec eax |
push ebx ecx |
mov ecx, [SECTORS_PER_CLUSTER] |
imul eax, ecx |
add eax, [DATA_START] |
mov ebx, edi |
@@: |
call hd_write |
inc eax |
loop @b |
pop ecx ebx eax |
clc |
ret |
fat_get_sector: |
push ecx |
mov ecx, [eax] |
dec ecx |
dec ecx |
imul ecx, [SECTORS_PER_CLUSTER] |
add ecx, [DATA_START] |
add ecx, [eax+4] |
mov eax, ecx |
pop ecx |
ret |
;---------------------------------------------------------------- |
; |
; fs_HdRewrite - LFN variant for writing hard disk |
; |
; esi points to filename |
; ebx ignored (reserved) |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = number of written bytes |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fshrad: |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
fshrfs: |
mov eax, ERROR_UNKNOWN_FS |
xor ebx, ebx |
ret |
fs_HdRewrite: |
cmp [fat_type], 0 |
jz fshrfs |
cmp byte [esi], 0 |
jz fshrad |
pushad |
xor ebp, ebp |
push esi |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
lea ebp, [esi-1] |
jmp @b |
@@: |
pop esi |
test ebp, ebp |
jnz .noroot |
mov ebp, [ROOT_CLUSTER] |
cmp [fat_type], 32 |
jz .pushnotroot |
push fat16_root_extend_dir |
push fat16_root_end_write |
push fat16_root_next_write |
push fat16_root_begin_write |
xor ebp, ebp |
push ebp |
push ebp |
push fat16_root_first |
push fat16_root_next |
jmp .common1 |
.noroot: |
; check existence |
mov byte [ebp], 0 |
call hd_find_lfn |
mov byte [ebp], '/' |
lea esi, [ebp+1] |
jnc @f |
mov eax, ERROR_FILE_NOT_FOUND |
.ret1: |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
@@: |
test byte [edi+11], 0x10 ; must be directory |
mov eax, ERROR_ACCESS_DENIED |
jz .ret1 |
mov ebp, [edi+20-2] |
mov bp, [edi+26] ; ebp=cluster |
mov eax, ERROR_FAT_TABLE |
cmp ebp, 2 |
jb .ret1 |
.pushnotroot: |
push fat_notroot_extend_dir |
push fat_notroot_end_write |
push fat_notroot_next_write |
push fat_notroot_begin_write |
push 0 |
push ebp |
push fat_notroot_first |
push fat_notroot_next |
.common1: |
call fat_find_lfn |
jc .notfound |
; found, delete FAT chain |
push edi |
xor eax, eax |
mov dword [edi+28], eax ; zero size |
xor ecx, ecx |
mov eax, [edi+20-2] |
mov ax, [edi+26] |
mov word [edi+20], cx |
mov word [edi+26], cx |
test eax, eax |
jz .done1 |
mov [f_del], 1 |
@@: |
cmp eax, [fatRESERVED] |
jae .done1 |
push edx |
xor edx, edx |
call set_FAT |
mov eax, edx |
pop edx |
inc ecx |
jmp @b |
.done1: |
pop edi |
call get_time_for_file |
mov [edi+22], ax |
call get_date_for_file |
mov [edi+24], ax |
mov [edi+18], ax |
or byte [edi+11], 20h ; set 'archive' attribute |
jmp .doit |
.notfound: |
; file is not found; generate short name |
call fat_name_is_legal |
jc @f |
add esp, 32 |
popad |
mov eax, ERROR_FILE_NOT_FOUND |
xor ebx, ebx |
ret |
@@: |
sub esp, 12 |
mov edi, esp |
call fat_gen_short_name |
.test_short_name_loop: |
push esi edi ecx |
mov esi, edi |
lea eax, [esp+12+12+8] |
mov [eax], ebp |
and dword [eax+4], 0 |
call dword [eax-4] |
jc .found |
.test_short_name_entry: |
cmp byte [edi+11], 0xF |
jz .test_short_name_cont |
mov ecx, 11 |
push esi edi |
repz cmpsb |
pop edi esi |
jz .short_name_found |
.test_short_name_cont: |
lea eax, [esp+12+12+8] |
call dword [eax-8] |
jnc .test_short_name_entry |
jmp .found |
.short_name_found: |
pop ecx edi esi |
call fat_next_short_name |
jnc .test_short_name_loop |
.disk_full: |
add esp, 12+32 |
popa |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.found: |
pop ecx edi esi |
; now find space in directory |
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' |
mov al, '~' |
push ecx edi |
mov ecx, 8 |
repnz scasb |
push 1 |
pop eax ; 1 entry |
jnz .notilde |
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total |
xor eax, eax |
@@: |
cmp byte [esi], 0 |
jz @f |
inc esi |
inc eax |
jmp @b |
@@: |
sub esi, eax |
add eax, 12+13 |
mov ecx, 13 |
push edx |
cdq |
div ecx |
pop edx |
.notilde: |
push -1 |
push -1 |
push -1 |
; find <eax> successive entries in directory |
xor ecx, ecx |
push eax |
lea eax, [esp+16+8+12+8] |
mov [eax], ebp |
and dword [eax+4], 0 |
call dword [eax-4] |
pop eax |
jnc .scan_dir |
.fsfrfe3: |
add esp, 12+8+12+32 |
popad |
mov eax, 11 |
xor ebx, ebx |
ret |
.scan_dir: |
cmp byte [edi], 0 |
jz .free |
cmp byte [edi], 0xE5 |
jz .free |
xor ecx, ecx |
.scan_cont: |
push eax |
lea eax, [esp+16+8+12+8] |
call dword [eax-8] |
pop eax |
jnc .scan_dir |
cmp [hd_error], 0 |
jnz .fsfrfe3 |
push eax |
lea eax, [esp+16+8+12+8] |
call dword [eax+20] ; extend directory |
pop eax |
jnc .scan_dir |
add esp, 12+8+12+32 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.free: |
test ecx, ecx |
jnz @f |
mov [esp], edi |
mov ecx, [esp+12+8+12+8] |
mov [esp+4], ecx |
mov ecx, [esp+12+8+12+12] |
mov [esp+8], ecx |
xor ecx, ecx |
@@: |
inc ecx |
cmp ecx, eax |
jb .scan_cont |
; found! |
; calculate name checksum |
push esi ecx |
mov esi, [esp+8+12] |
mov ecx, 11 |
xor eax, eax |
@@: |
ror al, 1 |
add al, [esi] |
inc esi |
loop @b |
pop ecx esi |
pop edi |
pop dword [esp+8+12+12] |
pop dword [esp+8+12+12] |
; edi points to first entry in free chunk |
dec ecx |
jz .nolfn |
push esi |
push eax |
lea eax, [esp+8+8+12+8] |
call dword [eax+8] ; begin write |
mov al, 40h |
.writelfn: |
or al, cl |
mov esi, [esp+4] |
push ecx |
dec ecx |
imul ecx, 13 |
add esi, ecx |
stosb |
mov cl, 5 |
call fs_RamdiskRewrite.read_symbols |
mov ax, 0xF |
stosw |
mov al, [esp+4] |
stosb |
mov cl, 6 |
call fs_RamdiskRewrite.read_symbols |
xor eax, eax |
stosw |
mov cl, 2 |
call fs_RamdiskRewrite.read_symbols |
pop ecx |
lea eax, [esp+8+8+12+8] |
call dword [eax+12] ; next write |
xor eax, eax |
loop .writelfn |
pop eax |
pop esi |
; lea eax, [esp+8+12+8] |
; call dword [eax+16] ; end write |
.nolfn: |
xchg esi, [esp] |
mov ecx, 11 |
rep movsb |
mov word [edi], 20h ; attributes |
sub edi, 11 |
pop esi ecx |
add esp, 12 |
mov byte [edi+13], 0 ; tenths of a second at file creation time |
call get_time_for_file |
mov [edi+14], ax ; creation time |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+16], ax ; creation date |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
xor ecx, ecx |
mov word [edi+20], cx ; high word of cluster |
mov word [edi+26], cx ; low word of cluster - to be filled |
mov dword [edi+28], ecx ; file size - to be filled |
.doit: |
lea eax, [esp+8] |
call dword [eax+16] ; flush directory |
push ecx |
mov ecx, [esp+4+32+24] |
push ecx |
push edi |
mov esi, edx |
test ecx, ecx |
jz .done |
mov eax, 2 |
call get_free_FAT |
jc .diskfull |
push eax |
mov [edi+26], ax |
shr eax, 16 |
mov [edi+20], ax |
lea eax, [esp+16+8] |
call dword [eax+16] ; flush directory |
pop eax |
push edx |
mov edx, [fatEND] |
call set_FAT |
pop edx |
.write_cluster: |
push eax |
dec eax |
dec eax |
mov ebp, [SECTORS_PER_CLUSTER] |
imul eax, ebp |
add eax, [DATA_START] |
; write data |
.write_sector: |
mov ecx, 512 |
cmp dword [esp+8], ecx |
jb .writeshort |
; we can write directly from given buffer |
mov ebx, esi |
add esi, ecx |
jmp .writecommon |
.writeshort: |
mov ecx, [esp+8] |
push ecx |
mov edi, buffer |
mov ebx, edi |
rep movsb |
mov ecx, buffer+0x200 |
sub ecx, edi |
push eax |
xor eax, eax |
rep stosb |
pop eax |
pop ecx |
.writecommon: |
call hd_write |
cmp [hd_error], 0 |
jnz .writeerr |
inc eax |
sub dword [esp+8], ecx |
jz .writedone |
dec ebp |
jnz .write_sector |
; allocate new cluster |
pop eax |
mov ecx, eax |
call get_free_FAT |
jc .diskfull |
mov [f_del], 1 |
push edx |
mov edx, [fatEND] |
call set_FAT |
xchg eax, ecx |
mov edx, ecx |
call set_FAT |
pop edx |
xchg eax, ecx |
jmp .write_cluster |
.diskfull: |
mov eax, ERROR_DISK_FULL |
jmp .ret |
.writeerr: |
pop eax |
sub esi, ecx |
mov eax, 11 |
jmp .ret |
.writedone: |
pop eax |
.done: |
xor eax, eax |
.ret: |
pop edi ecx |
mov ebx, esi |
sub ebx, edx |
pop ebp |
mov [esp+32+28], eax |
lea eax, [esp+8] |
call dword [eax+8] |
mov [edi+28], ebx |
call dword [eax+16] |
mov [esp+32+16], ebx |
lea eax, [ebx+511] |
shr eax, 9 |
mov ecx, [SECTORS_PER_CLUSTER] |
lea eax, [eax+ecx-1] |
xor edx, edx |
div ecx |
mov ecx, ebp |
sub ecx, eax |
call add_disk_free_space |
add esp, 32 |
call update_disk |
popad |
ret |
; \end{diamond} |
/kernel/trunk/fs/fs.inc |
---|
61,6 → 61,7 |
; eax = 8 : disk full |
; eax = 9 : fat table corrupted |
; eax = 10 : access denied |
; eax = 11 : disk error |
; |
; ebx = size |
/kernel/trunk/fs/fs_lfn.inc |
---|
51,13 → 51,13 |
; operation codes: |
; 0 : read file |
; 1 : read folder |
; 2 : rewrite file - not implemented yet |
; 2 : create/rewrite file |
; 3 : write/append to file - not implemented yet |
; 4 : start application - not implemented yet |
; 5 : delete file - not implemented yet |
; 6 : create directory - not implemented yet |
; 7 : rename file/directory - not implemented yet |
; 8 : get file attributes structure - not implemented yet |
; 4 : delete file - not implemented yet |
; 5 : create directory - not implemented yet |
; 6 : rename file/directory - not implemented yet |
; 7 : get file attributes structure - not implemented yet |
; 8 : start application - not implemented yet |
add eax, std_application_base_address |
; parse file name |
290,8 → 290,8 |
cmp ecx, 1 |
jnz file_system_lfn.notfound |
mov eax, [ebx] |
cmp eax, 1 |
ja .not_impl |
cmp eax, fs_NumRamdiskServices |
jae .not_impl |
mov ecx, [ebx+12] |
mov edx, [ebx+16] |
add edx, std_application_base_address |
307,13 → 307,15 |
fs_RamdiskServices: |
dd fs_RamdiskRead |
dd fs_RamdiskReadFolder |
dd fs_RamdiskRewrite |
fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4 |
fs_OnFloppy: |
cmp ecx, 2 |
ja file_system_lfn.notfound |
mov eax, [ebx] |
cmp eax, 1 |
ja fs_OnRamdisk.not_impl |
cmp eax, fs_NumFloppyServices |
jae fs_OnRamdisk.not_impl |
call reserve_flp |
mov [flp_number], cl |
mov ecx, [ebx+12] |
329,6 → 331,8 |
fs_FloppyServices: |
dd fs_FloppyRead |
dd fs_FloppyReadFolder |
dd fs_FloppyRewrite |
fs_NumFloppyServices = ($ - fs_FloppyServices)/4 |
fs_OnHd0: |
call reserve_hd1 |
373,8 → 377,8 |
mov edx, [ebx+16] |
add edx, std_application_base_address |
mov eax, [ebx] |
cmp eax, 1 |
ja .not_impl |
cmp eax, fs_NumHdServices |
jae .not_impl |
add ebx, 4 |
call dword [fs_HdServices + eax*4] |
and [hd1_status], 0 |
389,6 → 393,8 |
fs_HdServices: |
dd fs_HdRead |
dd fs_HdReadFolder |
dd fs_HdRewrite |
fs_NumHdServices = ($ - fs_HdServices)/4 |
fs_HasRamdisk: |
mov al, 1 ; we always have ramdisk |