;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; RDOS operating system ; Copyright (C) 1988-2000, Leif Ekblad ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. The only exception to this rule ; is for commercial usage in embedded systems. For information on ; usage in commercial embedded systems, contact embedded@rdos.net ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ; ; The author of this program may be contacted at leif@rdos.net ; ; FAT.ASM ; FAT filesystem driver ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; NAME fat GateSize = 16 INCLUDE ..\os\driver.def INCLUDE ..\os\protseg.def INCLUDE ..\os\user.def INCLUDE ..\os\virt.def INCLUDE ..\os\os.def INCLUDE ..\os\user.inc INCLUDE ..\os\virt.inc INCLUDE ..\os\os.inc INCLUDE ..\os\system.def INCLUDE ..\os\system.inc INCLUDE ..\os\fs.inc INCLUDE fat.inc attr_read_only EQU 1 attr_hidden EQU 2 attr_system EQU 4 attr_volume EQU 8 attr_dir EQU 10h attr_arcive EQU 20h MAX_DRIVES EQU 'Z' -'A' + 1 extrn get_param:near extrn parse_dir:near extrn parse_file:near extrn insert_file_node:near extrn insert_dir_node:near extrn create_dir_handle:near extrn delete_dir_handle:near extrn open_file_handle:near extrn close_file_handle:near extrn remove_file_node:near extrn modify_file_entry:near extrn lock_dir_entry:near extrn update_dir_name:near extrn update_dir_time:near extrn update_dir_entry:near extrn set_dir_name:near extrn next_cluster:near extrn allocate_cluster:near extrn free_cluster:near extrn link_cluster:near extrn eof_cluster:near .386p code SEGMENT byte public use16 'CODE' assume cs:code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: MOUNT12 ; ; DESCRIPTION: Mount FAT12 on a drive ; ; RETRUNS: DS:SI ADDRESS TO DRIVE DATA ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mount12 PROC far push es ; push ax mov eax,SIZE drive_data_seg AllocateSmallGlobalMem mov ax,es mov ds,ax mov ax,flat_sel mov es,ax pop ax mov ds:fat_type,fat12 call get_param ; pop es ret mount12 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: MOUNT16 ; ; DESCRIPTION: Mount FAT16 on a drive ; ; RETRUNS: DS:SI ADDRESS TO DRIVE DATA ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mount16 PROC far push es ; push ax mov eax,SIZE drive_data_seg AllocateSmallGlobalMem mov ax,es mov ds,ax mov ax,flat_sel mov es,ax pop ax mov ds:fat_type,fat16 call get_param ; pop es ret mount16 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: MOUNT32 ; ; DESCRIPTION: Mount FAT32 on a drive ; ; RETRUNS: DS:SI ADDRESS TO DRIVE DATA ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mount32 PROC far push es ; push ax mov eax,SIZE drive_data_seg AllocateSmallGlobalMem mov ax,es mov ds,ax mov ax,flat_sel mov es,ax pop ax mov ds:fat_type,fat32 call get_param ; pop es ret mount32 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: DISMOUNT ; ; DESCRIPTION: Dismount filesystem ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; dismount PROC far ret dismount ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GET_DRIVE_INFO ; ; DESCRIPTION: Read info from drive ; ; RETURNS: EAX FREE UNITS ; CX BYTES / UNIT ; EDX TOTAL UNITS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_drive_info PROC far mov eax,ds:clusters mov cl,ds:fat_cluster_shift shl eax,cl mov edx,eax mov cx,200h clc ret get_drive_info ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: SET_CUR_DIR ; ; DESCRIPTION: Set current directory ; ; PARAMETERS: ES:EDI PATH NAME ; NC SUCCESS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; set_cur_dir PROC far push es push fs push edx ; mov dx,es mov gs,dx mov dx,flat_sel mov es,dx mov edx,edi ; call parse_dir mov al,gs:[edx] or al,al stc jne set_cur_dir_done mov dx,fs mov al,ds:drive_nr SetCurDirPtr clc set_cur_dir_done: pop edx pop fs pop es ret set_cur_dir ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GET_CUR_DIR ; ; DESCRIPTION: Get current directory ; ; PARAMETERS: ES:EDI PATH NAME ; AL DRIVE ; NC SUCCESS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_cur_dir PROC far push es push fs push ecx push edx push edi ; mov dx,es mov gs,dx mov dx,flat_sel mov es,dx mov edx,edi ; xor ecx,ecx mov byte ptr gs:[edx],0 ; push edx GetCurDirPtr mov fs,dx or dx,dx pop edx je get_cur_dir_done get_cur_dir_loop: mov ax,fs:dir_parent or ax,ax je get_cur_dir_done mov edi,fs:dir_parent_entry mov fs,ax push ds push es mov ax,gs mov es,ax mov ax,flat_sel mov ds,ax ; push ecx push esi push edi movzx eax,[edi].dir_name_size mov esi,edx mov edi,edx add edi,eax add esi,ecx add edi,ecx dec esi std rep movs byte ptr es:[edi],es:[esi] cld pop edi pop esi pop ecx add ecx,eax inc ecx ; push ecx push edi mov esi,edi mov edi,edx add esi,OFFSET dir_name mov ecx,eax mov al,es:[edi] rep movs byte ptr es:[edi],[esi] or al,al je get_cur_dir_no_slash mov al,'\' get_cur_dir_no_slash: stos byte ptr es:[edi] pop edi pop ecx ; pop es pop ds jmp get_cur_dir_loop get_cur_dir_done: clc ; pop edi pop edx pop ecx pop fs pop es ret get_cur_dir ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: MAKE_DIR ; ; DESCRIPTION: Create directory ; ; PARAMETERS: ES:EDI DIRECTORY NAME ; NC SUCCESS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; make_dir PROC far push es push fs push ax push ebx push edx push esi push edi ; mov dx,es mov gs,dx mov dx,flat_sel mov es,dx mov edx,edi ; call parse_dir mov al,gs:[edx] or al,al stc je make_dir_done call insert_dir_node jc make_dir_done call update_dir_name call update_dir_time ModifySector call create_dir_handle clc make_dir_done: pop edi pop esi pop edx pop ebx pop ax pop fs pop es ret make_dir ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: REMOVE_DIR ; ; DESCRIPTION: Remove directory ; ; PARAMETERS: ES:EDI DIRECTORY NAME ; NC SUCCESS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; remove_dir PROC far push es push fs push edx ; mov dx,es mov gs,dx mov dx,flat_sel mov es,dx mov edx,edi ; call parse_dir mov al,gs:[edx] or al,al stc jne remove_dir_done call delete_dir_handle remove_dir_done: pop edx pop fs pop es ret remove_dir ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: DELETE_FILE ; ; DESCRIPTION: Delete file ; ; PARAMETERS: ES:EDI FILE NAME ; NC SUCCESS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; delete_file PROC far push es push fs push ecx push edx push edi ; mov dx,es mov gs,dx mov dx,flat_sel mov es,dx mov edx,edi ; call parse_dir call parse_file jc delete_file_done push fs call open_file_handle mov fs,bx xor ecx,ecx call update_file_clusters pop fs call remove_file_node clc delete_file_done: pop edi pop edx pop ecx pop fs pop es ret delete_file ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: RENAME_FILE ; ; DESCRIPTION: Rename file ; ; PARAMETERS: FS:EBX CURRENT NAME ; ES:EDI NEW NAME ; NC SUCCESS ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; rename_file PROC far push fs push es push eax push ebx push cx push edx push esi push edi ; push es push edi mov dx,fs mov gs,dx mov dx,flat_sel mov es,dx mov edx,ebx ; call parse_dir call parse_file mov eax,edi pop edi pop es jc rename_file_done ; push eax mov dx,es mov gs,dx mov dx,flat_sel mov es,dx mov edx,edi ; mov cx,fs call parse_dir mov al,gs:[edx] or al,al je rename_dest_fail mov ax,fs cmp ax,cx jne rename_dest_fail call parse_file jnc rename_dest_fail pop edi call lock_dir_entry call set_dir_name ModifySector UnlockSector clc jmp rename_file_done rename_dest_fail: pop edi stc rename_file_done: pop edi pop esi pop edx pop cx pop ebx pop eax pop es pop fs ret rename_file ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GET_FILE_ATTRIB ; ; DESCRIPTION: Get file attribute ; ; PARAMETERS: ES:EDI FILENAME ; NC SUCCESS ; CX FILE ATTRIBUTE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_file_attrib PROC far push es push fs push ebx push edx push esi push edi ; mov dx,es mov gs,dx mov dx,flat_sel mov es,dx mov edx,edi ; call parse_dir mov al,gs:[edx] or al,al jne get_file_attrib_not_dir mov cx,10h clc jmp set_file_attrib_done get_file_attrib_not_dir: call parse_file jc get_file_attrib_done movzx cx,es:[edi].dir_attrib clc get_file_attrib_done: pop edi pop esi pop edx pop ebx pop fs pop es ret get_file_attrib ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: SET_FILE_ATTRIB ; ; DESCRIPTION: Set file attribute ; ; PARAMETERS: ES:EDI FILENAME ; NC SUCCESS ; CX FILE ATTRIBUTE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; set_file_attrib PROC far push es push fs push ebx push edx push esi push edi ; mov dx,es mov gs,dx mov dx,flat_sel mov es,dx mov edx,edi ; call parse_dir mov al,gs:[edx] or al,al jne set_file_attrib_not_dir test cl,10h clc jnz set_file_attrib_done stc jmp set_file_attrib_done set_file_attrib_not_dir: call parse_file jc set_file_attrib_done test cl,10h stc jnz set_file_attrib_done mov es:[edi].dir_attrib,cl call lock_dir_entry call update_dir_entry ModifySector UnlockSector clc set_file_attrib_done: pop edi pop esi pop edx pop ebx pop fs pop es ret set_file_attrib ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: OPEN_DIR ; ; DESCRIPTION: Open directory search ; ; PARAMETERS: ES:EDI PATH NAME ; NC SUCCESS ; ; RETURNS: BX HANDLE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; open_dir PROC far push es push fs push ax push edx ; mov dx,es mov gs,dx mov dx,flat_sel mov es,dx mov edx,edi ; call parse_dir mov al,gs:[edx] or al,al stc jne open_dir_done inc fs:dir_usage mov bx,fs clc open_dir_done: ; pop edx pop ax pop fs pop es ret open_dir ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: CLOSE_DIR ; ; DESCRIPTION: Close directory search ; ; PARAMETERS: BX HANDLE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; close_dir PROC far push fs mov fs,bx dec fs:dir_usage clc pop fs ret close_dir ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: READ_DIR ; ; DESCRIPTION: Read directory entry ; ; PARAMETERS: BX HANDLE ; DX ENTRY # ; CX MAX SIZE OF FILENAME ; ES:EDI FILENAME BUFFER ; RETURNS: ECX FILE SIZE ; BX FILE ATTRIBUTE ; EDX:EAX FILE TIME/DATE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; read_dir PROC far push fs push esi push ebp ; push es push edi ; mov ax,flat_sel mov es,ax mov fs,bx ; mov edi,fs:dir_dir_ptr or edi,edi jz read_file_start read_dir_entries: or dx,dx jz read_dir_ok dec dx mov edi,es:[edi].dir_next cmp edi,fs:dir_dir_ptr jne read_dir_entries read_file_start: mov edi,fs:dir_file_ptr or edi,edi jz read_dir_fail read_file_entries: or dx,dx jz read_dir_ok dec dx mov edi,es:[edi].dir_next cmp edi,fs:dir_file_ptr jne read_file_entries jmp read_dir_fail read_dir_ok: movzx ax,es:[edi].dir_name_size cmp ax,cx jnc read_dir_size_ok mov cx,ax read_dir_size_ok: movzx ecx,cx mov esi,edi mov ax,flat_sel mov ds,ax mov ebp,es:[edi].dir_file_size movzx bx,es:[edi].dir_attrib mov edx,es:[edi].dir_time+4 mov eax,es:[edi].dir_time pop edi pop es ; add esi,OFFSET dir_name rep movs byte ptr es:[edi],[esi] push ax xor al,al stos byte ptr es:[edi] pop ax mov ecx,ebp clc jmp read_dir_done read_dir_fail: stc pop edi pop es read_dir_done: pop ebp pop esi pop fs ret read_dir ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: OPEN_FILE ; ; DESCRIPTION: Open a file ; ; PARAMETERS: ES:EDI FILENAME ; CL ACCESS MODE ; ; RETURNS: BX HANDLE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; open_file PROC far push es push fs push edx push edi ; mov dx,es mov gs,dx mov dx,flat_sel mov es,dx mov edx,edi ; call parse_dir call parse_file jc open_file_fail call open_file_handle clc open_file_fail: pop edi pop edx pop fs pop es ret open_file ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: CREATE_FILE ; ; DESCRIPTION: Create a file ; ; PARAMETERS: ES:EDI FILENAME ; CX FILE ATTRIBUTE ; ; RETURNS: BX HANDLE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; create_file PROC far push es push fs push edx push edi ; mov dx,es mov gs,dx mov dx,flat_sel mov es,dx mov edx,edi ; call parse_dir call parse_file jc create_file_non_exist ; call open_file_handle push ecx push fs mov fs,bx xor ecx,ecx call update_file_clusters mov edi,fs:file_dir_entry pop fs call modify_file_entry pop ecx clc jmp create_file_done create_file_non_exist: call insert_file_node jc create_file_done call open_file_handle clc create_file_done: pop edi pop edx pop fs pop es ret create_file ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: CLOSE_FILE ; ; DESCRIPTION: Close a file ; ; PARAMETERS: BX HANDLE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; close_file PROC far push es push ax mov ax,flat_sel mov es,ax call close_file_handle pop ax pop es ret close_file ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GET_IOCTL_DATA ; ; DESCRIPTION: Get IOCTL data ; ; PARAMETERS: BX HANDLE ; ; RETURNS: DX IOCTL_DATA ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_ioctl_data PROC far movzx dx,al or dx,40h ret get_ioctl_data ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GET_FILE_SIZE ; ; DESCRIPTION: Get file size ; ; PARAMETERS: BX Handle ; ; RETURNS: EDX FILE SIZE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_file_size PROC far push es push fs push ax mov ax,flat_sel mov es,ax mov fs,bx mov edx,fs:file_dir_entry mov edx,es:[edx].dir_file_size clc pop ax pop fs pop es ret get_file_size ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GROW_FILE ; ; DESCRIPTION: Increase file size ; ; PARAMETERS: FS File selector ; ESI Current size of file ; EDI Wanted size of file ; EBP Cluster size ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; grow_file Proc near push eax push ebx push ecx push edx ; push esi or esi,esi jne grow_file_do ; mov al,ds:drive_nr call allocate_cluster jc grow_file_fail ; push edx mov bx,fs xor edx,edx GetFileListEntry pop edx ; mov es:[eax].ffl_clusters,edx mov ecx,fs:file_dir_entry mov es:[ecx].dir_cluster,edx add esi,ebp cmp esi,edi clc je grow_file_cluster_done grow_file_do: sub esi,ebp sub edi,ebp push edx mov bx,fs mov edx,esi GetFileListEntry pop edx ; lea ebx,[eax].ffl_clusters mov ecx,esi mov eax,fs:file_block_size dec eax and eax,ecx mov cl,ds:fat_cluster_shift add cl,9 shr eax,cl shl eax,2 add ebx,eax grow_file_loop: mov al,ds:drive_nr call allocate_cluster jc grow_file_fail ; mov ecx,edx mov edx,es:[ebx] call link_cluster add ebx,4 mov es:[ebx],ecx add esi,ebp cmp esi,edi clc je grow_file_cluster_done ; mov eax,fs:file_block_size dec eax and eax,esi jnz grow_file_loop ; mov edx,es:[ebx] push edx mov bx,fs mov edx,esi GetFileListEntry pop edx lea ebx,[eax].ffl_clusters mov es:[ebx],edx jmp grow_file_loop grow_file_cluster_done: mov eax,fs:file_block_size dec eax and eax,esi jnz grow_file_lock ; mov edx,es:[ebx] push edx mov bx,fs mov edx,esi GetFileListEntry pop edx lea ebx,[eax].ffl_clusters mov es:[ebx],edx grow_file_lock: pop esi mov ebx,esi grow_list_loop: cmp ebx,fs:file_size ja grow_file_done ; push bx push edx mov edx,ebx mov bx,fs GetFileListEntry pop edx pop bx mov edi,eax ; lea ebp,[eax].ffl_clusters mov eax,fs:file_block_size dec eax and eax,ebx mov cl,ds:fat_cluster_shift add cl,9 shr eax,cl shl eax,2 add ebp,eax ; mov esi,es:[edi].fl_base or esi,esi jnz grow_lock_valid ; push edx mov eax,fs:file_block_size AllocateBigLinear mov esi,edx pop edx mov es:[edi].fl_base,esi grow_lock_valid: mov eax,fs:file_block_size dec eax and eax,ebx add esi,eax ; mov edi,es:[edi].ffl_sector_ptr shr eax,9 shl eax,2 add edi,eax grow_lock_loop: cmp ebx,fs:file_size ja grow_file_done ; mov edx,es:[ebp] sub edx,2 mov eax,1 mov cl,ds:fat_cluster_shift shl edx,cl shl eax,cl mov ecx,eax add edx,ds:start_sector grow_cluster_loop: push ebx mov ebx,es:[edi] cmp ebx,-1 je grow_define_sector ; or ebx,ebx jnz grow_cluster_next grow_define_sector: mov al,ds:drive_nr DefineSector mov es:[edi],ebx grow_cluster_next: pop ebx add edi,4 inc edx add esi,200h add ebx,200h loop grow_cluster_loop ; add ebp,4 mov eax,fs:file_block_size dec eax and eax,ebx jnz grow_lock_loop jmp grow_list_loop grow_file_fail: pop esi grow_file_done: pop edx pop ecx pop ebx pop eax ret grow_file Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: SHRINK_FILE ; ; DESCRIPTION: Decrease size of file ; ; PARAMETERS: FS File selector ; ESI Current file size ; EDI Wanted file size ; EBP Cluster size ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; shrink_file Proc near push eax push ebx push ecx push edx ; push esi push edi shrink_file_unlock: mov ebx,edi shrink_list_loop: cmp ebx,esi ja shrink_file_free ; push bx push edx mov edx,ebx mov bx,fs GetFileListEntry pop edx pop bx mov edi,eax ; mov edi,es:[edi].ffl_sector_ptr mov eax,fs:file_block_size dec eax and eax,ebx shr eax,9 add edi,eax shrink_unlock_loop: cmp ebx,esi je shrink_file_free ; mov eax,1 mov cl,ds:fat_cluster_shift shl eax,cl mov ecx,eax shrink_cluster_loop: push ebx mov ebx,es:[edi] cmp ebx,-1 je shrink_cluster_next ; or ebx,ebx jz shrink_cluster_next ; UnlockSector shrink_cluster_next: mov dword ptr es:[edi],0 pop ebx add edi,4 inc edx add ebx,200h loop shrink_cluster_loop ; mov eax,fs:file_block_size dec eax and eax,ebx jnz shrink_unlock_loop jmp shrink_list_loop shrink_file_free: pop edi pop esi sub esi,ebp shrink_file_list_loop: mov bx,fs mov edx,esi GetFileListEntry ; lea ebx,[eax].ffl_clusters mov eax,fs:file_block_size dec eax and eax,esi mov cl,ds:fat_cluster_shift add cl,9 shr eax,cl shl eax,2 add ebx,eax shrink_file_loop: mov edx,es:[ebx] mov al,ds:drive_nr call free_cluster mov dword ptr es:[ebx],0 ; mov eax,fs:file_block_size dec eax and eax,esi sub ebx,4 sub esi,ebp jc shrink_file_zero ; cmp esi,edi jc shrink_file_mark_end ; or eax,eax jnz shrink_file_loop ; mov edx,esi add edx,ebp mov bx,fs push edi GetFileListEntry mov edi,eax FreeFileListEntry pop edi jmp shrink_file_list_loop shrink_file_mark_end: or eax,eax jnz shrink_mark_do ; mov edx,esi add edx,ebp mov bx,fs push edi GetFileListEntry mov edi,eax FreeFileListEntry pop edi ; mov bx,fs mov edx,esi GetFileListEntry ; lea ebx,[eax].ffl_clusters mov eax,fs:file_block_size dec eax and eax,esi mov cl,ds:fat_cluster_shift add cl,9 shr eax,cl shl eax,2 add ebx,eax shrink_mark_do: mov edx,es:[ebx] mov al,ds:drive_nr call eof_cluster jmp shrink_file_done shrink_file_zero: mov eax,fs:file_dir_entry mov es:[eax].dir_cluster,0 shrink_file_done: pop edx pop ecx pop ebx pop eax ret shrink_file Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: UPDATE_FILE_CLUSTERS ; ; DESCRIPTION: Update number of clusters in file ; ; PARAMETERS: FS File selector ; ECX New file size ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; update_file_clusters PROC near push eax push edx push esi push edi push ebp ; push ecx mov edi,fs:file_dir_entry mov esi,es:[edi].dir_file_size mov edi,ecx mov eax,200h mov cl,ds:fat_cluster_shift shl eax,cl mov ebp,eax neg eax dec esi and esi,eax dec edi and edi,eax add esi,ebp add edi,ebp mov edx,fs:file_size or edx,edx jz update_file_cluster_ok ; mov edx,esi sub edx,ebp call get_file_cluster ; push ebx push esi push edi ; mov bx,fs GetFileListEntry mov edi,eax ; lea esi,[edi].ffl_clusters mov eax,fs:file_block_size neg eax mov ebx,edx and ebx,eax neg eax mov cl,ds:fat_cluster_shift add cl,9 shr eax,cl mov ecx,eax update_req_loop: cmp ebx,fs:file_size ja update_req_done ; mov edx,es:[esi] or edx,edx jnz update_req_next ; mov edx,es:[esi-4] mov al,fs:file_drive call next_cluster mov es:[esi],edx update_req_next: add ebx,ebp add esi,4 loop update_req_loop update_req_done: pop edi pop esi pop ebx update_file_cluster_ok: pop ecx cmp edi,esi je update_file_equal jc update_file_shrink update_file_grow: mov fs:file_size,ecx call grow_file jmp update_file_done update_file_shrink: call shrink_file mov fs:file_size,ecx jmp update_file_done update_file_equal: mov fs:file_size,ecx update_file_done: mov edx,fs:file_dir_entry mov es:[edx].dir_file_size,ecx clc ; pop ebp pop edi pop esi pop edx pop eax ret update_file_clusters ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: SET_FILE_SIZE ; ; DESCRIPTION: Set file size ; ; PARAMETERS: BX HANDLE ; EDX FILE SIZE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; set_file_size PROC far push es push fs push ecx push edi ; mov cx,flat_sel mov es,cx mov fs,bx mov ecx,edx call update_file_clusters jc set_file_size_done ; mov edi,fs:file_dir_entry call modify_file_entry clc set_file_size_done: pop edi pop ecx pop fs pop es ret set_file_size ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GET_FILE_TIME ; ; DESCRIPTION: Get file time ; ; PARAMETERS: BX HANDLE ; ; RETURNS: EDX:ECX FILE TIME ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_file_time PROC far push es push fs push ax mov ax,flat_sel mov es,ax mov fs,bx mov edx,fs:file_dir_entry mov ecx,es:[edx].dir_time mov edx,es:[edx].dir_time+4 clc pop ax pop fs pop es ret get_file_time ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: SET_FILE_TIME ; ; DESCRIPTION: Set file time ; ; PARAMETERS: BX HANDLE ; EDX:ECX FILE TIME ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; set_file_time PROC far push es push fs push ax push ebx push esi push edi mov ax,flat_sel mov es,ax mov fs,bx mov edi,fs:file_dir_entry mov es:[edi].dir_time,ecx mov es:[edi].dir_time+4,edx call lock_dir_entry call update_dir_time ModifySector UnlockSector clc pop edi pop esi pop ebx pop ax pop fs pop es stc ret set_file_time ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: ALLOCATE_FILE_LIST ; ; DESCRIPTION: Allocate file list block ; ; PARAMETERS: BX File handle ; ; RETURNS: EDI Linear address of file list block ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; allocate_file_list PROC far push es push fs push eax push ecx push edx ; mov ax,flat_sel mov es,ax mov fs,bx ; mov cl,fs:file_entry_shift sub cl,9 mov edx,4 shl edx,cl mov eax,4 sub cl,ds:fat_cluster_shift shl eax,cl add eax,edx add eax,SIZE fat_file_list_struc + 4 AllocateSmallLinear mov edi,edx ; mov eax,1 shl eax,cl inc eax mov ecx,eax xor eax,eax push edi add edi,OFFSET ffl_clusters rep stos dword ptr es:[edi] mov edx,edi pop edi ; mov es:[edi].ffl_sector_ptr,edx mov cl,fs:file_entry_shift sub cl,9 mov eax,1 shl eax,cl mov ecx,eax xor eax,eax push edi mov edi,edx rep stos dword ptr es:[edi] pop edi ; pop edx pop ecx pop eax pop fs pop es ret allocate_file_list ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: free_file_list ; ; DESCRIPTION: Free file list ; ; PARAMETERS: EDI Linear address ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; free_file_list PROC far push es push fs push eax push ebx push ecx push edx ; mov ax,flat_sel mov es,ax mov fs,bx ; mov edx,es:[edi].ffl_sector_ptr mov cl,fs:file_entry_shift sub cl,9 mov eax,1 shl eax,cl mov ecx,eax file_list_unlock_loop: mov ebx,es:[edx] cmp ebx,-1 je file_list_unlock_next ; or ebx,ebx jz file_list_unlock_next ; UnlockSector file_list_unlock_next: add edx,4 loop file_list_unlock_loop ; mov ecx,edx mov edx,edi FreeLinear ; pop edx pop ecx pop ebx pop eax pop fs pop es clc ret free_file_list ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: get_file_cluster ; ; DESCRIPTION: Get cluster of file ; ; PARAMETERS: FS FILE HANDLE ; EDX POSITION ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_file_cluster Proc near pushad ; mov ebx,fs:file_block_size neg ebx and edx,ebx mov ebx,edx mov ebp,edx mov edi,fs:file_dir_entry mov edx,es:[edi].dir_cluster or ebp,ebp jz get_cluster_loop get_cluster_scan: mov edx,es:[edi].dir_cluster sub ebp,fs:file_block_size jz get_cluster_loop ; push bx push edx mov bx,fs mov edx,ebp GetFileListEntry pop edx pop bx mov edx,es:[eax].ffl_clusters or edx,edx jz get_cluster_scan ; lea eax,[eax].ffl_clusters+4 mov esi,200h mov cl,ds:fat_cluster_shift shl esi,cl mov ecx,edx mov edi,fs:file_block_size advance_cluster_loop: mov edx,es:[eax] or edx,edx jnz advance_cluster_next ; mov edx,ecx push ax mov al,fs:file_drive call next_cluster pop ax mov es:[eax],edx advance_cluster_next: mov ecx,edx add eax,4 sub edi,esi jnz advance_cluster_loop ; add ebp,fs:file_block_size get_cluster_loop: push bx push edx mov bx,fs mov edx,ebp GetFileListEntry pop edx pop bx mov es:[eax].ffl_clusters,edx get_cluster_check: cmp ebx,ebp je get_cluster_done ; lea eax,[eax].ffl_clusters+4 mov esi,200h mov cl,ds:fat_cluster_shift shl esi,cl mov edi,fs:file_block_size get_file_cluster_loop: mov edx,es:[eax] or edx,edx jnz get_file_cluster_next ; mov edx,es:[eax-4] push ax mov al,fs:file_drive call next_cluster pop ax mov es:[eax],edx get_file_cluster_next: add ebp,esi add eax,4 cmp ebp,fs:file_size jnc get_cluster_done ; sub edi,esi jnz get_file_cluster_loop ; jmp get_cluster_loop get_cluster_done: popad ret get_file_cluster Endp PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: READ_FILE_BLOCK ; ; DESCRIPTION: Read file block ; ; PARAMETERS: BX FILE HANDLE ; ECX BYTES TO READ ; EDX POSITION ; EDI FILE LIST ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; read_file_block PROC far push es push fs pushad ; mov fs,bx mov ax,flat_sel mov es,ax ; mov eax,fs:file_size sub eax,edx cmp eax,ecx jnc read_file_inrange ; mov ecx,eax read_file_inrange: mov eax,es:[edi].ffl_clusters or eax,eax jnz read_file_do ; call get_file_cluster read_file_do: push edi ; mov esi,es:[edi].fl_base lea ebp,[edi].ffl_clusters mov edi,es:[edi].ffl_sector_ptr mov eax,fs:file_block_size mov cl,ds:fat_cluster_shift add cl,9 shr eax,cl mov ecx,eax mov ebx,edx read_req_loop: cmp ebx,fs:file_size ja read_file_wait ; mov edx,es:[ebp] or edx,edx jnz read_file_req_cluster ; mov edx,es:[ebp-4] mov al,fs:file_drive call next_cluster mov es:[ebp],edx read_file_req_cluster: push ecx sub edx,2 mov eax,1 mov cl,ds:fat_cluster_shift shl edx,cl shl eax,cl mov ecx,eax add edx,ds:start_sector read_cluster_loop: push ebx mov ebx,es:[edi] or ebx,ebx jnz read_cluster_next ; mov al,ds:drive_nr ReqSector mov es:[edi],ebx read_cluster_next: pop ebx add edi,4 inc edx add esi,200h add ebx,200h loop read_cluster_loop ; add ebp,4 pop ecx loop read_req_loop read_file_wait: mov esi,edi pop edi read_wait_loop: sub esi,4 mov ebx,es:[esi] cmp ebx,-1 je read_wait_next ; WaitForSector UnlockSector mov dword ptr es:[esi],-1 read_wait_next: cmp esi,es:[edi].ffl_sector_ptr jne read_wait_loop read_file_done: popad clc pop fs pop es ret read_file_block ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: WRITE_FILE_BLOCK ; ; DESCRIPTION: Write file block ; ; PARAMETERS: BX HANDLE TO DEVICE ; ECX NUMBER OF BYTES TO WRITE ; EDX POSITION ; EDI FILE LIST ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; write_file_block PROC far push es push fs pushad ; mov fs,bx mov ax,flat_sel mov es,ax ; mov eax,fs:file_size sub eax,edx cmp eax,ecx jnc write_file_inrange ; mov ecx,eax write_file_inrange: mov eax,es:[edi].ffl_clusters or eax,eax jnz write_file_do ; call get_file_cluster write_file_do: mov esi,es:[edi].fl_base lea ebp,[edi].ffl_clusters mov edi,es:[edi].ffl_sector_ptr mov ebx,ecx add ebx,edx dec ebx mov eax,1 mov cl,9 add cl,ds:fat_cluster_shift shl eax,cl neg eax and edx,eax and ebx,eax neg eax add ebx,eax sub ebx,edx shr ebx,cl push ebx ; mov eax,fs:file_block_size dec eax mov ebx,edx and edx,eax and eax,ebx add esi,eax ; shr edx,cl shl edx,2 add ebp,edx ; mov cl,ds:fat_cluster_shift shl edx,cl add edi,edx pop ecx write_req_loop: cmp ebx,fs:file_size ja write_file_done ; mov edx,es:[ebp] or edx,edx jnz write_cluster_ok ; mov edx,es:[ebp-4] mov al,fs:file_drive call next_cluster mov es:[ebp],edx write_cluster_ok: push ecx sub edx,2 mov eax,1 mov cl,ds:fat_cluster_shift shl edx,cl shl eax,cl mov ecx,eax add edx,ds:start_sector write_cluster_loop: push ebx mov ebx,es:[edi] cmp ebx,-1 je write_cluster_define ; or ebx,ebx jnz write_cluster_next write_cluster_define: mov al,ds:drive_nr DefineSector write_cluster_next: ModifySector UnlockSector mov dword ptr es:[edi],-1 ; pop ebx add edi,4 inc edx add esi,200h add ebx,200h loop write_cluster_loop ; add ebp,4 pop ecx sub cx,1 jnz write_req_loop write_file_done: popad clc pop fs pop es ret write_file_block ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: init ; ; DESCRIPTION: init device ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; dummy Proc far stc ret dummy Endp fs12_name DB 'FAT12',0 fs12_ctrl: f12s00 DW OFFSET mount12, fat_code_sel f12s01 DW OFFSET dismount, fat_code_sel f12s02 DW OFFSET get_drive_info, fat_code_sel f12s03 DW OFFSET set_cur_dir, fat_code_sel f12s04 DW OFFSET get_cur_dir, fat_code_sel f12s05 DW OFFSET make_dir, fat_code_sel f12s06 DW OFFSET remove_dir, fat_code_sel f12s07 DW OFFSET delete_file, fat_code_sel f12s08 DW OFFSET rename_file, fat_code_sel f12s09 DW OFFSET get_file_attrib, fat_code_sel f12s10 DW OFFSET set_file_attrib, fat_code_sel f12s11 DW OFFSET open_dir, fat_code_sel f12s12 DW OFFSET close_dir, fat_code_sel f12s13 DW OFFSET read_dir, fat_code_sel f12s14 DW OFFSET open_file, fat_code_sel f12s15 DW OFFSET create_file, fat_code_sel f12s16 DW OFFSET close_file, fat_code_sel f12s17 DW OFFSET get_ioctl_data, fat_code_sel f12s18 DW OFFSET get_file_size, fat_code_sel f12s19 DW OFFSET set_file_size, fat_code_sel f12s20 DW OFFSET get_file_time, fat_code_sel f12s21 DW OFFSET set_file_time, fat_code_sel f12s22 DW OFFSET dummy, fat_code_sel f12s23 DW OFFSET dummy, fat_code_sel f12s24 DW OFFSET allocate_file_list,fat_code_sel f12s25 DW OFFSET free_file_list, fat_code_sel f12s26 DW OFFSET read_file_block, fat_code_sel f12s27 DW OFFSET write_file_block, fat_code_sel fs16_name DB 'FAT16',0 fs16_ctrl: f16s00 DW OFFSET mount16, fat_code_sel f16s01 DW OFFSET dismount, fat_code_sel f16s02 DW OFFSET get_drive_info, fat_code_sel f16s03 DW OFFSET set_cur_dir, fat_code_sel f16s04 DW OFFSET get_cur_dir, fat_code_sel f16s05 DW OFFSET make_dir, fat_code_sel f16s06 DW OFFSET remove_dir, fat_code_sel f16s07 DW OFFSET delete_file, fat_code_sel f16s08 DW OFFSET rename_file, fat_code_sel f16s09 DW OFFSET get_file_attrib, fat_code_sel f16s10 DW OFFSET set_file_attrib, fat_code_sel f16s11 DW OFFSET open_dir, fat_code_sel f16s12 DW OFFSET close_dir, fat_code_sel f16s13 DW OFFSET read_dir, fat_code_sel f16s14 DW OFFSET open_file, fat_code_sel f16s15 DW OFFSET create_file, fat_code_sel f16s16 DW OFFSET close_file, fat_code_sel f16s17 DW OFFSET get_ioctl_data, fat_code_sel f16s18 DW OFFSET get_file_size, fat_code_sel f16s19 DW OFFSET set_file_size, fat_code_sel f16s20 DW OFFSET get_file_time, fat_code_sel f16s21 DW OFFSET set_file_time, fat_code_sel f16s22 DW OFFSET dummy, fat_code_sel f16s23 DW OFFSET dummy, fat_code_sel f16s24 DW OFFSET allocate_file_list,fat_code_sel f16s25 DW OFFSET free_file_list, fat_code_sel f16s26 DW OFFSET read_file_block, fat_code_sel f16s27 DW OFFSET write_file_block, fat_code_sel fs32_name DB 'FAT32',0 fs32_ctrl: f32s00 DW OFFSET mount32, fat_code_sel f32s01 DW OFFSET dismount, fat_code_sel f32s02 DW OFFSET get_drive_info, fat_code_sel f32s03 DW OFFSET set_cur_dir, fat_code_sel f32s04 DW OFFSET get_cur_dir, fat_code_sel f32s05 DW OFFSET make_dir, fat_code_sel f32s06 DW OFFSET remove_dir, fat_code_sel f32s07 DW OFFSET delete_file, fat_code_sel f32s08 DW OFFSET rename_file, fat_code_sel f32s09 DW OFFSET get_file_attrib, fat_code_sel f32s10 DW OFFSET set_file_attrib, fat_code_sel f32s11 DW OFFSET open_dir, fat_code_sel f32s12 DW OFFSET close_dir, fat_code_sel f32s13 DW OFFSET read_dir, fat_code_sel f32s14 DW OFFSET open_file, fat_code_sel f32s15 DW OFFSET create_file, fat_code_sel f32s16 DW OFFSET close_file, fat_code_sel f32s17 DW OFFSET get_ioctl_data, fat_code_sel f32s18 DW OFFSET get_file_size, fat_code_sel f32s19 DW OFFSET set_file_size, fat_code_sel f32s20 DW OFFSET get_file_time, fat_code_sel f32s21 DW OFFSET set_file_time, fat_code_sel f32s22 DW OFFSET dummy, fat_code_sel f32s23 DW OFFSET dummy, fat_code_sel f32s24 DW OFFSET allocate_file_list,fat_code_sel f32s25 DW OFFSET free_file_list, fat_code_sel f32s26 DW OFFSET read_file_block, fat_code_sel f32s27 DW OFFSET write_file_block, fat_code_sel init PROC far push ds push es push fs push gs pushad mov bx,fat_code_sel InitDevice ; mov ax,cs mov ds,ax mov es,ax ; mov si,OFFSET fs12_name mov di,OFFSET fs12_ctrl RegisterFileSystem ; mov si,OFFSET fs16_name mov di,OFFSET fs16_ctrl RegisterFileSystem ; mov si,OFFSET fs32_name mov di,OFFSET fs32_ctrl RegisterFileSystem ; popad pop gs pop fs pop es pop ds ret init ENDP code ENDS END init