;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 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 ; ; FATTAB.ASM ; FAT allocation chain support ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INCLUDE ..\user.def INCLUDE ..\os.def INCLUDE ..\user.inc INCLUDE ..\os.inc INCLUDE ..\fs.inc INCLUDE fat.inc extrn lock_sector:near .386p code SEGMENT byte public use16 'CODE' assume cs:code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: LOCK_FAT ; ; DESCRIPTION: Lock first or second FAT sector, whichever is successful ; ; PARAMETERS: AL Drive ; EDX Sector # of first FAT ; ; RETURNS: EBX Handle ; ESI Linear address ; NC OK ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; lock_fat PROC near call lock_sector jnc lock_fat_done push edx sub edx,ds:fat1_sector add edx,ds:fat2_sector call lock_sector pop edx jnc lock_fat_done xor ebx,ebx stc lock_fat_done: ret lock_fat Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: UPDATE_CLUSTER_LINK12 ; ; DESCRIPTION: Update cluster link for FAT12 ; ; PARAMETERS: AL Drive ; EDX Cluster # ; ECX Next cluster ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; update_cluster_link12 PROC near push ebx push ecx push edx push esi push di ; cmp edx,ds:clusters cmc jc update_cluster_link_done2 ; push ecx mov ecx,edx add edx,edx add edx,ecx mov ecx,edx shr edx,10 add edx,ds:fat1_sector and cx,3FFh mov di,cx clc rcr cx,1 pushf call lock_sector jnc update_cluster_link_low1 popf pop ecx push edx jmp update_cluster_link_done1 update_cluster_link_low1: or si,cx popf pop ecx push edx jc update_cluster_link_high1 mov es:[esi],cl inc si test si,1FFh jnz update_cluster_link_low_ok1 ModifySector UnlockSector inc edx call lock_sector jc update_cluster_link_done1 update_cluster_link_low_ok1: push ax mov al,es:[esi] and al,0F0h or al,ch mov es:[esi],al pop ax jmp update_cluster_link_ok1 update_cluster_link_high1: push cx push ax ror cx,4 mov al,es:[esi] and al,0Fh or al,ch mov es:[esi],al pop ax inc si test si,1FFh jnz update_cluster_link_high_ok1 ModifySector UnlockSector inc edx call lock_sector jnc update_cluster_link_high_ok1 pop cx jmp update_cluster_link_done1 update_cluster_link_high_ok1: mov es:[esi],cl pop cx update_cluster_link_ok1: ModifySector UnlockSector update_cluster_link_done1: pop edx push cx sub edx,ds:fat1_sector add edx,ds:fat2_sector mov cx,di clc rcr cx,1 pushf call lock_sector jnc update_cluster_link_low2 popf pop cx jmp update_cluster_link_done2 update_cluster_link_low2: or si,cx popf pop cx jc update_cluster_link_high2 mov es:[esi],cl inc si test si,1FFh jnz update_cluster_link_low_ok2 ModifySector UnlockSector inc edx call lock_sector jc update_cluster_link_done2 update_cluster_link_low_ok2: push ax mov al,es:[esi] and al,0F0h or al,ch mov es:[esi],al pop ax jmp update_cluster_link_ok2 update_cluster_link_high2: push cx push ax ror cx,4 mov al,es:[esi] and al,0Fh or al,ch mov es:[esi],al pop ax inc si test si,1FFh jnz update_cluster_link_high_ok2 ModifySector UnlockSector inc edx call lock_sector jnc update_cluster_link_high_ok2 pop cx jmp update_cluster_link_done2 update_cluster_link_high_ok2: mov es:[esi],cl pop cx update_cluster_link_ok2: ModifySector UnlockSector update_cluster_link_done2: ; pop di pop esi pop edx pop ecx pop ebx ret update_cluster_link12 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: UPDATE_CLUSTER_LINK16 ; ; DESCRIPTION: Update cluster link for FAT16 ; ; PARAMETERS: AL Drive ; EDX Cluster # ; ECX Next cluster ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; update_cluster_link16 PROC near push ebx push ecx push edx push esi push di ; cmp edx,ds:clusters cmc jc update_cluster_link16_done mov di,cx movzx edx,dx add edx,edx mov cx,dx shr edx,9 add edx,ds:fat1_sector and cx,1FFh call lock_sector jc update_cluster_link16_fat2 or si,cx mov es:[esi],di ModifySector UnlockSector update_cluster_link16_fat2: sub edx,ds:fat1_sector add edx,ds:fat2_sector call lock_sector jc update_cluster_link16_done or si,cx mov es:[esi],di ModifySector UnlockSector clc update_cluster_link16_done: ; pop di pop esi pop edx pop ecx pop ebx ret update_cluster_link16 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: UPDATE_CLUSTER_LINK32 ; ; DESCRIPTION: Update cluster link for FAT32 ; ; PARAMETERS: AL Drive ; EDX Cluster # ; ECX Next cluster ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; update_cluster_link32 PROC near push ebx push ecx push edx push esi push edi ; cmp edx,ds:clusters cmc jc update_cluster_link32_done mov edi,ecx and edx,0FFFFFFFh shl edx,2 mov ecx,edx shr edx,9 add edx,ds:fat1_sector and cx,1FFh call lock_sector jc update_cluster_link32_fat2 or si,cx mov es:[esi],edi ModifySector UnlockSector update_cluster_link32_fat2: sub edx,ds:fat1_sector add edx,ds:fat2_sector call lock_sector jc update_cluster_link32_done or si,cx mov es:[esi],edi ModifySector UnlockSector clc update_cluster_link32_done: ; pop edi pop esi pop edx pop ecx pop ebx ret update_cluster_link32 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: NEXT_CLUSTER12 ; ; DESCRIPTION: Find next cluster for FAT12 ; ; PARAMETERS: AL Drive ; EDX Cluster # ; ; RETURNS: EDX Next cluster # ; NC OK ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; next_cluster12 PROC near push ds push ebx push cx push esi ; EnterSection ds:cluster_section mov cx,dx add dx,dx add dx,cx mov cx,dx movzx edx,dx shr edx,10 add edx,ds:fat1_sector and cx,3FFh clc rcr cx,1 pushf call lock_fat jnc next_cluster_locked popf stc jmp next_cluster12_done next_cluster_locked: or si,cx popf jc next_cluster_high mov cl,es:[esi] inc si test si,1FFh jnz next_cluster_low_ok UnlockSector inc edx call lock_fat jc next_cluster12_done next_cluster_low_ok: mov ch,es:[esi] and cx,0FFFh jmp next_cluster_ok next_cluster_high: mov ch,es:[esi] and ch,0F0h inc si test si,1FFh jnz next_cluster_high_ok UnlockSector inc edx call lock_fat jc next_cluster12_done next_cluster_high_ok: mov cl,es:[esi] rol cx,4 next_cluster_ok: UnlockSector movzx edx,cx cmp edx,0FF8h cmc next_cluster12_done: pushf LeaveSection ds:cluster_section popf ; pop esi pop cx pop ebx pop ds ret next_cluster12 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: NEXT_CLUSTER16 ; ; DESCRIPTION: Find next cluster for FAT16 ; ; PARAMETERS: AL Drive ; EDX Cluster # ; ; RETURNS: EDX Next cluster # ; NC OK ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; next_cluster16 PROC near push ds push ebx push cx push esi ; EnterSection ds:cluster_section add edx,edx mov cx,dx shr edx,9 add edx,ds:fat1_sector and cx,1FFh call lock_fat jc next_cluster16_done or si,cx movzx edx,word ptr es:[esi] UnlockSector cmp edx,0FFF8h cmc next_cluster16_done: pushf LeaveSection ds:cluster_section popf ; pop esi pop cx pop ebx pop ds ret next_cluster16 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: NEXT_CLUSTER32 ; ; DESCRIPTION: Find next cluster for FAT32 ; ; PARAMETERS: AL Drive ; EDX Cluster # ; ; RETURNS: EDX Next cluster # ; NC OK ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; next_cluster32 PROC near push ds push ebx push cx push esi ; EnterSection ds:cluster_section shl edx,2 mov cx,dx shr edx,9 add edx,ds:fat1_sector and cx,1FFh call lock_fat jc next_cluster32_done or si,cx mov edx,es:[esi] and edx,0FFFFFFFh UnlockSector cmp edx,0FFFFFF8h cmc next_cluster32_done: pushf LeaveSection ds:cluster_section popf ; pop esi pop cx pop ebx pop ds ret next_cluster32 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: NEXT_CLUSTER ; ; DESCRIPTION: Find next cluster ; ; PARAMETERS: AL Drive ; EDX Cluster # ; ; RETURNS: EDX Next cluster # ; NC OK ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; public next_cluster next_cluster Proc near cmp ds:fat_type,fat12 je nextc12 ; cmp ds:fat_type,fat16 je nextc16 nextc32: call next_cluster32 jmp next_cluster_done nextc16: call next_cluster16 jmp next_cluster_done nextc12: call next_cluster12 next_cluster_done: ret next_cluster Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: NEXT_SECTOR12 ; ; DESCRIPTION: Find next sector for FAT12 ; ; PARAMETERS: AL Drive ; EDX Sector # ; ; RETURNS: EDX Next sector # ; NC OK ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; next_sector12 PROC near push ecx push esi inc edx mov cl,ds:fat_cluster_shift mov si,1 shl si,cl dec si sub edx,ds:start_sector test si,dx clc jnz next_sector12_ok dec edx mov cl,ds:fat_cluster_shift shr edx,cl add edx,2 call next_cluster12 jc next_sector12_done sub edx,2 mov cl,ds:fat_cluster_shift shl edx,cl next_sector12_ok: add edx,ds:start_sector clc next_sector12_done: pop esi pop ecx ret next_sector12 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: NEXT_SECTOR16 ; ; DESCRIPTION: Find next sector for FAT16 ; ; PARAMETERS: AL Drive ; EDX Sector # ; ; RETURNS: EDX Next sector # ; NC OK ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; next_sector16 PROC near push ecx push esi inc edx mov cl,ds:fat_cluster_shift mov si,1 shl si,cl dec si sub edx,ds:start_sector test si,dx clc jnz next_sector16_ok dec edx mov cl,ds:fat_cluster_shift shr edx,cl add edx,2 call next_cluster16 jc next_sector16_done sub edx,2 mov cl,ds:fat_cluster_shift shl edx,cl next_sector16_ok: add edx,ds:start_sector clc next_sector16_done: pop esi pop ecx ret next_sector16 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: NEXT_SECTOR32 ; ; DESCRIPTION: Find next sector for FAT32 ; ; PARAMETERS: AL Drive ; EDX Sector # ; ; RETURNS: EDX Next sector # ; NC OK ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; next_sector32 PROC near push ecx push esi inc edx mov cl,ds:fat_cluster_shift mov si,1 shl si,cl dec si sub edx,ds:start_sector test si,dx clc jnz next_sector32_ok dec edx mov cl,ds:fat_cluster_shift shr edx,cl add edx,2 call next_cluster32 jc next_sector32_done sub edx,2 mov cl,ds:fat_cluster_shift shl edx,cl next_sector32_ok: add edx,ds:start_sector clc next_sector32_done: pop esi pop ecx ret next_sector32 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: NEXT_SECTOR ; ; DESCRIPTION: Find next sector ; ; PARAMETERS: AL Drive ; EDX Sector # ; ; RETURNS: EDX Next sector # ; NC OK ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; public next_sector next_sector Proc near cmp ds:fat_type,fat12 je next12 ; cmp ds:fat_type,fat16 je next16 next32: call next_sector32 jmp next_sector_done next16: call next_sector16 jmp next_sector_done next12: call next_sector12 next_sector_done: ret next_sector Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: ALLOCATE_CLUSTER12 ; ; DESCRIPTION: Allocate a cluster for FAT12 ; ; PARAMETERS: AL Drive ; ; RETURNS EDX Cluster # ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; allocate_cluster12 PROC near push ebx push ecx push esi push edi ; EnterSection ds:cluster_section dec ds:free_clusters mov edx,ds:fat1_sector xor edi,edi ; call lock_fat jc allocate_cluster_failed0 mov edi,2 add si,3 jmp allocate_cluster_low allocate_cluster_lock0: call lock_fat jnc allocate_cluster_low allocate_cluster_failed0: inc edx add edi,342 cmp edi,ds:clusters cmc jc allocate_cluster12_fail allocate_cluster_lock1: call lock_fat jnc allocate_cluster_low_locked1 ; inc edx add edi,341 cmp edi,ds:clusters cmc jc allocate_cluster12_fail allocate_cluster_lock0_5: call lock_fat jnc allocate_cluster_high ; inc edx add edi,341 cmp edi,ds:clusters cmc jc allocate_cluster12_fail jmp allocate_cluster_lock0 allocate_cluster_low_locked1: inc si allocate_cluster_low: mov cl,es:[esi] inc si test si,1FFh jnz allocate_cluster_low_ok UnlockSector inc edx call lock_fat jnc allocate_cluster_low_ok ; inc edx add edi,342 cmp edi,ds:clusters cmc jc allocate_cluster12_fail jmp allocate_cluster_lock0 allocate_cluster_low_ok: mov ch,es:[esi] and ch,0Fh stc jmp allocate_cluster12_test allocate_cluster_high: mov ch,es:[esi] and ch,0F0h inc si test si,1FFh jnz allocate_cluster_high_ok UnlockSector inc edx call lock_fat jnc allocate_cluster_high_ok ; inc edx add edi,342 cmp edi,ds:clusters cmc jc allocate_cluster12_fail jmp allocate_cluster_lock0_5 allocate_cluster_high_ok: mov cl,es:[esi] rol cx,4 inc si clc allocate_cluster12_test: pushf or cx,cx jz allocate_cluster12_mark add edi,1 cmp edi,ds:clusters jc allocate_cluster12_next popf stc jmp allocate_cluster12_done allocate_cluster12_next: popf jc allocate_cluster_high test si,1FFh jnz allocate_cluster_low UnlockSector inc edx jmp allocate_cluster_lock0 allocate_cluster12_mark: popf mov edx,edi mov ecx,0FFFh call update_cluster_link12 allocate_cluster12_done: pushf UnlockSector popf allocate_cluster12_fail: pushf LeaveSection ds:cluster_section popf ; pop edi pop esi pop ecx pop ebx ret allocate_cluster12 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: ALLOCATE_CLUSTER16 ; ; DESCRIPTION: Allocate a cluster for FAT16 ; ; PARAMETERS: AL Drive ; ; RETURNS EDX Cluster # ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; allocate_cluster16 PROC near push ebx push ecx push esi push edi ; EnterSection ds:cluster_section dec ds:free_clusters mov edx,ds:fat1_sector xor edi,edi ; call lock_fat jc allocate_cluster16_failed mov edi,2 add si,4 jmp allocate_cluster16_loop allocate_cluster16_lock: call lock_fat jnc allocate_cluster16_loop allocate_cluster16_failed: inc edx add edi,256 cmp edi,ds:clusters cmc jc allocate_cluster16_fail allocate_cluster16_loop: mov cx,es:[esi] add si,2 or cx,cx jz allocate_cluster16_mark inc edi cmp edi,ds:clusters jc allocate_cluster16_next stc jmp allocate_cluster16_done allocate_cluster16_next: test si,1FFh jnz allocate_cluster16_loop UnlockSector inc edx jmp allocate_cluster16_lock allocate_cluster16_mark: mov edx,edi mov ecx,0FFFFh call update_cluster_link16 allocate_cluster16_done: pushf UnlockSector popf allocate_cluster16_fail: pushf LeaveSection ds:cluster_section popf ; pop edi pop esi pop ecx pop ebx ret allocate_cluster16 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: ALLOCATE_CLUSTER32 ; ; DESCRIPTION: Allocate a cluster for FAT32 ; ; PARAMETERS: AL Drive ; ; RETURNS EDX Cluster # ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; allocate_cluster32 PROC near push ebx push ecx push esi push edi ; EnterSection ds:cluster_section dec ds:free_clusters mov edx,ds:info_sector or edx,edx jz allocate_cluster32_do ; mov al,ds:drive_nr LockSector mov edx,ds:free_clusters mov es:[esi].fi_free_clusters,edx ModifySector UnlockSector allocate_cluster32_do: mov edx,ds:fat1_sector xor edi,edi ; call lock_fat jc allocate_cluster32_failed mov edi,2 add si,8 jmp allocate_cluster32_loop allocate_cluster32_lock: call lock_fat jnc allocate_cluster32_loop allocate_cluster32_failed: inc edx add edi,128 cmp edi,ds:clusters cmc jc allocate_cluster32_fail allocate_cluster32_loop: mov ecx,es:[esi] add si,4 or ecx,ecx jz allocate_cluster32_mark inc edi cmp edi,ds:clusters jc allocate_cluster32_next stc jmp allocate_cluster32_done allocate_cluster32_next: test si,1FFh jnz allocate_cluster32_loop UnlockSector inc edx jmp allocate_cluster32_lock allocate_cluster32_mark: mov edx,edi mov ecx,0FFFFFFFh call update_cluster_link32 allocate_cluster32_done: pushf UnlockSector popf allocate_cluster32_fail: pushf LeaveSection ds:cluster_section popf ; pop edi pop esi pop ecx pop ebx ret allocate_cluster32 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: ALLOCATE_CLUSTER_NO_VERIFY ; ; DESCRIPTION: Allocate a cluster without verification ; ; PARAMETERS: AL Drive ; ; RETURNS EDX Cluster # ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; public allocate_cluster_no_verify allocate_cluster_no_verify Proc near cmp ds:fat_type,fat12 je alloc12 ; cmp ds:fat_type,fat16 je alloc16 alloc32: call allocate_cluster32 jmp allocate_cluster_done alloc16: call allocate_cluster16 jmp allocate_cluster_done alloc12: call allocate_cluster12 allocate_cluster_done: ret allocate_cluster_no_verify Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: FREE_CLUSTER ; ; DESCRIPTION: Free a cluster ; ; PARAMETERS: AL Drive ; EDX Cluster # ; ; RETURNS: NC OK ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; public free_cluster free_cluster Proc near push ecx EnterSection ds:cluster_section cmp ds:fat_type,fat12 je free12 ; cmp ds:fat_type,fat16 je free16 free32: xor ecx,ecx call update_cluster_link32 ; pushf push ebx push edx push esi inc ds:free_clusters mov edx,ds:info_sector or edx,edx jz free_cluster32_done ; LockSector mov edx,ds:free_clusters mov es:[esi].fi_free_clusters,edx ModifySector UnlockSector free_cluster32_done: pop esi pop edx pop ebx popf jmp free_cluster_done free16: xor ecx,ecx call update_cluster_link16 inc ds:free_clusters jmp free_cluster_done free12: xor ecx,ecx call update_cluster_link12 inc ds:free_clusters free_cluster_done: LeaveSection ds:cluster_section pop ecx ret free_cluster Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: LINK_CLUSTER ; ; DESCRIPTION: Link a cluster ; ; PARAMETERS: AL Drive ; EDX Cluster # ; ECX Linked cluster # ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; public link_cluster link_cluster Proc near EnterSection ds:cluster_section cmp ds:fat_type,fat12 je link12 ; cmp ds:fat_type,fat16 je link16 link32: call update_cluster_link32 jmp link_cluster_done link16: call update_cluster_link16 jmp link_cluster_done link12: call update_cluster_link12 link_cluster_done: LeaveSection ds:cluster_section ret link_cluster Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: EOF_CLUSTER ; ; DESCRIPTION: Mark cluster as last ; ; PARAMETERS: AL Drive ; EDX Cluster # ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; public eof_cluster eof_cluster Proc near EnterSection ds:cluster_section cmp ds:fat_type,fat12 je eof12 ; cmp ds:fat_type,fat16 je eof16 eof32: mov ecx,0FFFFFFFFh call update_cluster_link32 jmp eof_cluster_done eof16: mov ecx,0FFFFh call update_cluster_link16 jmp eof_cluster_done eof12: mov ecx,0FFFh call update_cluster_link12 eof_cluster_done: LeaveSection ds:cluster_section ret eof_cluster Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: BAD_CLUSTER ; ; DESCRIPTION: Mark cluster as bad ; ; PARAMETERS: AL Drive ; EDX Cluster # ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; public bad_cluster bad_cluster Proc near EnterSection ds:cluster_section cmp ds:fat_type,fat12 je bad12 ; cmp ds:fat_type,fat16 je bad16 bad32: mov ecx,0FFFFFFF8h call update_cluster_link32 jmp bad_cluster_done bad16: mov ecx,0FFF8h call update_cluster_link16 jmp bad_cluster_done bad12: mov ecx,0FF8h call update_cluster_link12 bad_cluster_done: LeaveSection ds:cluster_section ret bad_cluster Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GET_FREE_CLUSTER12 ; ; DESCRIPTION: Get free clusters for FAT12 ; ; PARAMETERS: AL Drive ; ; RETURNS EDX Free clusters ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_free_cluster12 PROC near push ebx push ecx push esi push edi push ebp ; xor ebp,ebp EnterSection ds:cluster_section mov edx,ds:fat1_sector xor edi,edi ; call lock_fat jc get_free_cluster_failed0 mov edi,2 add si,3 jmp get_free_cluster_low get_free_cluster_lock0: call lock_fat jnc get_free_cluster_low get_free_cluster_failed0: inc edx add edi,342 cmp edi,ds:clusters cmc jc get_free_cluster12_done get_free_cluster_lock1: call lock_fat jnc get_free_cluster_low_locked1 ; inc edx add edi,341 cmp edi,ds:clusters cmc jc get_free_cluster12_done get_free_cluster_lock0_5: call lock_fat jnc get_free_cluster_high ; inc edx add edi,341 cmp edi,ds:clusters cmc jc get_free_cluster12_done jmp get_free_cluster_lock0 get_free_cluster_low_locked1: inc si get_free_cluster_low: mov cl,es:[esi] inc si test si,1FFh jnz get_free_cluster_low_ok UnlockSector inc edx call lock_fat jnc get_free_cluster_low_ok ; inc edx add edi,342 cmp edi,ds:clusters cmc jc get_free_cluster12_done jmp get_free_cluster_lock0 get_free_cluster_low_ok: mov ch,es:[esi] and ch,0Fh stc jmp get_free_cluster12_test get_free_cluster_high: mov ch,es:[esi] and ch,0F0h inc si test si,1FFh jnz get_free_cluster_high_ok ; UnlockSector inc edx call lock_fat jnc get_free_cluster_high_ok ; inc edx add edi,342 cmp edi,ds:clusters cmc jc get_free_cluster12_done jmp get_free_cluster_lock0_5 get_free_cluster_high_ok: mov cl,es:[esi] rol cx,4 inc si clc get_free_cluster12_test: pushf or cx,cx jnz get_free_cluster12_used ; inc ebp get_free_cluster12_used: add edi,1 cmp edi,ds:clusters jc get_free_cluster12_next ; popf jmp get_free_cluster12_leave get_free_cluster12_next: popf jc get_free_cluster_high test si,1FFh jnz get_free_cluster_low UnlockSector inc edx jmp get_free_cluster_lock0 get_free_cluster12_done: UnlockSector get_free_cluster12_leave: LeaveSection ds:cluster_section ; mov edx,ebp pop ebp pop edi pop esi pop ecx pop ebx ret get_free_cluster12 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GET_FREE_CLUSTER16 ; ; DESCRIPTION: Get free clusters for FAT16 ; ; PARAMETERS: AL Drive ; ; RETURNS EDX Free clusters ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_free_cluster16 PROC near push ebx push ecx push esi push edi push ebp ; xor ebp,ebp EnterSection ds:cluster_section mov edx,ds:fat1_sector xor edi,edi ; call lock_fat jc get_free_cluster16_leave ; mov edi,2 add si,4 jmp get_free_cluster16_loop get_free_cluster16_lock: call lock_fat jnc get_free_cluster16_loop get_free_cluster16_failed: inc edx add edi,256 cmp edi,ds:clusters cmc jc get_free_cluster16_leave get_free_cluster16_loop: mov cx,es:[esi] add si,2 or cx,cx jnz get_free_cluster16_used ; inc ebp get_free_cluster16_used: inc edi cmp edi,ds:clusters jnc get_free_cluster16_done get_free_cluster16_next: test si,1FFh jnz get_free_cluster16_loop UnlockSector inc edx jmp get_free_cluster16_lock get_free_cluster16_done: pushf UnlockSector popf get_free_cluster16_leave: LeaveSection ds:cluster_section ; mov edx,ebp pop ebp pop edi pop esi pop ecx pop ebx ret get_free_cluster16 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GET_FREE_CLUSTER32 ; ; DESCRIPTION: Get free clusters for FAT32 ; ; PARAMETERS: AL Drive ; ; RETURNS EDX Free clusters ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; get_free_cluster32 PROC near push ebx push ecx push esi push edi push ebp ; xor ebp,ebp EnterSection ds:cluster_section mov edx,ds:fat1_sector xor edi,edi ; call lock_fat jc get_free_cluster32_leave ; mov edi,2 add si,8 jmp get_free_cluster32_loop get_free_cluster32_lock: call lock_fat jnc get_free_cluster32_loop get_free_cluster32_failed: inc edx add edi,128 cmp edi,ds:clusters cmc jc get_free_cluster32_leave get_free_cluster32_loop: mov ecx,es:[esi] add si,4 or ecx,ecx jnz get_free_cluster32_used ; inc ebp get_free_cluster32_used: inc edi cmp edi,ds:clusters jnc get_free_cluster32_done get_free_cluster32_next: test si,1FFh jnz get_free_cluster32_loop UnlockSector inc edx jmp get_free_cluster32_lock get_free_cluster32_done: UnlockSector get_free_cluster32_leave: LeaveSection ds:cluster_section ; mov edx,ebp pop ebp pop edi pop esi pop ecx pop ebx ret get_free_cluster32 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: GET_FREE_CLUSTERS ; ; DESCRIPTION: Get number of free clusters ; ; PARAMETERS: AL Drive ; ; RETURNS: EDX Free clusters ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; public get_free_clusters get_free_clusters Proc near cmp ds:fat_type,fat12 je gfc12 ; cmp ds:fat_type,fat16 je gfc16 gfc32: call get_free_cluster32 jmp gfc_cluster_done gfc16: call get_free_cluster16 jmp gfc_cluster_done gfc12: call get_free_cluster12 gfc_cluster_done: ret get_free_clusters Endp code ENDS END