From 7c7f68ee6f07049171348ca844eb4a2a9f87738f Mon Sep 17 00:00:00 2001 From: "Evgeny Grechnikov (Diamond)" Date: Mon, 24 Apr 2006 14:28:05 +0000 Subject: [PATCH] File system: read files with long names (LFN) git-svn-id: svn://kolibrios.org@71 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/blkdev/rd.inc | 342 ++++++++++++++++++++++++++++++++++++- kernel/trunk/fs/fat12.inc | 180 +++++++++++++++++++ kernel/trunk/fs/fat32.inc | 237 +++++++++++++++++++++++++ kernel/trunk/fs/fs.inc | 9 +- kernel/trunk/fs/fs_lfn.inc | 206 ++++++++++++++++++++++ 5 files changed, 968 insertions(+), 6 deletions(-) create mode 100644 kernel/trunk/fs/fs_lfn.inc diff --git a/kernel/trunk/blkdev/rd.inc b/kernel/trunk/blkdev/rd.inc index 3a5627397c..148af37ea3 100644 --- a/kernel/trunk/blkdev/rd.inc +++ b/kernel/trunk/blkdev/rd.inc @@ -258,15 +258,12 @@ fileread: call memmove add [esp+8],dword 512 dec dword [esp+12] ; last wanted cluster ? - cmp [esp+12],dword 0 je frnoread jmp frfl8 frfl7: dec dword [esp+16] frfl8: - shl edi,1 ;find next cluster from FAT - add edi,0x280000 - movzx eax,word [edi] + movzx eax,word [edi*2+0x280000] ; find next cluster from FAT mov edi,eax cmp edi,4095 ;eof - cluster jz frnoread2 @@ -519,4 +516,339 @@ mov [edi+22],ax ; time rd_getfileinfo_end: xor eax,eax add esp,32 - ret + ret + +; \begin{diamond} + +uni2ansi_str: +; convert UNICODE zero-terminated string to ASCII-string (codepage 866) +; in: esi->source, edi->buffer (may be esi=edi) +; destroys: eax,esi,edi + lodsw + test ax, ax + jz .done + cmp ax, 0x80 + jb .ascii + cmp ax, 0x401 + jz .yo1 + cmp ax, 0x451 + jz .yo2 + cmp ax, 0x410 + jb .unk + cmp ax, 0x440 + jb .rus1 + cmp ax, 0x450 + jb .rus2 +.unk: + mov al, '_' + jmp .doit +.yo1: + mov al, '' + jmp .doit +.yo2: + mov al, '' + jmp .doit +.rus1: +; 0x410-0x43F -> 0x80-0xAF + add al, 0x70 + jmp .doit +.rus2: +; 0x440-0x450 -> 0xE0-0xEF + add al, 0xA0 +.ascii: +.doit: + stosb + jmp uni2ansi_str +.done: + mov byte [edi], 0 + ret + +char_toupper: +; convert character to uppercase, using cp866 encoding +; in: al=symbol +; out: al=converted symbol + cmp al, 'a' + jb .ret + cmp al, 'z' + jbe .az + cmp al, '' + jb .ret + cmp al, '' + jb .rus1 + cmp al, '' + ja .ret +; 0xE0-0xEF -> 0x90-0x9F + sub al, ''-'' +.ret: + ret +.rus1: +; 0xA0-0xAF -> 0x80-0x8F +.az: + and al, not 0x20 + ret + +fat_get_name: +; in: edi->FAT entry +; out: CF=1 - no valid entry +; else CF=0 and ebp->ASCIIZ-name +; (maximum length of filename is 255 (wide) symbols without trailing 0, +; but implementation requires buffer 261 words) +; destroys eax + cmp byte [edi], 0 + jz .no + cmp byte [edi], 0xE5 + jnz @f +.no: + stc + ret +@@: + cmp byte [edi+11], 0xF + jz .longname + push ecx + mov ecx, 8 + push edi ebp ecx +@@: + mov al, [edi] + inc edi + mov [ebp], al + inc ebp + loop @b + pop ecx +@@: + cmp byte [ebp-1], ' ' + jnz @f + dec ebp + loop @b +@@: + mov byte [ebp], '.' + inc ebp + mov ecx, 3 + push ecx +@@: + mov al, [edi] + inc edi + mov [ebp], al + inc ebp + loop @b + pop ecx +@@: + cmp byte [ebp-1], ' ' + jnz @f + dec ebp + loop @b + dec ebp +@@: + and byte [ebp], 0 ; CF=0 + pop ebp edi ecx + ret +.longname: +; LFN + mov al, byte [edi] + and eax, 0x3F + dec eax + cmp al, 20 + jae .no ; ignore invalid entries + mov word [ebp+260*2], 0 ; force null-terminating for orphans + imul eax, 13*2 + add ebp, eax + test byte [edi], 0x40 + jz @f + mov word [ebp+13*2], 0 +@@: + push eax +; now copy name from edi to ebp ... + mov eax, [edi+1] + mov [ebp], eax ; symbols 1,2 + mov eax, [edi+5] + mov [ebp+4], eax ; 3,4 + mov eax, [edi+9] + mov [ebp+8], ax ; 5 + mov eax, [edi+14] + mov [ebp+10], eax ; 6,7 + mov eax, [edi+18] + mov [ebp+14], eax ; 8,9 + mov eax, [edi+22] + mov [ebp+18], eax ; 10,11 + mov eax, [edi+28] + mov [ebp+22], eax ; 12,13 +; ... done + pop eax + sub ebp, eax + test eax, eax + jz @f +; if this is not first entry, more processing required + stc + ret +@@: +; if this is first entry: +; buffer at ebp contains UNICODE name, convert it to ANSI + push esi edi + mov esi, ebp + mov edi, ebp + call uni2ansi_str + pop edi esi + clc + ret + +fat_compare_name: +; compares ASCIIZ-names, case-insensitive (cp866 encoding) +; in: esi->name, ebp->name +; out: if names match: ZF=1 and esi->next component of name +; else: ZF=0, esi is not changed +; destroys eax + push ebp esi +.loop: + mov al, [ebp] + inc ebp + call char_toupper + push eax + lodsb + call char_toupper + cmp al, [esp] + jnz .done + pop eax + test al, al + jnz .loop + dec esi + pop eax + pop ebp + xor eax, eax ; set ZF flag + ret +.done: + cmp al, '/' + jnz @f + cmp byte [esp], 0 + jnz @f + mov [esp+4], esi +@@: + pop eax + pop esi ebp + ret + +rd_find_lfn: +; in: esi->name +; out: CF=1 - file not found +; else CF=0 and edi->direntry + push esi ebp edi + sub esp, 262*2 ; allocate space for LFN + mov ebp, esp ; ebp points to buffer + mov edi, 0x100000+512*19 ; to root dir +.l1: + call fat_get_name + jc .l2 + call fat_compare_name + jz .found +.l2: + add edi, 0x20 + cmp edi, 0x100000+512*33 + jb .l1 +.notfound: + add esp, 262*2 + pop edi ebp esi + stc + ret +.found: +; found +; if this is LFN entry, advance to true entry + cmp byte [edi+11], 0xF + jnz @f + add edi, 0x20 +@@: +; folders are not supported + cmp byte [esi], 0 + jnz .notfound + add esp, 262*2+4 ; CF=0 + pop ebp esi + ret + +;---------------------------------------------------------------- +; +; fs_RamdiskRead - LFN variant for reading sys floppy +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to read, 0+ +; edx mem location to return data +; +; ret ebx = size or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_RamdiskRead: + cmp byte [esi], 0 + jnz @f + or ebx, -1 + mov eax, 10 ; access denied + ret +@@: + push edi + call rd_find_lfn + jnc .found + pop edi + or ebx, -1 + mov eax, 5 ; file not found + ret +.found: + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f + mov ebx, [edi+28] +.reteof: + mov eax, 6 ; EOF + pop edi + ret +@@: + mov ebx, [ebx] +.l1: + push dword [edi+28] ; file size + push dword [edi+28] + movzx edi, word [edi+26] ; cluster + push ecx edx +.new: + jecxz .done + test edi, edi + jz .eof + cmp edi, 0xFF8 + jae .eof + lea eax, [edi+31] ; bootsector+2*fat+filenames + shl eax, 9 ; *512 + add eax, 0x100000 ; image base +; now eax points to data of cluster + sub ebx, 512 + jae .skip + lea eax, [eax+ebx+512] + neg ebx + push ecx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: + cmp ecx, [esp+12] + jbe @f + mov ecx, [esp+12] +@@: + mov ebx, edx + call memmove + add edx, ecx + sub [esp], ecx + sub [esp+12], ecx + pop ecx + xor ebx, ebx + cmp [esp+8], ebx + jnz .skip + jecxz .done + jmp .eof +.skip: + movzx edi, word [edi*2+0x280000] ; find next cluster from FAT + jmp .new +.eof: + pop edx ecx ebx ebx + jmp .reteof +.done: + pop edx ecx ebx ebx edi + xor eax, eax + ret + +; \end{diamond} \ No newline at end of file diff --git a/kernel/trunk/fs/fat12.inc b/kernel/trunk/fs/fat12.inc index 4ae37876ab..b0b24aa86f 100644 --- a/kernel/trunk/fs/fat12.inc +++ b/kernel/trunk/fs/fat12.inc @@ -1082,3 +1082,183 @@ check_new_flp: pop ebx ret + +; \begin{diamond} +fd_find_lfn: +; in: esi->name +; out: CF=1 - file not found +; else CF=0 and edi->direntry + pusha + sub esp, 262*2 ; reserve place for LFN + mov ebp, esp + 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: + call fat_get_name + jc @f + 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: + add esp, 262*2 + popa + stc + ret +@@: +; read next sector from FAT + mov eax, [(eax-31)*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 + cmp byte [edi+11], 0xF + jnz .entryfound + add edi, 0x20 + cmp edi, 0xD200 + jb .entryfound + dec dh + jz .error + inc eax + call read_chs_sector + cmp [FDC_Status], 0 + jnz .error + 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] + add eax, 31 + mov dh, 0 + jmp .main_loop +.done: + add esp, 262*2+4 + push edi + popad + ret + +;---------------------------------------------------------------- +; +; fs_FloppyRead - LFN variant for reading floppy +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to read, 0+ +; edx mem location to return data +; +; ret ebx = size or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_FloppyRead: + mov [save_flag], 0 + cmp byte [esi], 0 + jnz @f + or ebx, -1 + mov eax, 10 ; access denied + ret +@@: + push edi + call fd_find_lfn + jnc .found + pop edi + or ebx, -1 + mov eax, 5 ; file not found + ret +.found: + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f + mov ebx, [edi+28] +.reteof: + mov eax, 6 ; EOF + pop edi + ret +@@: + mov ebx, [ebx] +.l1: + push dword [edi+28] + push dword [edi+28] + movzx edi, word [edi+26] + push ecx edx +.new: + jecxz .done + test edi, edi + jz .eof + cmp edi, 0xFF8 + jae .eof + mov eax, edi + add eax, 31 + pusha + call read_chs_sector + popa + cmp [FDC_Status], 0 + jnz .err + sub ebx, 512 + jae .skip + lea eax, [eax+ebx+512] + neg ebx + push ecx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: + cmp ecx, [esp+12] + jbe @f + mov ecx, [esp+12] +@@: + mov ebx, edx + mov eax, 0xD000 + call memmove + add edx, ecx + sub [esp], ecx + sub [esp+12], ecx + pop ecx + xor ebx, ebx + cmp [esp+8], ebx + jnz .skip + jecxz .done + jmp .eof +.skip: + movzx edi, word [edi*2+0x282000] + jmp .new +.done: + pop edx ecx ebx ebx edi + xor eax, eax + ret +.eof: + pop edx ecx ebx ebx + jmp .reteof +.err: + mov eax, 5 ; may be other error code? + pop edx ecx ebx ebx edi + ret +; \end{diamond} \ No newline at end of file diff --git a/kernel/trunk/fs/fat32.inc b/kernel/trunk/fs/fat32.inc index 5494b9b78a..331cae6f0d 100644 --- a/kernel/trunk/fs/fat32.inc +++ b/kernel/trunk/fs/fat32.inc @@ -8,6 +8,7 @@ ;; ;; ;; See file COPYING for details ;; ;; ;; +;; 23.04.2006 LFN read - diamond ;; ;; 28.01.2006 find all Fat16/32 partition in all input point ;; ;; to MBR, see file part_set.inc - Mario79 ;; ;; 15.01.2005 get file size/attr/date, file_append - ATV ;; @@ -2577,3 +2578,239 @@ read_hd_file: ret +; \begin{diamond} +hd_find_lfn: +; 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 + 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 + mov edi, ebx + add ebx, 512 + push eax +.l1: + call fat_get_name + jc .l2 + call fat_compare_name + 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 eax, 2 + jb .notfound + cmp eax, [fatRESERVED] + jb .new_cluster +.notfound: + add esp, 262*2 + popa + 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 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 + 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 ; CF=0 + push edi + popad + ret + +;---------------------------------------------------------------- +; +; fs_HdRead - LFN variant for reading hard disk +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to read, 0+ +; edx mem location to return data +; +; ret ebx = size or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_HdRead: + cmp [fat_type], 0 + jnz @f + or ebx, -1 + mov eax, ERROR_UNKNOWN_FS + ret +@@: + push edi + cmp byte [esi], 0 + jnz @f +.noaccess: + pop edi + or ebx, -1 + mov eax, ERROR_ACCESS_DENIED + ret +@@: + call hd_find_lfn + jnc .found + pop edi + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret +.found: + test byte [edi+11], 0x10 ; do not allow read directories + jnz .noaccess + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f + mov ebx, [edi+28] +.reteof: + mov eax, 6 + pop edi + ret +@@: + mov ebx, [ebx] +.l1: + push dword [edi+28] ; file size + mov eax, [edi+20-2] + mov ax, [edi+26] + push ecx edx + push dword [edi+28] +; now eax=cluster, ebx=position, ecx=count, edx=buffer for data +.new_cluster: + jecxz .new_sector + test eax, eax + jz .eof + cmp eax, [fatRESERVED] + jae .eof + mov [cluster_tmp], eax + dec eax + dec eax + mov edi, [SECTORS_PER_CLUSTER] + imul eax, edi + add eax, [DATA_START] +.new_sector: + test ecx, ecx + jz .done + sub ebx, 512 + jae .skip + add ebx, 512 + jnz .force_buf + cmp ecx, 512 + jb .force_buf + cmp dword [esp], 512 + jb .force_buf +; we may read directly to given buffer + push ebx + mov ebx, edx + call hd_read + pop ebx + add edx, 512 + sub ecx, 512 + sub dword [esp], 512 + jmp .skip +.force_buf: +; we must read sector to temporary buffer and then copy it to destination + push eax ebx + mov ebx, buffer + call hd_read + mov eax, ebx + pop ebx + add eax, ebx + push ecx + add ecx, ebx + cmp ecx, 512 + jbe @f + mov ecx, 512 +@@: + sub ecx, ebx + cmp ecx, [esp+8] + jbe @f + mov ecx, [esp+8] +@@: + mov ebx, edx + call memmove + add edx, ecx + sub [esp], ecx + sub [esp+8], ecx + pop ecx + pop eax + xor ebx, ebx + cmp [esp], ebx + jnz .skip + jecxz .done + jmp .eof +.skip: + inc eax + dec edi + jnz .new_sector + mov eax, [cluster_tmp] + call get_FAT + jmp .new_cluster +.done: + pop ebx edx ecx ebx edi + xor eax, eax + ret +.eof: + pop ebx edx ecx ebx + jmp .reteof +; \end{diamond} \ No newline at end of file diff --git a/kernel/trunk/fs/fs.inc b/kernel/trunk/fs/fs.inc index 4d2652b521..2355e489de 100644 --- a/kernel/trunk/fs/fs.inc +++ b/kernel/trunk/fs/fs.inc @@ -3,6 +3,7 @@ ;; System service for filesystem call ;; ;; (C) 2004 Ville Turjanmaa, License: GPL ;; ;; ;; +;; xx.04.2006 LFN support - diamond ;; ;; 15.01.2005 get file size/attr/date, file_append (only for hd) - ATV ;; ;; 23.11.2004 test if hd/partition is set - ATV ;; ;; 18.11.2004 get_disk_info and more error codes - ATV ;; @@ -49,7 +50,7 @@ file_system: ; ; eax = 0 : read ok ; eax = 1 : no hd base and/or partition defined -; eax = 2 : yet unsupported FS +; eax = 2 : function is unsupported for this FS ; eax = 3 : unknown FS ; eax = 4 : partition not defined at hd ; eax = 5 : file not found @@ -86,6 +87,10 @@ file_system: ; Extract parameters add eax, std_application_base_address ; abs start of info block +; \begin{diamond} + cmp byte [eax+1], 1 + jz file_system_lfn +; \end{diamond} cmp dword [eax+0],12 ; Get file size je fs_read @@ -1126,3 +1131,5 @@ err: partition_string: dd 0 db 32 + + include 'fs_lfn.inc' diff --git a/kernel/trunk/fs/fs_lfn.inc b/kernel/trunk/fs/fs_lfn.inc new file mode 100644 index 0000000000..b8c90e4641 --- /dev/null +++ b/kernel/trunk/fs/fs_lfn.inc @@ -0,0 +1,206 @@ +; System function 58, subfunctions 1xx +; diamond, 2006 + +iglobal +; in this table names must be in lowercase +rootdirs: + db 2,'rd' + dd fs_OnRamdisk + db 7,'ramdisk' + dd fs_OnRamdisk + db 2,'fd' + dd fs_OnFloppy + db 10,'floppydisk' + dd fs_OnFloppy + db 3,'hd0' + dd fs_OnHd0 + db 3,'hd1' + dd fs_OnHd1 + db 3,'hd2' + dd fs_OnHd2 + db 3,'hd3' + dd fs_OnHd3 + db 0 +endg + +file_system_lfn: +; in: eax->fileinfo block +; operation codes: +; 0x100 : read file +; 0x101 : rewrite file - not implemented yet +; 0x102 : delete file - not implemented yet +; 0x103 : write/append to file - not implemented yet +; 0x104 : create directory - not implemented yet +; 0x105 : rename file/directory - not implemented yet +; 0x106 : get file attributes structure - not implemented yet +; 0x107 : start application - not implemented yet +; 0x108 : find file with mask - not implemented yet + +; parse file name + xchg ebx, eax + lea esi, [ebx+20] + lodsb + cmp al, '/' + jz @f +.notfound: + mov dword [esp+36], 5 ; file not found + ret +@@: + cmp byte [esi], 0 + jz .rootdir + mov edi, rootdirs-4 + xor ecx, ecx + push esi +.scan1: + pop esi + add edi, ecx + scasd + mov cl, byte [edi] + jecxz .notfound + inc edi + push esi +@@: + lodsb + or al, 20h + scasb + loopz @b + jnz .scan1 + pop eax + lodsb + cmp al, '/' + jz .found1 + test al, al + jnz .scan1 +; directory /xxx +.maindir: +; directory / +.rootdir: + mov dword [esp+36], 10 ; access denied + ret + +.found1: + cmp byte [esi], 0 + jz .maindir + mov ebp, dword [edi] ; handler for this device +; read partition number + xor ecx, ecx + xor eax, eax +@@: + lodsb + cmp al, '/' + jz .done1 + test al, al + jz .done1 + sub al, '0' + cmp al, 9 + ja .notfound + imul ecx, 10 + add ecx, eax + jmp @b +.done1: + test ecx, ecx + jz .notfound + test al, al + jnz @f + dec esi +@@: +; now ebp contains handler address, ecx - partition number, esi points to ASCIIZ string - rest of name + jmp ebp + +; handlers for devices +; in: ecx = partition number +; esi -> relative (for device) name +; ebx -> fileinfo +; out: [esp+36]=image of eax, [esp+24]=image of ebx + +fs_OnRamdisk: + cmp ecx, 1 + jnz file_system_lfn.notfound + movzx eax, byte [ebx] + test eax, eax + jnz .not_impl + mov ecx, [ebx+12] + mov edx, [ebx+16] + add edx, std_application_base_address + add ebx, 4 + call dword [fs_RamdiskServices + eax*4] + mov [esp+36], eax + mov [esp+24], ebx + ret +.not_impl: + mov dword [esp+36], 2 ; not implemented + ret + +fs_RamdiskServices: + dd fs_RamdiskRead + +fs_OnFloppy: + cmp ecx, 2 + ja file_system_lfn.notfound + movzx eax, byte [ebx] + test eax, eax + jnz fs_OnRamdisk.not_impl + call reserve_flp + mov [flp_number], cl + mov ecx, [ebx+12] + mov edx, [ebx+16] + add edx, std_application_base_address + add ebx, 4 + call dword [fs_FloppyServices + eax*4] + and [flp_status], 0 + mov [esp+36], eax + mov [esp+24], ebx + ret + +fs_FloppyServices: + dd fs_FloppyRead + +fs_OnHd0: + call reserve_hd1 + mov [hdbase], 0x1F0 + mov [hdid], 0 + push 1 + jmp fs_OnHd +fs_OnHd1: + call reserve_hd1 + mov [hdbase], 0x1F0 + mov [hdid], 0x10 + push 2 + jmp fs_OnHd +fs_OnHd2: + call reserve_hd1 + mov [hdbase], 0x170 + mov [hdid], 0 + push 3 + jmp fs_OnHd +fs_OnHd3: + call reserve_hd1 + mov [hdbase], 0x170 + mov [hdid], 0x10 + push 4 +fs_OnHd: + pop eax + mov [hdpos], eax + cmp ecx, [0x40001+eax] + jbe @f + and [hd1_status], 0 + mov dword [esp+36], 5 ; not found + ret +@@: + mov [fat32part], ecx + push ebx esi + call choice_necessity_partition_1 + pop esi ebx + mov ecx, [ebx+12] + mov edx, [ebx+16] + add edx, std_application_base_address + movzx eax, byte [ebx] + add ebx, 4 + call dword [fs_HdServices + eax*4] + and [hd1_status], 0 + mov [esp+36], eax + mov [esp+24], ebx + ret + +fs_HdServices: + dd fs_HdRead