;*****************************************************************************
; DIR.ASM [ TRDOS KERNEL - COMMAND EXECUTER SECTION - DIRECTORY FUNCTIONS ]
; (c) 2004-2010 Erdogan TAN [ 17/01/2004 ] Last Update: 09/10/2011
; ! Under Development !
proc_print_directory proc near
; 30/10/2010 File Size string loop BugFix (>= 1GB)
; 03/10/2009 Current Directory String Length
; 19/09/2009
; 2005
; INPUT : DS:SI = Asciiz File/Dir Name Address
; INPUT : CS = DS = ES
push si
mov word ptr [Dir_Count],0
mov word ptr [File_Count],0
mov word ptr [Total_FSize], 0
mov word ptr [Total_FSize]+2, 0
call proc_clear_screen
mov ah, byte ptr [Current_Drv] ; DirBuff_Drv - 'A'
mov al, byte ptr [Current_Dir_Drv]
;mov al, ah
;add al, 'A'
mov byte ptr [Dir_Drive_Name], al
xor al, al
mov si, offset Logical_DosDisks
add si, ax
mov di, offset Vol_Name
mov al, byte ptr [SI][LD_FATType]
; 19/12/2009 FS Directory Listing
; push ax
; ....
cmp al, 2
ja short pass_print_add_si_ld_FAT_vname
or al, al
jz short loc_print_dir_fs_volume_name
mov ax, word ptr [SI][LD_BPB][VolumeID]
mov word ptr [Current_VolSerial1], ax
mov ax, word ptr [SI][LD_BPB][VolumeID]+2
mov word ptr [Current_VolSerial2], ax
add si, LD_BPB+VolumeLabel
jmp short pass_print_add_si_ld_FAT32_vname
loc_print_dir_fs_volume_name:
mov ax, word ptr [SI][LD_FS_VolumeSerial]
mov word ptr [Current_VolSerial1], ax
mov ax, word ptr [SI][LD_FS_VolumeSerial]+2
mov word ptr [Current_VolSerial2], ax
add si, LD_FS_VolumeName
mov cx, 32
rep movsw
jmp short pass_print_dir_fat_volume_name
pass_print_add_si_ld_FAT_vname:
mov ax, word ptr [SI][LD_BPB][FAT32_VolID]
mov word ptr [Current_VolSerial1], ax
mov ax, word ptr [SI][LD_BPB][FAT32_VolID]+2
mov word ptr [Current_VolSerial2], ax
add si, LD_BPB+FAT32_VolLab
pass_print_add_si_ld_FAT32_vname:
mov cx, 11
rep movsb
mov byte ptr [DI], 0
pass_print_dir_fat_volume_name:
mov al, byte ptr [Current_VolSerial1]
call proc_hex
mov word ptr [Vol_Serial1]+2, ax
mov al, byte ptr [Current_VolSerial1]+1
call proc_hex
mov word ptr [Vol_Serial1], ax
mov al, byte ptr [Current_VolSerial2]
call proc_hex
mov word ptr [Vol_Serial2]+2, ax
mov al, byte ptr [Current_VolSerial2]+1
call proc_hex
mov word ptr [Vol_Serial2], ax
mov si, offset Current_Dir_Root
mov di, offset Dir_Str_Root
;xor ch, ch
mov cl, byte ptr [Current_Dir_Strlen]
inc cl
cmp cl, 64
jna short pass_print_dir_strlen_shorting
inc si
add si, cx
sub si, 64
inc di
mov ax, '..'
stosw
mov ah, 20h ; mov ax, ' .'
stosw
pass_print_dir_strlen_shorting:
rep movsb
mov si, offset Dir_Drive_Str
call proc_printmsg
mov si, offset Vol_Serial_Header
call proc_printmsg
mov ah,0Eh
mov bx,07h
mov al,0Dh
int 10h
mov al,0Ah
int 10h
mov al,0Dh
int 10h
mov al,0Ah
int 10h
; 19/12/2009 FS Directory Listing
; pop bx ;pushed ax
; ....
; 19/12/2009 FS Directory listing
; or bl,bl ; bl = 0 => FS, not FAT
; jnz short loc_print_dir_first_file
;Print FS directory is not usable for now
;17/9/2009
; pop si
; retn
loc_print_dir_first_file:
mov byte ptr [PrintDir_RowCounter], 16
mov ax, word ptr [AttributesMask]
pop si
call proc_find_first_file
push ds
pop es
jc loc_dir_ok
loc_dfname_use_this:
push cx ; CL = Attr = byte ptr [SI]+11
test cl, 10h ; Is it a directory?
jz short loc_not_dir
inc word ptr [Dir_Count]
push si
mov cx, 10
mov si, offset Type_Dir ; '
'
mov di, offset Dir_Or_FileSize
rep movsb ; move 10 bytes
pop si
jmp short loc_dir_attribute
loc_not_dir:
inc word ptr [File_Count]
add word ptr [Total_FSize], ax
adc word ptr [Total_FSize]+2, dx
mov di,10 ; 30/10/2010 BugFix
; (mov di, 9 -> Bug for >=1 GB file size)
mov cx, di ; 16 bit divisor
loc_dir_rdivide:
call Rx_Dos_Div32 ; 32 bit divide
add bl, '0' ; to make visible
dec di
mov Byte Ptr [Dir_Or_FileSize][DI],bl
cmp ax,0
ja short loc_dir_rdivide
cmp dx,0
ja short loc_dir_rdivide
loc_dir_fill_space:
cmp di,0
jna short loc_dir_attribute
dec di
mov Byte Ptr [Dir_Or_FileSize][DI],20h
jmp short loc_dir_fill_space
loc_dir_attribute:
pop cx
mov word ptr [File_Attribute], 2020h
mov word ptr [File_Attribute]+2, 2020h
cmp cl, 20h ; Is it an archive file?
jb short loc_dir_pass_arch
mov Byte Ptr [File_Attribute]+3,'A'
loc_dir_pass_arch:
and cl,7
jz short loc_dir_file_name
mov ch,cl
and cl,3
cmp ch,cl
jna short loc_dir_pass_s
mov byte ptr [File_Attribute], 'S'
loc_dir_pass_s:
and cl,2
jz short loc_dir_pass_h
mov byte ptr [File_Attribute]+1, 'H'
loc_dir_pass_h:
and ch,1
jz short loc_dir_file_name
mov byte ptr [File_Attribute]+2, 'R'
loc_dir_file_name:
mov bx, word ptr [SI]+18h ; Date
mov dx, word ptr [SI]+16h ; Time
push si
mov cx, 8
mov di, offset File_Name
rep movsb ; move 8 bytes
mov Byte Ptr [DI],20h
inc di
mov cx, 3
rep movsb ; move 3 bytes
pop si
Dir_Date_start:
mov ax, bx ; Date
and ax, 00011111b ; Day Mask
aam ; Q([AL]/10)->AH
; R([AL]/10)->AL
; [AL]+[AH]= Day as BCD
or ax, '00' ; Convert to ASCII
xchg al,ah
mov word ptr [File_Day],ax
mov ax, bx
mov cl, 5
shr ax, cl ; shift right 5 times
and ax, 00001111b ; Month Mask
aam
or ax, '00'
xchg ah,al
mov word ptr [File_Month],ax
mov ax, bx
mov cl, 9
shr ax, cl
and ax, 01111111b ; Result = Year - 1980
add ax, 1980
mov cl, 10
div cl ; Q -> AL, R -> AH
or ah, '0'
mov byte ptr [File_Year]+3,ah
aam
xchg ah, al
or ah, '0' ; Convert to ASCII
mov byte ptr [File_Year]+2,ah
aam
xchg al, ah
or ax, '00'
mov word ptr [File_Year],ax
Dir_Time_start:
mov ax, dx ; Time
mov cl, 5
shr ax, cl ; shift right 5 times
and ax, 0000111111b ; Minute Mask
aam
or ax, '00'
xchg ah,al
mov word ptr [File_Minute],ax
mov al, dh
shr al, 1
shr al, 1
shr al, 1 ; ax = hours
aam
or ax, '00'
xchg ah, al
mov word ptr [File_Hour],ax
loc_show_line:
push si
mov si, offset File_Name
mov cx, 46
mov ah, 0Eh
mov bx, 07h
loop_loc_dir_entry:
lodsb
int 10h
loop loop_loc_dir_entry
pop si
mov al,0Dh
int 10h
mov al,0Ah
int 10h
dec byte ptr [PrintDir_RowCounter]
jz Pause_dir_scroll
loc_next_entry:
call proc_find_next_file
push ds
pop es
jnc loc_dfname_use_this
loc_dir_ok:
mov ax, word ptr [Dir_Count]
mov di, offset Decimal_Dir_Count
cmp ax, 10
jb short pass_ddc
inc di
cmp ax, 100
jb short pass_ddc
inc di
cmp ax, 1000
jb short pass_ddc
inc di
cmp ax, 10000
jb short pass_ddc
inc di
pass_ddc:
mov byte ptr [DI]+1, 0
loc_ddc_rediv:
xor dx, dx
mov cx, 10
div cx
add dl, "0"
mov byte ptr [DI], dl
dec di
cmp ax, 0
ja short loc_ddc_rediv
mov ax, word ptr [File_Count]
mov di, offset Decimal_File_Count
cmp ax, 10
jb short pass_dfc
inc di
cmp ax, 100
jb short pass_dfc
inc di
cmp ax, 1000
jb short pass_dfc
inc di
cmp ax, 10000
jb short pass_dfc
inc di
pass_dfc:
mov byte ptr [DI]+1, 0
loc_dfc_rediv:
xor dx, dx
mov cx, 10
div cx
add dl, "0"
mov byte ptr [DI], dl
dec di
cmp ax, 0
ja short loc_dfc_rediv
mov di, offset TFS_Dec_End
mov byte ptr [DI], 0
mov ax, word ptr [Total_FSize]
mov dx, word ptr [Total_FSize]+2
mov cx, 10
rediv_tfs_hex:
call Rx_Dos_Div32
add bl, "0"
dec di
mov byte ptr [DI], bl
cmp ax, 0
ja short rediv_tfs_hex
cmp dx, 0
ja short rediv_tfs_hex
mov word ptr [TFS_Dec_Begin], di
mov si, offset Decimal_File_Count_Header
call proc_printmsg
mov si, offset str_files
call proc_printmsg
mov si, offset str_dirs
call proc_printmsg
mov si, word ptr [TFS_Dec_Begin]
call proc_printmsg
mov si, offset str_bytes
call proc_printmsg
retn
Pause_dir_scroll:
xor ah, ah
int 16h
cmp al,1Bh
je loc_dir_ok
mov byte ptr [PrintDir_RowCounter], 16 ; Reset counter
jmp loc_next_entry
PrintDir_RowCounter: db 0
File_Count: dw 0
Dir_Count: dw 0
Decimal_File_Count_Header: db 0Dh, 0Ah
Decimal_File_Count: db 6 dup(0)
str_files: db " file(s) & "
Decimal_Dir_Count: db 6 dup(0)
str_dirs: db " directory(s) ", 0Dh, 0Ah, 0
Total_FSize: dd 0
TFS_Dec_Begin: dw 0
db 10 dup(0)
TFS_Dec_End: db 0
str_bytes: db " byte(s) in file(s)", 0Dh, 0Ah, 0
proc_print_directory endp
Proc_Find_First_File proc near
; 09/10/2011
; 11/09/2011
; 06/02/2011 Modification (Dir_File_Name -> Dir_Entry_Name)
; 19/11/2010 Directory Entry Number, Longname Entry Length
; 29/10/2010 BugFix
; 24/01/2010 FindFile_drv <- Current_Drv
; 18/10/2009
; 02/10/2009 proc_convert_file_name (mov si, di)
; 17/09/2009
; 2005
; INPUT -> DS:SI = ASCIIZ File/Dir/Path Name Address
; AL = Attributes AND mask (The AND result must be equal to AL)
; bit 0 = Read Only
; bir 1 = Hidden
; bit 2 = System
; bit 3 = Volume Label
; bit 4 = Directory
; bit 5 = Archive
; bit 6 = Reserved, must be 0
; bit 7 = Reserved, must be 0
; AH = Attributes NAND mask (The AND result must be ZERO)
;
; OUTPUT -> CF = 1 : Error, Error Code in AX (AL)
; CF = 0 -> DS:SI = Directory Entry (FindFile_DirEntry) Location
; ES:DI = Directory Buffer Directory Entry Location
; DX:AX = File Size
; CL = Attributes of The File/Directory
; CH = Long Name Yes/No Status (>0 is YES)
; BX > 0 : Ambiguous filename chars are used
push cs ; 11/09/2011
pop es ; 11/09/2011
mov word ptr CS:[FindFile_AttributesMask], ax
mov di, offset FindFile_DirEntry ; TR-DOS Fullfilename formatted buffer
xor ax, ax
mov cx, 23 ; 29/10/2010, 23 -> 22 BugFix -> 19/11/2010, 23 (+2 byte)
rep stosw
; mov di, offset FindFile_Drv ; TR-DOS Fullfilename formatted buffer
; add di, 66 ; Dot File Name
mov di, offset FindFile_Name ; FFF structure, offset 66
push di
; mov cx, 12
mov cl, 12 ; 11/09/2011
rep movsb
;xor al, al ; 09/10/2011
stosb
pop si
push cs
pop ds
mov di, offset Dir_Entry_Name ; Dir Entry Format File Name
call proc_convert_file_name
; 02/10/2009
;mov si, offset Dir_Entry_Name
mov si, di
mov ax, word ptr [FindFile_AttributesMask]
;xor cx, cx
xor cl, cl ; 11/09/2011
call proc_locate_current_dir_file
jc short loc_fff_retn
; ES:DI = Directory Entry
; 19/11/2010
xor ch, ch
xor dh, 0Fh
jz short loc_fff_longname_yes
mov byte ptr [FindFile_LongNameYes], ch
jmp short loc_fff_longname_no
loc_fff_longname_yes:
;inc byte ptr [FindFile_LongNameYes]
mov cl, byte ptr [LongName_EntryLength]
mov byte ptr [FindFile_LongNameEntryLength], cl
loc_fff_longname_no:
; 19/11/2010 optimization
;mov bx, word ptr [DirBuff_CurrentEntry]
mov word ptr [FindFile_DirEntryOffset], bx
mov bx, ax ; Ambigouos Filename chars used sign > 0
;24/01/2010 FindFile_Drv = Current_Drv
mov al, byte ptr [Current_Drv]
mov byte ptr [FindFile_Drv], al
mov ax, word ptr [Current_Dir_FCluster]
mov dx, word ptr [Current_Dir_FCluster]+2
mov word ptr [FindFile_DirFirstCluster], ax
mov word ptr [FindFile_DirFirstCluster]+2, dx
loc_fff_fnf_return:
; 19/11/2010
mov ax, word ptr [DirBuff_Cluster]
mov dx, word ptr [DirBuff_Cluster]+2
mov word ptr [FindFile_DirCluster], ax
mov word ptr [FindFile_DirCluster]+2, dx
inc word ptr [FindFile_MatchCounter]
push es
push ds
pop es
pop ds
push di
mov si, di
mov di, offset FindFile_DirEntry
push di
mov cl, 16
rep movsw
pop si
pop di
push ds
pop es
push cs
pop ds
mov ax, word ptr [FindFile_DirEntry]+28 ; File Size Low Word
mov dx, word ptr [FindFile_DirEntry]+30 ; File Size High Word
mov cl, byte ptr [FindFile_DirEntry]+11 ; File Attributes
mov ch, byte ptr [FindFile_LongNameYes]
push word ptr [DirBuff_EntryCounter]
pop word ptr [FindFile_DirEntryNumber]
loc_fff_retn:
retn
;FFF Structure
FindFile_Drv: db 0
FindFile_Directory: db 65 dup(0)
FindFile_Name: db 13 dup(0)
FindFile_LongNameEntryLength:
FindFile_LongNameYes: db 0 ; Sign for longname procedures
;Above 80 bytes
;is TR-DOS Source/Destination File FullName Format/Structure
FindFile_AttributesMask: dw 0
FindFile_DirEntry: db 32 dup(0)
FindFile_DirFirstCluster: dd 0
FindFile_DirCluster: dd 0
FindFile_DirEntryOffset: dw 0
FindFile_MatchCounter: dw 0
; 19/11/2010
FindFile_DirEntryNumber: dw 0
; Above is 128 bytes
;06/02/2011
Dir_Entry_Name: db 13 dup(0)
;
Proc_Find_First_File endp
Proc_Find_Next_File proc near
; 06/02/2011 Modification (Dir_File_Name -> Dir_Entry_Name)
; 19/11/2010
; 29/10/2010
; 27/09/2009
; 26/09/2009
; 17/09/2009
; 2005
; INPUT -> NONE, Find First File Parameters (CS=DS=ES)
; OUTPUT -> CF = 1 : Error, Error Code in AX (AL)
; CF = 0 -> DS:SI = Directory Entry (FindFile_DirEntry) Location
; ES:DI = Directory Buffer Directory Entry Location
; DX:AX = File Size
; CL = Attributes of The File/Directory
; CH = Long Name Yes/No Status (>0 is YES)
; BX = Offset of FindFile (128 byte) Structure Address
; 29/10/2010
cmp word ptr [FindFile_MatchCounter], 0
ja short loc_start_search_next_file
;
loc_fnf_stc_retn:
stc
loc_fnf_ax12h_retn:
mov ax, 12h ; 18, No More files
;loc_fnf_retn:
retn
loc_start_search_next_file:
mov bx, word ptr [FindFile_DirEntryOffset]
inc bx
cmp bx, word ptr [DirBuff_LastEntry]
jna short loc_fnf_search
loc_cont_search_next_file:
mov bh, byte ptr [Current_Drv]
xor bl, bl
mov si, offset Logical_DosDisks
add si, bx
;10/01/2009 FS modification
cmp byte ptr [Current_Dir_Level], 0
jna short loc_fnf_check_FAT_type
cmp byte ptr [SI][LD_FATType], 1
jb short loc_fnf_ax12h_retn
jmp short loc_fnf_check_next_cluster
loc_fnf_check_FAT_type:
cmp byte ptr [SI][LD_FATType], 3
jb short loc_fnf_ax12h_retn
loc_fnf_check_next_cluster:
mov ax, word ptr [DirBuff_Cluster]
mov dx, word ptr [DirBuff_Cluster]+2
call proc_get_next_cluster
jnc short loc_fnf_load_next_dir_cluster
or ax, ax
jz short loc_fnf_stc_retn
;mov ax, 15h ;Drive not ready or read error
cmc ;stc
loc_fnf_retn:
retn
loc_fnf_load_next_dir_cluster:
call proc_load_FAT_sub_directory
jc short loc_fnf_retn
loc_fnf_search_xorcx:
xor bx, bx
mov word ptr [FindFile_DirEntryOffset], bx
xor cx, cx
loc_fnf_search:
mov si, offset Dir_Entry_Name ; 06/02/2011
mov ax, word ptr [FindFile_AttributesMask]
call proc_find_direntry
jc short loc_cont_search_next_file
; 19/11/2010
xor ch, ch
xor dh, 0Fh
jz short loc_fnf_longname_yes
mov byte ptr [FindFile_LongNameYes], ch
jmp short loc_fnf_longname_no
loc_fnf_longname_yes:
;inc byte ptr [FindFile_LongNameYes]
mov cl, byte ptr [LongName_EntryLength]
mov byte ptr [FindFile_LongNameEntryLength], cl
loc_fnf_longname_no:
; 19/11/2010
;mov bx, word ptr [DirBuff_CurrentEntry]
mov word ptr [FindFile_DirEntryOffset], bx
mov bx, ax ; Ambigouos Filename chars used sign > 0
jmp loc_fff_fnf_return
Proc_Find_Next_File endp
proc_locate_current_dir_file proc near
; 14/08/2010 return optimization
; 25/01/2010 FS modification
; 26/09/2009
; 22/09/2009
; 19/09/2009
; 2005
; INPUT ->
; DS:SI = DOS DirEntry Format FileName
; AL = Attributes Mask
; ("AL AND EntryAttrib" must be equal to AL)
; AH = Negative Attributes Mask (If AH>0)
; ("AH AND EntryAttrib" must be ZERO)
; CH > 0 Find First Free Dir Entry or Deleted Entry
; CL = 0 -> Return the First Free Dir Entry
; CL = E5h -> Return the 1st deleted entry
; CL = FFh -> Return the 1st deleted or free entry
; CL > 0 and CL<> E5h and CL<> FFh -> Return the first
; proper entry (which fits with Atributes Masks)
; CX = 0 Find Valid File/Directory/VolumeName
; ? = Any One Char
; * = Every Chars
; OUTPUT ->
; ES:DI = Directory Entry Address (in Directory Buffer)
; DS:SI = DOS DirEntry Format FileName Address
; CF=0 -> No Error, Proper Entry,
; DL= Attributes
; DH= Previous Entry Attr (LongName Check)
; AL > 0 -> Ambiguous filename wildcard "?" used
; AH > 0 -> Ambiguous filename wildcard "*" used
; AX = 0 -> Filename full fits with directory entry
; CH = The 1st Name Char of Current Dir Entry
; CF=1 -> Proper entry not found, Error Code in AX/AL
; CL=0 and CH=0 -> Free Entry (End Of Dir)
; CL=0 and CH=E5h -> Deleted Entry fits with filters
; CL >0 -> Entry not found, CH invalid
; CF=0
; BX = Current Directory Entry
mov word ptr [DirBuff_EntryCounter], 0 ; Zero Based
;push ds
;pop es
mov word ptr [CDLF_FNAddress], si
mov word ptr [CDLF_AttributesMask], ax
mov word ptr [CDLF_DEType], cx
;22/9/2009
mov bh, byte ptr [Current_Drv]
cmp byte ptr [DirBuff_ValidData], 0
jna short loc_lcdf_reload_current_directory
mov bl, byte ptr [DirBuff_Drv]
sub bl, 'A'
cmp bh, bl
jne short loc_lcdf_reload_current_directory
mov dx, word ptr [DirBuff_Cluster]
cmp dx, word ptr [Current_Dir_FCluster]
jne short loc_lcdf_reload_current_directory
mov dx, word ptr [DirBuff_Cluster]+2
cmp dx, word ptr [Current_Dir_FCluster]+2
je short loc_cdir_locatefile_search
loc_lcdf_reload_current_directory:
;22/9/2009
xor bl, bl
mov si, offset Logical_DosDisks
add si, bx
call proc_reload_current_directory
jnc short loc_locatefile_search_again
retn
loc_cdir_locatefile_search:
xor bx, bx
call proc_find_direntry
jnc short loc_cdir_locate_file_retn
push ds
pop es
loc_locatefile_check_stc_reason:
or ch, ch
jz short loc_cdir_locate_file_stc_retn
loc_locatefile_check_next_entryblock:
mov bh, byte ptr [Current_Drv]
xor bl, bl
mov si, offset Logical_DosDisks
add si, bx
;25/01/2010 FS modification
cmp byte ptr [Current_Dir_Level], 0
jna short loc_locatefile_check_FAT_type
; 14/08/2010
cmp byte ptr [Current_FATType], 1
jnb short loc_locatefile_load_subdir_cluster
retn
loc_locatefile_check_FAT_type:
cmp byte ptr [Current_FATType], 3
jb short loc_cdir_locate_file_retn
loc_locatefile_load_subdir_cluster:
mov ax, word ptr [DirBuff_Cluster]
mov dx, word ptr [DirBuff_Cluster]+2
call proc_get_next_cluster
jnc short loc_locatefile_next_cluster
or ax, ax
jnz short loc_locatefile_drive_not_ready_read_err
stc
loc_locatefile_file_notfound:
mov ax, 2 ; File/Directory/VolName not found
retn
loc_locatefile_drive_not_ready_read_err:
; mov ax, 15h ;Drive not ready or read error
loc_cdir_locate_file_stc_retn:
cmc ;stc
loc_cdir_locate_file_retn:
retn
loc_locatefile_next_cluster:
call proc_load_FAT_sub_directory
;jc short loc_locatefile_drive_not_ready_read_err
jc short loc_cdir_locate_file_retn
loc_locatefile_search_again:
mov si, word ptr [CDLF_FNAddress]
mov ax, word ptr [CDLF_AttributesMask]
mov cx, word ptr [CDLF_DEType]
jmp short loc_cdir_locatefile_search
CDLF_FNAddress: dw 0
CDLF_AttributesMask: dw 0
CDLF_DEType: dw 0
proc_locate_current_dir_file endp
proc_find_direntry proc near
; 14/08/2010 'loc_find_dir_proper_direntry' relocation
; 18/07/2010 -> Bugfix (attributes 'and mask' AL)
; (longname entry was returning as found, while al=0)
; 13/07/2010 ('add di, 32' was duplicated) bugfix
; 28/02/2010 (DirBuff_EntryCounter -> total count)
;
; 19/09/2009
; 2005
; INPUT -> DS:SI = Sub Dir or File Name Address
; AL = Attributes Mask
; ("AL AND EntryAttrib" must be equal to AL)
; AH = Negative Attributes Mask (If AH>0)
; ("AH AND EntryAttrib" must be ZERO)
; CH > 0 Find First Free Dir Entry or Deleted Entry
; CL = 0 -> Return the First Free Dir Entry
; CL = E5h -> Return the 1st deleted entry
; CL = FFh -> Return the 1st deleted or free entry
; CL > 0 and CL<> E5h and CL<> FFh -> Return the first
; proper entry (which fits with Atributes Masks)
; CX = 0 Find Valid File/Directory/VolumeName
; ? = Any One Char
; * = Every Chars
; BX = Current Dir Entry
;
; RETURN ->
; ES:DI = Directory Entry Address (in DirectoryBuffer)
; DS:SI = Sub Dir or File Name Address
; CF=0 -> No Error, Proper Entry,
; DL= Attributes
; DH= Previous Entry Attr (LongName Check)
; AL > 0 -> Ambiguous filename wildcard "?" used
; AH > 0 -> Ambiguous filename wildcard "*" used
; AX = 0 -> Filename full fits with directory entry
; BX= CurrentDirEntry
; CH = The 1st Name Char of Current Dir Entry
; CF=1 -> Proper entry not found, Error Code in AX/AL
; CL=0 and CH=0 -> Free Entry (End Of Dir)
; CL=0 and CH=E5h -> Deleted Entry fits with filters
; CL > 0 -> Entry not found, CH invalid
; CF
; push cs
; pop ds
mov word ptr [DirBuff_CurrentEntry], bx
cmp bx, word ptr [DirBuff_LastEntry]
ja loc_ffde_stc_retn_255
mov di, word ptr [Directory_Buffer]
mov es, di
xor di, di
mov word ptr [FDE_AttrMask], ax
mov ax, 32
mov byte ptr [PreviousAttr], ah
mov word ptr [AmbiguousFileName], di
mul bx
add di, ax
or ch, ch
jnz loc_find_free_deleted_entry_0
or cl, cl
jnz loc_ffde_stc_retn_255
check_find_dir_entry:
mov ax, word ptr [FDE_AttrMask]
push si
mov ch, byte ptr ES:[DI]
cmp ch, 0 ; Is it never used entry?
jna short pop_si_loc_find_direntry_stc_retn
mov dl, byte ptr ES:[DI]+0Bh
cmp ch, 0E5h ; Is it a deleted file?
je short loc_find_dir_next_entry_prevdeleted
; 17/10/2009 save longname sub component
cmp dl, 0Fh
jne short loc_check_attributes_mask
call proc_save_longname_sub_component
loc_check_attributes_mask:
mov dh, al
and dh, dl
cmp al, dh
jne loc_find_dir_next_entry
and ah, dl
jnz loc_find_dir_next_entry
cmp dl, 0Fh
jne short pass_direntry_attr_check
; 18/07/2010 Bugfix for AX=0 input and longname
cmp al, 0Fh ; AL = 0Fh -> find long name
jne loc_find_dir_next_entry
;
pop si
xor ax, ax
mov dh, byte ptr [PreviousAttr]
mov word ptr [DirBuff_CurrentEntry], bx
retn
pass_direntry_attr_check:
mov dx, di
mov cx, 8
loc_lodsb_find_dir:
lodsb
cmp al, '*'
jne short pass_fde_ambiguous1_check
inc byte ptr [AmbiguousFileName]+1
jmp short loc_check_direntry_extension
pass_fde_ambiguous1_check:
cmp al, '?'
jne short pass_fde_ambiguous2_check
inc byte ptr [AmbiguousFileName]
cmp byte ptr ES:[DI], 20h
jna short loc_find_dir_next_entry_dx
jmp short loc_scasb_find_dir_inc_di
pass_fde_ambiguous2_check:
cmp al, 20h
jne short loc_scasb_find_dir
cmp byte ptr ES:[DI], 20h
jne short loc_find_dir_next_entry_dx
jmp short loc_check_direntry_extension
pop_si_loc_find_direntry_stc_retn:
pop si
jmp short loc_find_direntry_stc_retn
loc_find_dir_next_entry_prevdeleted:
or dl, 80h ; Bit 7 -> deleted entry sign
jmp short loc_find_dir_next_entry
loc_scasb_find_dir:
cmp al, byte ptr ES:[DI]
jne short loc_find_dir_next_entry_dx
loc_scasb_find_dir_inc_di:
inc di
loop loc_lodsb_find_dir
loc_check_direntry_extension:
pop si
push si
add si, 8
mov di, dx
add di, 8
mov cl, 3
loc_lodsb_find_dir_ext:
lodsb
cmp al, '*'
jne short pass_fde_ambiguous3_check
inc byte ptr [AmbiguousFileName]+1
jmp short loc_find_dir_proper_direntry
pass_fde_ambiguous3_check:
cmp al, '?'
jne short pass_fde_ambiguous4_check
inc byte ptr [AmbiguousFileName]
cmp byte ptr ES:[DI], 20h
jna short loc_find_dir_next_entry_dx
jmp short loc_scasb_find_dir_ext_inc_di
pass_fde_ambiguous4_check:
cmp al, 20h
jne short loc_scasb_find_dir_ext
cmp byte ptr ES:[DI], 20h
jne short loc_find_dir_next_entry_dx
; 14/08/2010
loc_find_dir_proper_direntry:
xor cl, cl
loc_find_dir_proper_direntry_1:
pop si
mov di, dx
mov ch, byte ptr ES:[DI]
mov dl, byte ptr ES:[DI]+0Bh
mov ax, word ptr [AmbiguousFileName]
loc_find_dir_proper_direntry_2:
mov dh, byte ptr [PreviousAttr]
mov word ptr [DirBuff_CurrentEntry], bx
retn
loc_find_dir_next_entry_dx:
mov di, dx
loc_find_dir_next_entry:
pop si
add di, 32
inc word ptr [DirBuff_EntryCounter]
inc bx
cmp bx, word ptr [DirBuff_LastEntry]
ja short loc_ffde_stc_retn_255
mov byte ptr [PreviousAttr], dl ; LongName check
jmp check_find_dir_entry
loc_scasb_find_dir_ext:
cmp al, byte ptr ES:[DI]
jne short loc_find_dir_next_entry_dx
loc_scasb_find_dir_ext_inc_di:
inc di
loop loc_lodsb_find_dir_ext
; 14/08/2010
jmp short loc_find_dir_proper_direntry_1
loc_ffde_stc_retn_255:
mov cx, 0FFFFh
loc_find_direntry_stc_retn:
loc_check_ffde_retn_1:
mov ax, 2 ; File Not Found
mov dh, byte ptr [PreviousAttr]
mov word ptr [DirBuff_CurrentEntry], bx
stc
retn
loc_find_free_deleted_entry_0:
mov ax, word ptr [FDE_AttrMask]
mov ch, byte ptr ES:[DI]
mov dl, byte ptr ES:[DI]+0Bh
or cl, cl
jz short loc_check_ffde_0_repeat
;cmp cl, 0E5h
;je short pass_loc_check_ffde_0_err
cmp cl, 0FFh
je short loc_find_free_deleted_entry_1
jmp short pass_loc_check_ffde_0_err
loc_check_ffde_0_repeat:
or ch, ch
jnz short loc_check_ffde_0_next
loc_check_ffde_retn_2:
xor ax, ax
mov dh, byte ptr [PreviousAttr]
mov word ptr [DirBuff_CurrentEntry], bx
retn
loc_check_ffde_0_next:
inc bx
; 13/07/2010 -> duplicated 'add di, 32' removed
add di, 32
; 28/02/2010
inc word ptr [DirBuff_EntryCounter]
;
cmp bx, word ptr [DirBuff_LastEntry]
ja short loc_ffde_stc_retn_255
mov byte ptr [PreviousAttr], dl
mov ch, byte ptr ES:[DI]
mov dl, byte ptr ES:[DI]+0Bh
jmp short loc_check_ffde_0_repeat
loc_find_free_deleted_entry_1:
xor dl, dl
loc_find_free_deleted_entry_2:
or ch, ch
jz short loc_check_ffde_retn_2
cmp ch, 0E5h
je short loc_check_ffde_retn_2
inc bx
add di, 32
cmp bx, word ptr [DirBuff_LastEntry]
ja short loc_ffde_stc_retn_255
mov ch, byte ptr ES:[DI]
jmp short loc_find_free_deleted_entry_2
pass_loc_check_ffde_0_err:
cmp ch, cl
je short loc_check_ffde_attrib
inc bx
add di, 32
cmp bx, word ptr [DirBuff_LastEntry]
ja short loc_ffde_stc_retn_255
mov byte ptr [PreviousAttr], dl
mov ch, byte ptr ES:[DI]
mov dl, byte ptr ES:[DI]+0Bh
jmp short pass_loc_check_ffde_0_err
loc_check_ffde_attrib:
mov dh, al
and dh, dl
cmp al, dh
jne short loc_check_ffde_0_next
and ah, dl
jnz short loc_check_ffde_0_next
xor cl, cl
jmp short loc_check_ffde_retn_2
PreviousAttr: db 0
FDE_AttrMask: dw 0
AmbiguousFileName: dw 0
proc_find_direntry endp
proc_convert_file_name proc near
; 06/10/2009
; INPUT -> DS:SI = Dot File Name Location
; ES:DI = Dir Entry Format File Name Location
; OUTPUT -> ES:DI = Dir Entry Format File Name Location
; DS:SI = Dot File Name Location (capitalized)
; (CX and AL will be changed)
; 2005
push si
push di
mov cx, 11
mov al, 20h
rep stosb
pop di
push di
mov cx, 12
loc_check_first_dot:
mov al, byte ptr [SI]
cmp al, 2Eh
jne short pass_check_first_dot
mov byte ptr ES:[DI], al
inc di
inc si
loop loc_check_first_dot
jmp short stop_convert_file
loc_get_fchar:
mov al, byte ptr [SI]
pass_check_first_dot:
cmp al, 61h
jb short pass_name_capitalize
cmp al, 7Ah
ja short pass_name_capitalize
and al, 0DFh
mov byte ptr [SI], al
pass_name_capitalize:
cmp al, 21h
jb short stop_convert_file
cmp al, 2Eh
jne short pass_dot_space
add_space:
cmp cx, 4
jna short inc_and_loop
inc di
dec cx
jmp short add_space
pass_dot_space:
mov byte ptr ES:[DI], al
loc_after_double_dot:
inc di
inc_and_loop:
inc si
loop loc_get_fchar
stop_convert_file:
pop di
pop si
retn
proc_convert_file_name endp
Get_File_Name proc near
; INPUT -> DS:SI -> Directory Entry Format File Name
; ES:DI -> DOS Dot File Name Address
;
; OUTPUT -> DS:SI -> DOS Dot File Name Address
; ES:DI -> Directory Entry Format File Name
; 2005
push ds
push es
push si
push di
lodsb
cmp al, 20h
jna short pass_gfn_ext
push si
stosb
mov cx, 7
loc_gfn_next_char:
lodsb
cmp al, 20h
jna short pass_gfn_fn
stosb
loop loc_gfn_next_char
pass_gfn_fn:
pop si
add si, 7
lodsb
cmp al, 20h
jna short pass_gfn_ext
mov ah, "."
xchg ah, al
stosw
lodsb
cmp al, 20h
jna short pass_gfn_ext
stosb
lodsb
cmp al, 20h
jna short pass_gfn_ext
stosb
pass_gfn_ext:
xor al, al
stosb
pop si
pop di
pop ds
pop es
retn
Get_File_Name endp
proc_reload_current_directory proc near
; 13/06/2010 loc_reload_FAT_sub_directory bugfix
; 24/04/2010 FS recognition, bugfix
; 03/10/2009 Current_FATType
; 23/09/2009
; 22/09/2009
; INPUT ->
; DS:SI = Dos drive description table address
;
;mov al, byte ptr [SI][LD_FATType]
mov al, byte ptr [Current_FATType]
cmp al, 2
ja short loc_reload_FAT_sub_directory
mov ah, byte ptr [Current_Dir_Level]
or al, al
jz short loc_reload_FS_directory
or ah, ah
jnz short loc_reload_FAT_sub_directory
loc_reload_FAT_12_16_root_directory:
call proc_load_FAT_root_directory
retn
loc_reload_FS_directory:
and ah, ah
jnz short loc_reload_FS_sub_directory
loc_reload_FS_root_directory:
call proc_load_FS_root_directory
retn
loc_reload_FS_sub_directory:
mov ax, word ptr [Current_Dir_FCluster]
mov dx, word ptr [Current_Dir_FCluster]+2
call proc_load_FS_sub_directory
retn
loc_reload_FAT_sub_directory:
mov ax, word ptr [Current_Dir_FCluster]
mov dx, word ptr [Current_Dir_FCluster]+2
call proc_load_FAT_sub_directory
retn
proc_reload_current_directory endp
proc_change_current_directory proc near
; 18/09/2011
; 17/09/2011
; 25/01/2010 Singlix FS Change DIR functionality
; 29/11/2009 ->
; INPUT -> AH = CD COMMAND (or another command) sign
; cmp byte ptr [CD_COMMAND], 0CDh
; 'CD' command sign is for restoring cdir from
; or saving cdir to DOS Drv Description table
; 17/10/2009
; 16/10/2009 proc_parse_dir_name
; 14/10/2009 '.' & '..' modifications
; in proc_parse_dir_name
; 11/10/2009
; 04/10/2009
; INPUT -> DS:SI = Directory string
; (ES=CS)
; OUTPUT ->
; ES:DI = DOS Drive Description Table (ES=CS)
; stc -> error
; AX = Error code
; clc -> succesful
; DS:SI = PATH_Array
; DX:AX = Current Directory First Cluster
; BH = Current Drive, BL = 0
;
; 29/11/2009
mov byte ptr CS:[CD_COMMAND], ah
; 14/10/2009
cmp byte ptr [SI], "/"
jne short loc_ccd_cdir_level
inc si
xor al, al
jmp short loc_ccd_parse_path_name
loc_ccd_cdir_level:
mov al, byte ptr CS:[Current_Dir_Level]
loc_ccd_parse_path_name:
; 17/10/2009
mov ah, al
mov di, offset PATH_Array
; push cs
; pop es
; Reset directory levels > cdir level
; is this required !?
;
; Relations:
; MAINPROG.ASM (pass_ccdrv_reset_cdir_FAT_fcluster)
; proc_parse_dir_name,
; proc_change_current_directory (this procedure)
; proc_change_prompt_dir_string
xor ch, ch
mov cl, al
inc cl
shl cl, 1
shl cl, 1
shl cl, 1
shl cl, 1
add di, cx
mov cl, 7
sub cl, al
shl cl, 1
shl cl, 1
shl cl, 1
push ax
xor ax, ax
rep stosw
pop ax
; 17/10/2009
cmp byte ptr [SI], 20h
; 18/09/2011
cmc
jnc short pass_ccd_parse_dir_name
; 16/10/2009
; push cs
; pop es
mov di, offset PATH_Array
;push di
; DS:SI = Path name
; AL = CCD_Level
call proc_parse_dir_name
; AL = CCD_Level
; AH = Last_Dir_Level
;pop di
push cs
pop ds
pass_ccd_parse_dir_name:
pushf ; 18/09/2011
;mov byte ptr [CCD_Level], al
;mov byte ptr [Last_Dir_Level], ah
mov word ptr [CCD_Level], ax
xor bl, bl
mov bh, byte ptr [Current_Drv]
mov si, offset Logical_DOSDisks
add si, bx
popf ; 18/09/2011
jc short loc_ccd_bad_path_name_retn
mov word ptr [CCD_DriveDT], si
;
cmp al, 7
jb short loc_ccd_load_child_dir
loc_ccd_bad_path_name_retn:
; 18/09/2011
xchg si, di
xor ah, ah
mov al, 18h ; DOS Error Code : Bad request structure length
stc
loc_ccd_retn_p:
retn
loc_ccd_load_child_dir:
; 16/10/2009
; al = CCD_Level
or al, al
jz short loc_ccd_load_root_dir
; 18/09/2011
mov si, di ; offset PATH_Array
mov cx, ax
cbw
; mov si, offset PATH_Array ; 18/09/2011
shl al, 1
shl al, 1
shl al, 1
shl al, 1
add si, ax
mov ax, word ptr [SI]+12
mov dx, word ptr [SI]+14
cmp cl, ch
je loc_ccd_load_sub_directory
mov word ptr [Current_Dir_FCluster], ax
mov word ptr [Current_Dir_FCluster]+2, dx
;
loc_ccd_load_child_dir_next:
add si, 16
mov al, 00010000b ; 10h (Attrib AND mask)
;mov ah, 11001000b ; C8h
mov ah, 00001000b ; 08h (Attrib NAND, AND=>zero mask)
xor cx, cx
call proc_locate_current_dir_file
; ES=DS if cf=1 ; ES<>DS if cf=0
jnc short loc_ccd_set_dir_cluster_ptr
mov di, word ptr [CCD_DriveDT] ; 18/09/2011
mov ah, byte ptr [CCD_Level]
cmp al, 3 ; AL=2 => File not found error
jb short loc_ccd_path_not_found_retn
stc
retn
loc_ccd_path_not_found_retn:
mov al, 3 ; Path not found
retn
loc_ccd_load_FAT_root_dir:
cmp byte ptr [Current_FATType], 2
ja short loc_ccd_load_FAT32_root_dir
;mov si, word ptr [CCD_DriveDT]
;push si
call proc_load_FAT_root_directory
;pop di ; Dos Drv Description Table
pass_ccd_load_FAT_root_dir:
mov di, si
mov si, offset PATH_Array
push ds
pop es
jc short loc_ccd_retn_p
xor ax, ax
xor dx, dx
jmp short loc_ccd_set_cdfc
loc_ccd_load_root_dir:
;25/01/2010
cmp byte ptr [Current_FATType], 1
jnb short loc_ccd_load_FAT_root_dir
loc_ccd_load_FS_root_dir:
call proc_load_FS_root_directory
jmp short pass_ccd_load_FAT_sub_directory
loc_ccd_load_FS_sub_directory_next:
; 25/01/2010
call proc_load_FS_sub_directory
jmp short pass_ccd_set_dir_cluster_ptr
loc_ccd_set_dir_cluster_ptr:
; ES:DI = Directory Entry
mov ax, word ptr ES:[DI]+26 ; First Cluster Low Word
mov dx, word ptr ES:[DI]+20 ; First Cluster High Word
push ds
pop es
mov si, word ptr [CCD_DriveDT]
cmp byte ptr [Current_FATType], 1
jb short loc_ccd_load_FS_sub_directory_next
;push si
call proc_load_FAT_sub_directory
;pop di ; Dos Drv Description Table
pass_ccd_set_dir_cluster_ptr:
; mov di, si ; 18/09/2011
mov si, offset PATH_Array
;push ds
;pop es
jc short loc_ccd_retn_c
mov ax, word ptr [DirBuff_Cluster]
mov dx, word ptr [DirBuff_Cluster]+2
xor bh, bh
inc byte ptr [CCD_Level]
mov bl, byte ptr [CCD_Level]
shl bl, 1
shl bl, 1
shl bl, 1
shl bl, 1
add si, bx
mov word ptr [SI]+12, ax
mov word ptr [SI]+14, dx
jmp short loc_ccd_set_cdfc
loc_ccd_load_FAT32_root_dir:
mov si, offset PATH_Array
mov ax, word ptr [SI]+12
mov dx, word ptr [SI]+14
mov si, word ptr [CCD_DriveDT]
loc_ccd_load_FAT_sub_directory:
;push si
call proc_load_FAT_sub_directory
;pop di ; Dos Drv Description Table
pass_ccd_load_FAT_sub_directory:
; mov di, si ; 18/09/2011
mov si, offset PATH_Array
push ds
pop es
jc short loc_ccd_retn_c
mov ax, word ptr [DirBuff_Cluster]
mov dx, word ptr [DirBuff_Cluster]+2
loc_ccd_set_cdfc:
xor bx, bx
mov cl, byte ptr [CCD_Level]
mov byte ptr [Current_Dir_Level], cl ; 18/09/2011
mov word ptr [Current_Dir_FCluster], ax
mov word ptr [Current_Dir_FCluster]+2, dx
loc_ccd_check_cdlevel_lastlevel:
mov ch, byte ptr [Last_Dir_Level]
cmp cl, ch
jb loc_ccd_load_child_dir_next
mov si, offset PATH_Array ; 17/09/2011
;29/11/2009 -> check cdir will be restored or saved ?
cmp byte ptr [CD_COMMAND], 0CDh ;'CD' command or another
je short loc_ccd_save_current_dir
clc
loc_ccd_retn_c:
mov di, word ptr [CCD_DriveDT] ; 18/09/2011
retn
; jne -> don't save, but restore (the previous cdir) later !
; (saving the cdir would prevent previous cdir restoration!)
loc_ccd_load_sub_directory:
;25/01/2010
mov si, word ptr [CCD_DriveDT]
cmp byte ptr [Current_FATType], 1
jnb short loc_ccd_load_FAT_sub_directory
call proc_load_FS_sub_directory
jmp short pass_ccd_load_FAT_sub_directory
loc_ccd_save_current_dir:
mov di, word ptr [CCD_DriveDT] ; 18/09/2011
;mov byte ptr [DI][LD_CDirLevel], cl
push di
;add di, LD_CurrentDirectory
add di, LD_CdirLevel ; 18/09/2011
mov byte ptr [DI], cl
inc di ; LD_CurrentDirectory
push si
mov cx, 64
rep movsw
; Current directory has been saved to
; the DOS drive description table, cdir area !
pop si ; PATH_Array
pop di ; Dos Drv Description Table
retn
CCD_Level: db 0
Last_Dir_Level: db 0
; 08/10/2009
CCD_DriveDT: dw 0
;
;29/11/2009
CD_COMMAND: db 0
proc_change_current_directory endp
proc_parse_dir_name proc near
; 18/09/2011
; 17/10/2009
; INPUT -> DS:SI = ASCIZZ Directory String
; AL = Current Directory Level
; INPUT -> ES:DI = Destination Adress
; (8 levels, each one 12+4 byte)
;
; OUTPUT -> ES:DI = Dir Entry Formatted Array
; with zero cluster pointer at the last level
; (SI, BX, CX will be changed)
; AH = Last Dir Level
; AL = Current Dir Level
;
;mov word ptr CS:[PATH_Array_Ptr], di
mov ah, al
mov word ptr CS:[PATH_CDLevel], ax
repeat_ppdn_check_slash:
lodsb
cmp al, "/"
je short repeat_ppdn_check_slash
cmp al, 21h
jb short loc_ppdn_retn ; 18/09/2011
loc_ppdn_get_dir_name:
mov cx, 12
push es
push di
push cs
pop es
mov di, offset Dir_File_Name
repeat_ppdn_get_dir_name:
stosb
lodsb
cmp al, "/"
je short loc_check_level_dot_convert_dir_name
cmp al, 20h
jna short loc_ppdn_end_of_path_scan
loop repeat_ppdn_get_dir_name
pop di
pop es
stc
loc_ppdn_retn : ; 18/09/2011
retn
loc_ppdn_end_of_path_scan:
dec si
loc_check_level_dot_convert_dir_name:
xor al, al
stosb
mov bx, si
pop di
pop es
push ds
push cs
pop ds
mov si, offset Dir_File_Name
lodsb
repeat_ppdn_name_check_dot:
cmp al, "."
jne short loc_ppdn_convert_sub_dir_name
repeat_ppdn_name_dot_dot:
lodsb
cmp al,"."
je short loc_ppdn_dot_dot
cmp al, 21h
jb short pass_ppdn_convert_sub_dir_name
loc_ppdn_convert_sub_dir_name:
mov ah, byte ptr [PATH_Level]
cmp ah, 7
jnb short pass_ppdn_convert_sub_dir_name
inc ah
mov byte ptr [PATH_Level], ah
mov si, offset Dir_File_Name
;mov di, word ptr [PATH_Array_Ptr]
mov al, 16
mul ah
or ax, ax
jz short pass_ppdn_convert_sub_dir_name
push di
add di, ax
call proc_convert_file_name
pop di
pass_ppdn_convert_sub_dir_name:
mov si, bx
pop ds
repeat_ppdn_check_last_slash:
lodsb
cmp al, "/"
je short repeat_ppdn_check_last_slash
cmp al, 21h
jnb short loc_ppdn_get_dir_name
end_of_parse_dir_name:
cmc
;mov al, byte ptr CS:[PATH_CDLevel]
;mov ah, byte ptr CS:[PATH_Level]
mov ax, word ptr CS:[PATH_CDLevel]
retn
loc_ppdn_dot_dot:
lodsb
cmp al, 21h
jb short loc_ppdn_dot_dot_prev_level
pop ds
jmp short end_of_parse_dir_name
loc_ppdn_dot_dot_prev_level:
mov ax, word ptr [PATH_CDLevel]
sub ah, 1
adc ah, 0
cmp al, ah
jna short pass_ppdn_set_al_to_ah
mov al, ah
pass_ppdn_set_al_to_ah:
mov word ptr [PATH_CDLevel], ax
jmp short pass_ppdn_convert_sub_dir_name
;PATH_Array_Ptr: dw 0
PATH_CDLevel: db 0
PATH_Level: db 0
proc_parse_dir_name endp
proc_change_prompt_dir_string proc near
; 27/03/2011 Major modification
; for INT 21h Function 47h compatibility
; (proc_get_current_directory procedure)
; 09/10/2009
; INPUT/OUTPUT => none
; it changes current directory string/text
; 2005
mov di, offset Current_Directory
mov ah, byte ptr [Current_Dir_Level]
mov si, offset PATH_Array
;push ds
;pop es
call proc_return_current_directory_string
mov byte ptr [Current_Dir_Strlen], cl
retn
proc_change_prompt_dir_string endp
proc_calculate_checksum proc near
; INPUT DS:SI = 11 byte Dos File Name location
; (in DOS Directory Entry Format)
; © Erdogan Tan [ 17-10-2009 ]
; 'ror al, 1' instruction
; © Erdogan Tan [ 20-06-2004 ]
; This 8086 assembly code is an original code
; which is adapted from C code in
; Microsoft FAT32 File System Specification
; Version 1.03, December 6, 2000
; Page 28
xor al, al
mov cx, 11
loc_next_sum:
;xor ah, ah
;test al, 1
;jz short pass_ah_80h
;mov ah, 80h
;pass_ah_80h:
;shr al, 1
ror al, 1 ; 17/10/2009
add al, byte ptr [SI]
inc si
;add al, ah
loop loc_next_sum
; al= 8 bit checksum (CRC) value
retn
proc_calculate_checksum endp
proc_find_longname proc near
; 24/01/2010 <- fs long file name
; 17/10/2009
; 2005
; INPUT ->
; DS:SI = DOS short file name address
; for example: "filename.ext"
; ES=DS=CS
; OUTPUT ->
; DS:SI = ASCIZZ longname address (cf=0)
; cf=1, error number returns in AL
; AL= 0 & CF=1 -> longname not found
; the file/directory has no longname
; 24/01/2010
; cf=0 -> AL = FAT Type
loc_find_long_name:
; 17/10/2009
; ASCIIZ string will be returned
; as LongFileName
; reset is not needed
;mov cx, 33
;mov di, Offset LongFileName
;mov ax, 0
;rep stosw
;mov byte ptr [LongNameFound],0
;DS:SI = ASCIIZ file/directory name address
; AL = Attributes AND mask
; AH = Negative attributes mask (nand)
mov ax, 0800h
; it must not be volume name or longname
call proc_find_first_file
push ds
pop es
jc short loc_fln_retn
; 24/01/2010
loc_fln_check_FAT_Type:
cmp byte ptr [Current_FATType], 1
jnb short loc_fln_check_longname_yes_sign
; 24/01/2010
call proc_get_fs_longname
retn
loc_fln_check_longname_yes_sign:
or ch, ch
jnz short loc_fln_check_longnamefound_number
loc_fln_longname_not_found_retn:
xor ax, ax ; cf=1 & al = 0 -> longname not found
stc
loc_fln_retn:
retn
loc_fln_check_longnamefound_number:
; 'LongNameFound' is set by
; by 'proc_same_longname_sub_component'
; which is called from
; 'proc_find_directory_entry'
; which is called from
; 'proc_find_first_file'
; It must be 1 if the longname is valid
cmp byte ptr [LongNameFound], 1
jne short loc_fln_longname_not_found_retn
loc_fln_calculate_checksum:
call proc_calculate_checksum
; al = shortname checksum
loc_fln_longname_validation:
; 'LFN_Checksum' has been set already
; by 'proc_same_longname_sub_component'
; which is called from
; 'proc_find_directory_entry'
; which is called from
; 'proc_find_first_file'
cmp byte ptr [LFN_Checksum], al
jne short loc_fln_longname_not_found_retn
mov si, offset LongFileName
; 24/01/2010
mov al, byte ptr [Current_FATType]
retn
proc_find_longname endp
proc_save_longname_sub_component proc near
; 28/02/2010 longname entry length
; 19/10/2009 movsw
; 17/10/2009
; INPUT -> ES:DI = Directory Entry
; call from 'proc_find_directory_entry'
; If last entry returns with
; LongnameFound = 1 and
; LFN_Checksum = the next shortname checksum
; long name is valid.
; If a longname is longer than 65 bytes
; it is invalid for trdos. (>45h)
push es
push ds
push di
push si
;push bx
;push cx
;push dx
push ax
mov al, byte ptr ES:[DI] ; LDIR_Order
cmp al, 41h ;40h (last long entry sign) +1
jb short pass_pslnsc_last_long_entry
; 28/02/2010
mov ah, al
sub ah, 40h
mov byte ptr [LongName_EntryLength], ah
;
cmp al, 45h ;40h (last long entry sign) +5
; Max 130 byte length is usable in TRDOS
; 26*5 = 130
ja short loc_pslnsc_retn
and al, 07h ; 0Fh
mov byte ptr [LongNameFound], al
dec al
mov cx, 26
mul cl
mov si, offset LongFileName
add si, ax
add si, cx
; to make is an ASCIZZ string
; with ax+26 bytes length
mov word ptr [SI], 0
jmp short loc_pslsc_move_ldir_name2
pass_pslnsc_last_long_entry:
cmp al, 04h
ja short loc_pslnsc_retn
dec byte ptr [LongNameFound]
cmp al, byte ptr [LongNameFound]
jne short loc_pslnsc_retn
loc_pslsc_move_ldir_name1:
dec al
mov ah, 26
mul ah
loc_pslsc_move_ldir_name2:
mov cl, byte ptr ES:[DI]+0Dh
mov byte ptr [LFN_CheckSum], cl
push ds
push es
pop ds
pop es
mov si, di ; LDIR_Order
mov di, offset LongFileName
add di, ax
inc si
mov cx, 5 ; chars 1 to 5
loc_pslsc_ldir_name1:
movsw
loop loc_pslsc_ldir_name1
add si, 3
mov cx, 6 ; char 6 to 11
loc_pslsc_ldir_name2:
movsw
loop loc_pslsc_ldir_name2
inc si
inc si
movsw ; char 12
movsw ; char 13
loc_pslnsc_retn:
pop ax
;pop dx
;pop cx
;pop bx
pop si
pop di
pop ds
pop es
retn
proc_save_longname_sub_component endp
proc_parse_pathname proc near
; 10/09/2011
; 19/06/2011
; 27/01/2011
; 20/11/2010
; 04/08/2010 No-path modification
; 21/04/2010 (loc_ppn_invalid_drive -> retn)
; 27-11-2009
; 5-12-2004
; Input DS:SI -> Beginning of ASCIIZ pathname string
; ES:DI -> Destination Address
; is TR-DOS Findfile data buffer
; Output, CF = 1 : Error, Error Code in AX (AL)
;
push di
mov cx, 40
xor ax, ax
rep stosw ; Reset the pathname structure in TR-DOS Findfile data buffer
pop di
mov ax, word ptr [SI]
cmp ah, ':'
je short loc_ppn_change_drive
mov al, byte ptr CS:[Current_Drv]
jmp short pass_ppn_change_drive
pass_ppn_cdir:
mov si, word ptr CS:[First_Path_Pos]
mov al, byte ptr [SI]
loc_ppn_get_filename:
add di, 65 ; FindFile_FileName location
; mov cx, 12 ; TRDOS Filename length must not be more than 12 bytes
mov cl, 12
loc_ppn_get_fnchar_next:
;mov byte ptr ES:[DI], al
;inc di
stosb
inc si
mov al, byte ptr [SI]
; 27/01/2011
cmp al, 21h
;jb short loc_ppn_get_fname_finish
jb short loc_ppn_clc_return
loop short loc_ppn_get_fnchar_next
;loc_ppn_get_fname_finish:
;xor al, al
;mov byte ptr ES:[DI], al
loc_ppn_return:
retn
loc_ppn_change_drive:
and al, 0DFh
sub al, 'A'; A:
jc short loc_ppn_invalid_drive
cmp byte ptr CS:[Last_Dos_DiskNo], al
jb short loc_ppn_invalid_drive
; 04/08/2010
inc si
inc si
mov ah, byte ptr [SI]
; 19/06/2011
cmp ah, 21h
jnb short pass_ppn_change_drive
loc_ppn_cmd_failed:
; 19/06/2011
; File or directory name is not existing
mov byte ptr ES:[DI], al ; Drv
mov ax, 1
; TR-DOS Error Code 1h = Bad Command Argument
; MS-DOS Error Code 1h : Invalid Function Number
;stc
; (MainProg ErrMsg: "Bad command or file name!")
retn
pass_ppn_change_drive:
mov word ptr CS:[First_Path_Pos], si
mov word ptr CS:[Last_Slash_Pos], 0
;mov byte ptr ES:[DI], al ; FindFile_Drv
;inc di
stosb
mov al, byte ptr [SI]
loc_scan_ppn_dslash:
cmp al, '/'
jne short loc_scan_next_slash_pos
mov word ptr CS:[Last_Slash_Pos], si
loc_scan_next_slash_pos:
inc si
mov al, byte ptr [SI]
cmp al, 20h
ja short loc_scan_ppn_dslash
cmp word ptr CS:[Last_Slash_Pos], 0
jna short pass_ppn_cdir
mov ax, word ptr CS:[Last_Slash_Pos]
push ax
mov si, word ptr CS:[First_Path_Pos]
sub ax, si
inc ax
;10/09/2011
cmp ax, 64
ja short loc_ppn_invalid_drive_stc
;
;mov cx, ax
mov cl, al
push di ; Dest Dir String Location (65 byte)
rep movsb
;mov byte ptr ES:[DI], ah ; 0, End of Dir String
pop di
pop si ; pushed ax
inc si
mov al, byte ptr [SI]
; 19/06/2011
cmp al, 21h
jnb short loc_ppn_get_filename
loc_ppn_clc_return:
clc
retn
loc_ppn_invalid_drive_stc: ; 10/09/2011
cmc
loc_ppn_invalid_drive:
; The Drive Letter/Char < "A" or > "Z"
mov ax, 0Fh
; MS-DOS Error Code 0Fh = Disk Drive Invalid
;stc
; (MainProg ErrMsg: "Drive not ready or read error!")
retn
;loc_ppn_drive_not_ready:
; Drive is not ready or read error (from disk io process)
; or Drive Number > Last_Dos_DiskNo
; mov ax, 15h
; MS-DOS Error Code 15h = Drive Not Ready
; stc
; (MainProg ErrMsg: "Drive not ready or read error!")
; retn
First_Path_Pos: dw 0
Last_Slash_Pos: dw 0
proc_parse_pathname endp
proc_delete_longname proc near
; 01/08/2011
; 12/04/2010
; 28/03/2010
; 14/03/2010
; INPUT
; AX = Directory Entry Number
; OUTPUT
; clc -> ok
; stx -> error code in AL
; ES, DI, DX, AX, CX, BX will be destroyed
mov word ptr [DLN_EntryNumber], ax
;12/04/2010
mov byte ptr [DLN_40h], 40h
call proc_locate_current_dir_entry
jnc short loc_dln_check_attributes
retn
loc_dln_longname_not_found:
xor ah, ah
mov al, 02h
stc
retn
loc_dln_check_attributes:
mov al, 0Fh
mov ah, byte ptr ES:[DI]+0Bh
cmp ah, al
jne short loc_dln_longname_not_found
mov ah, byte ptr ES:[DI]
sub ah, byte ptr [DLN_40h]
jna short loc_dln_longname_not_found
cmp ah, 14h ; 84-64=20 -> 20*13=260 bytes
ja short loc_dln_longname_not_found
mov byte ptr ES:[DI], 0E5h
mov byte ptr [DirBuff_ValidData], 2
; 12/04/2010
mov byte ptr [DLN_40h], 0 ; 40h -> 0
loc_dln_delete_next_ln_entry:
cmp ah, 1
jna short loc_dln_longname_retn
loc_dln_delete_next_ln_entry_0:
inc word ptr [DLN_EntryNumber]
mov ax, word ptr [DLN_EntryNumber]
call proc_locate_current_dir_entry
jnc short loc_dln_check_attributes
loc_dln_longname_stc_retn:
retn
loc_dln_longname_retn:
;01/08/2011
;cmp byte ptr [DirBuff_ValidData], 2
;jne short loc_dln_longname_retn_xor_ax
call proc_save_directory_buffer
jc short loc_dln_longname_stc_retn
loc_dln_longname_retn_xor_ax:
xor ax, ax
retn
DLN_EntryNumber: dw 0
;12/04/2010
DLN_40h: db 0 ; 40h
proc_delete_longname endp
proc_locate_current_dir_entry proc near
; 01/08/2011
; 17/04/2010 BugFix
; 12/04/2010 BugFix
; 28/03/2010
; 14/03/2010
; 07/03/2010
; INPUT ->
; AX = Directory Entry Number
; OUTPUT ->
; ES:DI -> Directory Entry
; DX:AX = Dir Buff Cluster
; BX = Dir Buff Entry Offset
; CX = DirBuff Valid data
; If clc and Cl =2 then
; directory buffer modified
; and must be written to disk
; if cl= 1 then dir buffer
; has been written already
; stc -> Error code in AL
; 12/04/2010
loc_locate_current_dir_entry:
push si
mov cx, ax
mov dx, 32
mul dx
mov word ptr [LCDE_ByteOffset], ax
mov word ptr [LCDE_ByteOffset]+2, dx
mov bh, byte ptr [Current_Drv]
xor bl, bl
mov al, byte ptr [DirBuff_Drv]
sub al, 'A'
mov si, offset Logical_DosDisks
add si, bx
cmp bh, al
jne short loc_lcde_reload_current_directory
loc_lcde_cdl_check:
cmp byte ptr [Current_Dir_Level], 0
ja short loc_lcde_calc_dirbuff_cluster_offset
mov ax, word ptr [SI][LD_BPB][RootDirEnts]
dec ax
xor dx, dx
cmp ax, cx ; cx = Directory Entry Number
jb short loc_lcde_stc_12h_retn
mov word ptr [LCDE_EntryOffset], cx
xor ax, ax
jmp short loc_lcde_check_dir_buffer_cluster
loc_lcde_stc_12h_retn:
pop si
mov bx, cx
mov cx, dx
mov ax, 12h ; AL= 12h No more files
retn
loc_lcde_calc_dirbuff_cluster_offset:
mov bl, byte ptr [SI][LD_BPB][SecPerClust]
xor bh, bh
mov ax, word ptr [SI][LD_BPB][BytesPerSec]
mul bx
or dx, dx ; If bytes per cluster > 32KB it is invalid
jnz short loc_lcde_invalid_format
mov cx, ax ; BYTES PER CLUSTER
mov ax, word ptr [LCDE_ByteOffset]
mov dx, word ptr [LCDE_ByteOffset]+2
call RX_DOS_DIV32
or dx, dx
jnz short loc_lcde_invalid_format
mov word ptr [LCDE_ClusterSN], ax
; 17/04/2010
mov ax, 32
xchg ax, bx
div bx
mov word ptr [LCDE_EntryOffset], ax
;
loc_lcde_get_current_sub_dir_fcluster:
mov ax, word ptr [Current_Dir_FCluster]
mov dx, word ptr [Current_Dir_FCluster]+2
loc_lcde_get_next_cluster:
cmp word ptr [LCDE_ClusterSN], 0
jna short loc_lcde_check_dir_buffer_cluster
mov word ptr [LCDE_Cluster], ax
mov word ptr [LCDE_Cluster]+2, dx
call proc_get_next_cluster
jc short loc_lcde_check_gnc_error
dec word ptr [LCDE_ClusterSN]
jmp short loc_lcde_get_next_cluster
loc_lcde_reload_current_directory:
push cx
call proc_reload_current_directory
pop cx
jnc short loc_lcde_cdl_check
pop si
retn
loc_lcde_check_gnc_error:
or ax, ax
jnz short loc_lcde_drive_not_ready_read_err
dec word ptr [LCDE_ClusterSN]
jnz short loc_lcde_invalid_format
mov ax, word ptr [LCDE_Cluster]
mov dx, word ptr [LCDE_Cluster]+2
jmp short loc_lcde_check_dir_buffer_cluster
loc_lcde_invalid_format:
mov ax, 0Bh ; MSDOS Error code: Invalid Format
;mov ax, 0Dh ; MSDOS Error code: Invalid Data
;xor dx, dx
loc_lcde_drive_not_ready_read_err:
stc
pop si
retn
loc_lcde_check_dir_buffer_cluster:
cmp ax, word ptr [DirBuff_Cluster]
jne short loc_lcde_load_dir_cluster
cmp dx, word ptr [DirBuff_Cluster]+2
jne short loc_lcde_load_dir_cluster
cmp byte ptr [DirBuff_ValidData], 0
ja short lcde_check_dir_buffer_cluster_next
cmp byte ptr [Current_Dir_Level], 0
ja short loc_lcde_load_dir_cluster_0
mov ax, word ptr [SI][LD_RootBegin]
mov dx, word ptr [SI][LD_RootBegin]+2
jmp short loc_lcde_load_dir_cluster_1
lcde_check_dir_buffer_cluster_next:
mov bx, word ptr [LCDE_EntryOffset]
cmp bx, word ptr [DirBuff_LastEntry]
ja short loc_lcde_invalid_format
mov ax, 32
mul bx
or dx, dx
jnz short loc_lcde_invalid_format
mov di, word ptr [Directory_Buffer]
mov es, di
mov di, ax
loc_lcde_dir_buffer_last_check:
mov ax, word ptr [DirBuff_Cluster]
mov dx, word ptr [DirBuff_Cluster]+2
mov bx, word ptr [LCDE_EntryOffset]
mov cl, byte ptr [DirBuff_ValidData]
xor ch, ch
loc_lcde_retn:
pop si
retn
loc_lcde_load_dir_cluster:
; 01/08/2011
;cmp byte ptr [DirBuff_ValidData], 2
;jne short loc_lcde_load_dir_cluster_n2
push dx
push ax
call proc_save_directory_buffer
pop ax
pop dx
jc short loc_lcde_retn
loc_lcde_load_dir_cluster_n2:
mov byte ptr [DirBuff_ValidData], 0
loc_lcde_load_dir_cluster_0:
mov word ptr [DirBuff_Cluster], ax
mov word ptr [DirBuff_Cluster]+2, dx
sub ax, 2
sbb dx, 0
xor bh, bh
mov bl, byte ptr [SI][LD_BPB][SecPerClust]
mov cx, bx
call proc_mul32
add ax, word ptr [SI][LD_DATAbegin]
adc dx, word ptr [SI][LD_DATAbegin]+2
loc_lcde_load_dir_cluster_1:
mov bx, word ptr [Directory_Buffer]
push es
mov es, bx
xor bx, bx
call proc_disk_read
pop es
jc short loc_lcde_retn
loc_lcde_validate_dirBuff:
mov byte ptr [DirBuff_ValidData], 1
jmp short lcde_check_dir_buffer_cluster_next
LCDE_EntryOffset: dw 0
LCDE_ClusterSN: dw 0
LCDE_Cluster: dd 0
LCDE_ByteOffset: dd 0
proc_locate_current_dir_entry endp
proc_delete_current_directory_entry proc near
; 14/03/2010
; INPUT ->
; ES:DI Directory Entry Address
; AX = Attributes Mask
; OUTPUT ->
; ES:DI Directory Entry Address
; clc -> deleted
; stc -> not deleted
; AL = entry attributes
; AH = entry/filename first char
mov word ptr [DCDE_Attributes], ax
mov ah, byte ptr ES:[DI]
mov al, byte ptr ES:[DI]+0Bh
cmp ah, 0E5h
je short pass_dcde_delete_current_dir_entry
or ah, ah
jz short pass_dcde_delete_current_dir_entry
and byte ptr [DCDE_Attributes], al
cmp al, byte ptr [DCDE_Attributes]
jne short pass_dcde_delete_current_dir_entry
and byte ptr [DCDE_Attributes]+2, ah
jnz short pass_dcde_delete_current_dir_entry
mov word ptr ES:[DI], 0E5h
mov byte ptr [DirBuff_ValidData], 2
retn
pass_dcde_delete_current_dir_entry:
stc
retn
DCDE_Attributes: dw 0
proc_delete_current_directory_entry endp
proc_save_directory_buffer proc near
; 01/08/2011
; 14/08/2010
; Output -> BX = Directory Buffer Segment
; 01/05/2010 FS bugfix
; 18/04/2010
; 06/04/2010 root dir bugfix
; 14/03/2010
; INPUT ->
; none
; OUTPUT ->
; clc -> write OK...
; stc -> error code in AL
; stc & AL= 0Dh => CH/CL= FS/FAT type
; BX = Directory Buffer Segment
; AX, CX, DX will be modified
mov bx, word ptr [Directory_Buffer]
cmp byte ptr [DirBuff_ValidData], 2
je short loc_save_dir_buffer
loc_save_dir_buffer_retn:
xor ax, ax
retn
loc_save_dir_buffer:
push si
mov bh, byte ptr [DirBuff_Drv]
sub bh, 'A'
xor bl, bl
mov si, offset Logical_DosDisks
add si, bx
;18/04/2010
mov cx, word ptr [SI][LD_FATtype]
; ch = FS Type (A1h for FS)
; cl = FAT Type (0 for FS)
;
; 01/08/2011
or cl, cl
jz short loc_save_dir_buff_stc_retn
loc_save_dir_buffer_check_cluster_no:
mov ax, word ptr [DirBuff_Cluster]
mov dx, word ptr [DirBuff_Cluster]+2
; 06/04/2010
mov bx, ax
or bx, dx
jnz short loc_save_sub_dir_buffer
mov ah, byte ptr [DirBuff_FATType]
inc bl
; 01/08/2011
cmp ah, bl
jb short loc_save_dir_buff_inv_data_retn
inc bl
cmp bl, ah
jb short loc_save_dir_buff_inv_data_retn
loc_save_root_dir_buffer:
; 01/08/2011
; 06/04/2010
mov bx, word ptr [SI][LD_BPB][RootDirEnts]
add bx, 15
shr bx, 1
shr bx, 1
shr bx, 1
shr bx, 1
or bx, bx
jz short loc_save_dir_buff_stc_retn
mov cx, bx
mov ax, word ptr [SI][LD_ROOTBegin]
mov dx, word ptr [SI][LD_ROOTBegin]+2
jmp short loc_write_directory_to_disk
loc_save_dir_buff_stc_retn:
stc
loc_save_dir_buff_inv_data_retn:
mov al, 0Dh ; Invalid data !
mov byte ptr [DirBuff_ValidData], 0
loc_save_dir_buff_pop_si_retn:
; 18/04/2010
pop si
loc_save_dir_buff_return:
; 14/08/2010
mov bx, word ptr [Directory_Buffer]
loc_write_directory_to_disk_err:
; 01/08/2011
retn
loc_save_sub_dir_buffer:
sub ax, 2
sbb dx, 0
xor bh, bh
mov bl, byte ptr [SI][LD_BPB][SecPerClust]
mov cx, bx
call proc_mul32
add ax, word ptr [SI][LD_DATAbegin]
adc dx, word ptr [SI][LD_DATAbegin]+2
loc_write_directory_to_disk:
mov bx, word ptr [Directory_Buffer]
push es
mov es, bx
xor bx, bx
call proc_disk_write
mov bx, es ; 14/08/2010
pop es
pop si
jc short loc_write_directory_to_disk_err
loc_save_dir_buff_validate_retn:
mov byte ptr [DirBuff_ValidData], 1
retn
proc_save_directory_buffer endp
proc_convert_current_date_time proc near
; 13/06/2010 retn (bugfix)
; 12/06/2010
; converts date&time to dos dir entry format
; INPUT -> none
; OUTPUT -> DX = Date in dos dir entry format
; AX = Time in dos dir entry format
mov ah, 04h ; Return Current Date
int 1Ah
mov al, ch ; <- century BCD
and al, 0Fh
mov ah, ch
shr ah,1
shr ah,1
shr ah,1
shr ah,1
aad
mov ch, al ; -> century
mov al, cl ; <- year BCD
and al, 0Fh
mov ah, cl
shr ah,1
shr ah,1
shr ah,1
shr ah,1
aad
mov cl, al ; -> year
mov al, ch
mov ah, 100
mul ah
xor ch, ch
add ax, cx
sub ax, 1980 ; ms-dos epoch
mov cx, ax
mov al, dh ; <- month in bcd
and al, 0Fh
mov ah, dh
shr ah,1
shr ah,1
shr ah,1
shr ah,1
aad
mov dh, al ; -> month
mov al, dl ; <- day BCD
and al, 0Fh
mov ah, dl
shr ah,1
shr ah,1
shr ah,1
shr ah,1
aad
mov dl, al ; -> day
mov al, cl ; count of years from 1980
shl ax, 1
shl ax, 1
shl ax, 1
shl ax, 1
or al, dh ; month of year, 1 to 12
shl ax, 1
shl ax, 1
shl ax, 1
shl ax, 1
shl ax, 1
or al, dl ; day of year, 1 to 31
push ax ; push date
mov ah, 02h ; Return Current Time
int 1Ah
mov al, ch ; <- hours BCD
and al, 0Fh
mov ah, ch
shr ah,1
shr ah,1
shr ah,1
shr ah,1
aad
mov ch, al ; -> hours
mov al, cl ; <- minutes BCD
and al, 0Fh
mov ah, cl
shr ah,1
shr ah,1
shr ah,1
shr ah,1
aad
mov cl, al ; -> minutes
mov al, dh ; <- seconds BCD
and al, 0Fh
mov ah, dh
shr ah,1
shr ah,1
shr ah,1
shr ah,1
aad
mov dh, al ; -> seconds
mov al, ch ; hours
shl ax, 1
shl ax, 1
shl ax, 1
shl ax, 1
shl ax, 1
shl ax, 1
or al, cl ; minutes
shl ax, 1
shl ax, 1
shl ax, 1
shl ax, 1
shl ax, 1
shr dh, 1 ; 2 seconds
or al, dl ; seconds
pop dx ; pop date
retn
proc_convert_current_date_time endp
proc_make_directory proc near
; 01/08/2011
; 30/04/2011
; 12/03/2011 Directory attributes input
; 25/12/2010 FS mkdir parent dir ddt bugfix
; 16/10/2010 calculate FAT free space
; infinitive loop bugfix
; 21/08/2010 'calculate free space' modif.
; 14/08/2010 modification
; 09/08/2010 no more files (12h) error return
; 24/07/2010 mkdir_ParentDir_FCluster
; relocated
; 18/07/2010 Current dir level restoration
; 18/07/2010 update_cluster bugfixes
; 17/07/2010
; 10/07/2010
; INPUT ->
; DS:SI = ASCIIZ Directory name (DS = CS)
; CL = Directory Attributes (12/03/2011)
; OUTPUT ->
; DX:AX = New sub dir's first cluster
; DS:SI = Logical Dos Drv Descr. Table Addr.
; stc -> error code in AL
;
; 12/03/2011
; test cl, 10h (directory or volume name)
; jz short loc_make_directory_access_denied
; test cl, 08h
; jnz short loc_make_directory_access_denied
and cl, 07h
mov byte ptr [mkdir_attrib], cl
push si
mov bh, byte ptr [Current_Drv]
xor bl, bl
mov si, offset Logical_DOSDisks
add si, bx
pop bx ; 14/08/2010
; 10/07/2010 -> 1st writable disk check for trdos
; LD_DiskType = 0 for write protection (read only)
cmp byte ptr [SI][LD_DiskType], 1 ; 0 = Invalid
jnb short loc_mkdir_check_file_sytem
mov ax, 13h ; MSDOS err => Disk write-protected
mov dx, 0
; err retn: DX = 0, BX= Dir name offset
; DS:SI -> Dos drive description table address
retn
;loc_make_directory_access_denied:
; 12/03/2011
; mov ax, 05h ; access denied (invalid attributes input)
; stc
; retn
loc_mkdir_check_file_sytem:
cmp byte ptr [SI][LD_FATType], 1
jnb short loc_mkdir_check_free_sectors_hw
loc_make_fs_directory:
; DX:AX -> Parent directory DDT Address
; DS:SI -> Logical DOS Drive DT
; BX -> Directory name offset as ASCIIZ name
; 25/12/2010 BugFix
mov ax, word ptr [Current_Dir_FCluster]
mov dx, word ptr [Current_Dir_FCluster]+2
call proc_make_fs_directory
retn
loc_mkdir_check_free_sectors_hw:
;14/08/2010
cmp word ptr [SI][LD_FreeSectors]+2, 0
jna short loc_mkdir_check_free_sectors_lw
mov cx, 0FFFFh
jmp short loc_make_fat_directory
loc_mkdir_check_free_sectors_lw:
mov cx, word ptr [SI][LD_FreeSectors]
or ch, ch
jnz short loc_make_fat_directory
cmp cl, byte ptr [SI][LD_BPB]+SecPerClust
jb short loc_mkdir_insufficient_disk_space
;
loc_make_fat_directory:
; 14/08/2010
mov word ptr [mkdir_DirName_Offset], bx
mov word ptr [mkdir_FreeSectors], cx
mov al, byte ptr [SI][LD_BPB]+SecPerClust
mov byte ptr [mkdir_SecPerClust], al
loc_mkdir_gffc_1:
call proc_get_first_free_cluster
jc short loc_mkdir_gffc_retn
; 15/08/2010
;or dx, dx
;jz short loc_mkdir_gffc_1_cont
;cmp dx, 0FFFFh
;jne short loc_mkdir_gffc_1_save_fcluster
;stc
;jmp short loc_mkdir_gffc_insufficient_disk_space
;loc_mkdir_gffc_1_cont:
;cmp ax, 2
;jb short loc_mkdir_gffc_insufficient_disk_space
;loc_mkdir_gffc_1_save_fcluster:
; 14/08/2010
mov word ptr [mkdir_FFCluster], ax
mov word ptr [mkdir_FFCluster]+2, dx
loc_mkdir_locate_ffe:
; Current directory fcluster <> Directory buffer cluster
; Current directory will be reloaded by
; proc_locate_current_dir_file procedure
;
; DS:SI = Logical Dos Drv Desc. Table Adress
push si ; 30/04/2011
xor ax, ax
mov cx, ax
dec cx ; FFFFh
; CX = FFFFh -> find first deleted or free entry
; DS:SI would be ASCIZZ filename Address if the call
; would not be for first free or deleted dir entry
call proc_locate_current_dir_file
jnc short loc_mkdir_set_ff_dir_entry_1
pop si ; 30/04/2011
; DS:SI = Logical DOS Drv. Description Table Address
cmp ax, 2
jne short loc_mkdir_stc_return
loc_mkdir_add_new_cluster:
; 14/08/2010
cmp byte ptr [Current_FATType], 2
;cmp byte ptr [SI][LD_FATType], 2
ja short loc_mkdir_add_new_cluster_check_fsc
cmp byte ptr [Current_Dir_Level], 1
;cmp byte ptr [SI][LD_CDirLevel], 1
jnb short loc_mkdir_add_new_cluster_check_fsc
; 09/08/2010
mov al, 12 ; No more files
;
loc_mkdir_gffc_retn:
retn
loc_mkdir_add_new_cluster_check_fsc:
mov cx, word ptr [mkdir_FreeSectors]
; xor ah, ah
mov al, byte ptr [mkdir_SecPerClust]
shl ax, 1 ; AX = 2 * AX
cmp cx, ax
jnb short loc_mkdir_add_new_subdir_cluster
loc_mkdir_insufficient_disk_space:
mov dx, cx
;loc_mkdir_gffc_insufficient_disk_space:
mov ax, 27h ; MSDOS err => insufficient disk space
; err retn: DX = Free sectors, BX= Dir name offset
; DS:SI -> Dos drive description table address
; cx = dx
;
retn
loc_mkdir_stc_return:
stc
retn
loc_mkdir_gffc_2:
; 14/08/2010
call proc_get_first_free_cluster
jc short loc_mkdir_gffc_retn
; 15/08/2010
;or dx, dx
;jz short loc_mkdir_gffc_2_cont
;cmp dx, 0FFFFh
;jne short loc_mkdir_gffc_2_save_fcluster
;stc
;jmp short loc_mkdir_gffc_insufficient_disk_space
;loc_mkdir_gffc_2_cont:
;cmp ax, 2
;jb short loc_mkdir_gffc_insufficient_disk_space
;loc_mkdir_gffc_2_save_fcluster:
; 14/08/2010
mov word ptr [mkdir_FFCluster], ax
mov word ptr [mkdir_FFCluster]+2, dx
mov ax, word ptr [mkdir_LastDirCluster]
mov dx, word ptr [mkdir_LastDirCluster]+2
call proc_load_FAT_sub_directory
jc short loc_mkdir_gffc_retn
mov es, bx
xor di, di
;
loc_mkdir_set_ff_dir_entry_1:
; ES:DI -> Directory entry address
mov si, word ptr [mkdir_DirName_Offset]
mov ax, word ptr [mkdir_FFCluster]
mov dx, word ptr [mkdir_FFCluster]+2
mov cx, 10h ; CL= Directory attribute
; CH = 0 -> File size is 0
; 12/03/2011
or cl, byte ptr [mkdir_attrib] ; S, H, R
call proc_make_directory_entry
pop si ; 30/04/2011
push ds
pop es
; 01/08/2011
mov byte ptr [DirBuff_ValidData], 2
; 14/08/2010
call proc_save_directory_buffer
jnc loc_mkdir_set_ff_dir_entry_2
loc_mkdir_return:
retn
loc_mkdir_add_new_subdir_cluster:
; 14/08/2010 modification
;mov ax, word ptr [DirBuff_Cluster]
;mov dx, word ptr [DirBuff_Cluster]+2
;mov word ptr [mkdir_LastDirCluster], ax
;mov word ptr [mkdir_LastDirCluster]+2, dx
push word ptr [DirBuff_Cluster]
pop word ptr [mkdir_LastDirCluster]
push word ptr [DirBuff_Cluster]+2
pop word ptr [mkdir_LastDirCluster]+2
mov ax, word ptr [mkdir_FFCluster]
mov dx, word ptr [mkdir_FFCluster]+2
call proc_load_FAT_sub_directory
jc short loc_mkdir_return
pass_mkdir_add_new_subdir_cluster:
mov es, bx
xor di, di
mov ax, 256 ; word
mul cx ; cx = directory buffer sector count
mov cx, ax
xor ax, ax ; 0
rep stosw ; AX to ES:DI as CX times (DI= DI+2)
push ds
pop es
; 01/08/2011
mov byte ptr [DirBuff_ValidData], 2
call proc_save_directory_buffer
jc short loc_mkdir_return
loc_mkdir_save_added_cluster:
; 14/08/2010
mov ax, word ptr [mkdir_LastDirCluster]
mov dx, word ptr [mkdir_LastDirCluster]+2
mov cx, word ptr [mkdir_FFCluster]
mov bx, word ptr [mkdir_FFCluster]+2
call proc_update_cluster
; 18/07/2010
jnc short loc_mkdir_save_fat_buffer_0
or ax, ax ;AX = 0 -> cluster value is 0 or eoc
jnz short loc_mkdir_save_fat_buffer_stc_retn
loc_mkdir_save_fat_buffer_0:
;
mov ax, word ptr [mkdir_FFCluster]
mov dx, word ptr [mkdir_FFCluster]+2
; 14/08/2010
mov word ptr [mkdir_LastDirCluster], ax
mov word ptr [mkdir_LastDirCluster]+2, dx
;
xor cx, cx
dec cx
mov bx, cx ; FFFFh
call proc_update_cluster
; 18/07/2010
jnc short loc_mkdir_save_fat_buffer_1
or ax, ax
jz short loc_mkdir_save_fat_buffer_1
loc_mkdir_save_fat_buffer_stc_retn:
stc
loc_mkdir_save_fat_buffer_retn:
retn
loc_mkdir_save_fat_buffer_1:
; Byte ptr [FAT_BUffValidData] = 2
call proc_save_fat_buffer
jc short loc_mkdir_save_fat_buffer_retn
mov byte ptr [mkdir_add_new_cluster], 1
jmp loc_mkdir_upd_parent_dir_lmdt
loc_mkdir_update_sub_dir_cluster:
mov ax, word ptr [mkdir_FFCluster]
mov dx, word ptr [mkdir_FFCluster]+2
xor cx, cx
dec cx ; FFFFh
; 30/01/2011
; DS:SI = Logical DOS drv Desc. Table Address
;mov bh, byte ptr [Current_Drv]
;xor bl, bl
;mov si, offset Logical_DosDisks
;add si, bx
mov bx, cx ; FFFFh
call proc_update_cluster
; 18/07/2010
jnc short loc_mkdir_save_fat_buffer_2
or ax, ax ;AX = 0 -> cluster value is 0 or eoc
jz short loc_mkdir_save_fat_buffer_2
stc
retn
loc_mkdir_set_ff_dir_entry_2:
; 30/04/2011
; DS:SI = Logical DOS Drv Desc. Table Address
; 14/08/2010 modification
;mov si, offset Logical_DosDisks
;mov bh, byte ptr [Current_Drv]
;xor bl, bl
;add si, bx
; 17/07/2010
mov ax, word ptr [mkdir_FFCluster]
mov dx, word ptr [mkdir_FFCluster]+2
; DS:SI = DOS Drive Description Table
; Load disk sectors as a directory cluster
call proc_load_FAT_sub_directory
jc short retn_make_fat_directory
mov es, bx
mov di, 64
mov ax, 256 ; word
mul cx ; cx = directory buffer sector count
sub ax, 32 ; 64 bytes
mov cx, ax
xor ax, ax ; 0
rep stosw ; AX to ES:DI as CX times (DI= DI+2)
xor di, di ; 0
push si ;30/04/2011
mov si, offset mkdir_Name
mov word ptr [SI], 2Eh ; db '.', '0'
mov ax, word ptr [mkdir_FFCluster]
mov dx, word ptr [mkdir_FFCluster]+2
mov cx, 10h ; CL= Directory attribute
; CH = 0 -> File size is 0
call proc_make_directory_entry
mov di, 32
mov ax, word ptr [Current_Dir_FCluster] ; parent dir
mov dx, word ptr [Current_Dir_FCluster]+2 ; parent dir
mov word ptr [SI]+1, 2Eh ; db '.', '0'
;mov cx, 10h
call proc_make_directory_entry
pop si ; 30/04/2011
push ds
pop es
; 01/08/2011
mov byte ptr [DirBuff_ValidData], 2
call proc_save_directory_buffer
; 14/08/2010
jnc short loc_mkdir_update_sub_dir_cluster
retn_make_fat_directory:
retn
loc_mkdir_save_fat_buffer_2:
; Byte ptr [FAT_BuffValidData] = 2
call proc_save_fat_buffer
jc short retn_make_fat_directory
mov byte ptr [mkdir_add_new_cluster], 0
loc_mkdir_upd_parent_dir_lmdt:
; 16/10/2010
call proc_update_parent_dir_lmdt
loc_mkdir_calculate_FAT_freespace:
; 16/10/2010
mov byte ptr [CFS_error], 0
loc_mkdir_calculate_FAT_freespace_next:
; 21/08/2010
xor dx, dx
mov ax, 1 ; Only one Cluster
mov bx, 0FF02h ; BH= FF -> DS:SI -> Dos drv desc. table
; BL= 2 -> subtract (1 cluster)
call proc_calculate_FAT_freespace
and cx, cx ; cx = 0 -> valid free sector count
jz short pass_mkdir_recalculate_FAT_freespace
cmp byte ptr [CFS_error], 0
ja short loc_mkdir_calculate_FAT_freespace_err
loc_mkdir_recalculate_FAT_freespace:
; 16/10/2010
inc byte ptr [CFS_error]
; 21/08/2010
mov bx, 0FF00h
call proc_calculate_FAT_freespace
; 16/10/2010
and cx, cx
jz short loc_mkdir_calculate_FAT_freespace_next
loc_mkdir_calculate_FAT_freespace_err:
; 16/10/2010
pass_mkdir_recalculate_FAT_freespace:
; 21/08/2010
; 14/08/2010
cmp byte ptr [mkdir_add_new_cluster], 0
ja loc_mkdir_gffc_2
loc_mkdir_retn_new_dir_cluster:
mov ax, word ptr [mkdir_FFCluster]
mov dx, word ptr [mkdir_FFCluster]+2
loc_mkdir_retn:
retn
; 12/03/2011
mkdir_attrib: dw 0
; 10/07/2010
mkdir_FFCluster: dd 0
mkdir_DirName_Offset: dw 0
; 17/07/2010
mkdir_add_new_cluster: db 0
mkdir_Name: db 13 dup (0)
; 14/08/2010
mkdir_SecPerClust: db 0
mkdir_FreeSectors: dw 0
mkdir_LastDirCluster: dd 0
proc_make_directory endp
proc_make_directory_entry proc near
; 09/08/2010 File Size in dword ptr DX:[BX]
; 17/07/2010
; INPUT ->
; ES:DI = Directory Entry Address (32 bytes)
; DS:SI = Dot File Name Location
; DX:AX = First Cluster
; File Size = 0 (Must be set later)
; CL= Attributes
; CH = 0 (File size = 0)
; (If CH>0, File size is in
; dword ptr DS:[BX])
; OUTPUT ->
; ES:DI = Directory Entry Address (32 bytes)
; DS:SI = Dot File Name Location (Capitalized)
; If CH input = 0, File Size = 0
; Otherwise file size is as dword ptr DS:[BX]
; DX= Date, AX= Time in DOS Dir Entry format
; BX = same
; CX = same
push cx
mov byte ptr ES:[DI]+11, cl ; Attributes
mov word ptr ES:[DI]+26, ax ; FClusterLw, 26
mov word ptr ES:[DI]+20, dx ; FClusterHw, 20
xor ax, ax
mov word ptr ES:[DI]+12, ax ; NTReserved, 12
; CrtTimeTenth, 13
xor dx, dx
or ch, ch
jz short loc_make_direntry_set_filesize
mov ax, word ptr [BX]
mov dx, word ptr [BX]+2
loc_make_direntry_set_filesize:
mov word ptr ES:[DI]+28, ax ; FileSizeLW, 28
mov word ptr ES:[DI]+30, dx ; FileSizeHW, 30
call proc_convert_file_name
;ES:DI = Dir Entry Format File Name Location
;DS:SI = Dot File Name Location (capitalized)
call proc_convert_current_date_time
; OUTPUT -> DX = Date in dos dir entry format
; AX = Time in dos dir entry format
mov word ptr ES:[DI]+14, ax ; CrtTime, 14
mov word ptr ES:[DI]+16, dx ; CrtDate, 16
mov word ptr ES:[DI]+18, dx ; LastAccDate, 18
mov word ptr ES:[DI]+22, ax ; WrtTime, 14
mov word ptr ES:[DI]+24, dx ; WrtDate, 16
pop cx
retn
proc_make_directory_entry endp
proc_update_parent_dir_lmdt proc near
; 01/08/2011
; 15/05/2011
; 30/04/2011 push si, pop si
; 16/10/2010 moved here from
; proc_delete_file in FILE.ASM
;
; INPUT -> none
; OUTPUT ->
; ES, AX, BX, CX, DX, DI will be changed
; 15/05/2011 FS Check
mov ah, byte ptr [Current_Dir_Level]
mov al, byte ptr [Current_FATType]
cmp al, 1
jb short loc_UPDLMDT_proc_retn
loc_update_parent_dir_lm_date_time:
; 15/05/2011
; 13/06/2010 BugFix
; 12/06/2010
; mov ah, byte ptr [Current_Dir_Level]
or ah, ah
jz short loc_UPDLMDT_proc_retn
push si ; 30/04/2011
; 18/07/2010
mov byte ptr [UPDLMDT_CDirLevel], ah
push word ptr [Current_Dir_FCluster]
pop word ptr [UPDLMDT_CDirFCluster]
push word ptr [Current_Dir_FCluster]+2
pop word ptr [UPDLMDT_CDirFCluster]+2
; 12/06/2010
dec ah ; 15/05/2011 al -> ah
push ds
pop es
mov cx, 12
mov si, offset Path_Array
; 13/06/2010
mov byte ptr [Current_Dir_Level], ah
or ah, ah
jnz short loc_update_parent_dir_lmdt_load_sub_dir_1
cmp byte ptr [Current_FATType], 2
ja short loc_update_parent_dir_lmdt_load_sub_dir_2
xor al, al
xor dx, dx
jmp short loc_update_parent_dir_lmdt_load_sub_dir_3
loc_UPDLMDT_proc_retn:
; 16/10/2010
retn
loc_update_parent_dir_lmdt_load_sub_dir_1:
; 15/05/2011
; 13/06/2010
mov al, 16
mul ah
add si, ax
loc_update_parent_dir_lmdt_load_sub_dir_2:
mov ax, word ptr [SI]+12 ; Parent Dir First cluster LW
mov dx, word ptr [SI]+14 ; Parent Dir First cluster HW
loc_update_parent_dir_lmdt_load_sub_dir_3:
; 13/06/2010
mov word ptr [Current_Dir_FCluster], ax
mov word ptr [Current_Dir_FCluster]+2, dx
add si, 16
mov di, offset Dir_File_Name
rep movsb
mov si, offset Logical_DosDisks
mov bh, byte ptr [Current_Drv]
xor bl, bl
add si, bx
call proc_reload_current_directory
jc short loc_update_parent_dir_lmdt_restore_cdirlevel
loc_update_parent_dir_lmdt_locate_dir:
mov si, offset Dir_File_Name
xor cx, cx
mov ax, 0810h ; Only directories
call proc_locate_current_dir_file
; ES:DI = DirBuff Directory Entry Address
jc short loc_update_parent_dir_lmdt_restore_cdirlevel
call proc_convert_current_date_time
mov word ptr ES:[DI]+18, dx ; Last Access Date
mov word ptr ES:[DI]+24, dx ; Last Write Date
mov word ptr ES:[DI]+22, ax ; Last Write Time
; 01/08/2011
mov byte ptr [DirBuff_ValidData], 2
call proc_save_directory_buffer
jc short loc_update_parent_dir_lmdt_restore_cdirlevel
xor al, al
loc_update_parent_dir_lmdt_restore_cdirlevel:
; 18/07/2010 current directory level restoration
mov ah, byte ptr [UPDLMDT_CDirLevel]
mov byte ptr [Current_Dir_Level], ah
push word ptr [UPDLMDT_CDirFCluster]
pop word ptr [Current_Dir_FCluster]
push word ptr [UPDLMDT_CDirFCluster]+2
pop word ptr [Current_Dir_FCluster]+2
; 16/10/2010
; push ds
; pop es
pop si ; 30/04/2011
retn
; 16/10/2010 (delfile-> UPDLMDT)
; 18/07/2010
UPDLMDT_CDirLevel: db 0
UPDLMDT_CDirFCluster: dd 0
proc_update_parent_dir_lmdt endp
proc_rename_directory_entry proc near
; 01/08/2011
; 20/11/2010
; 19/11/2010
; INPUT -> (Current Directory)
; CX = Directory Entry Number
; DX:AX = First Cluster number of file or directory
; BL = Longname Length (dir entry count)
; BH = 0
; DS:SI = New file (or directory) name (no path).
; (ASCIZZ string)
; OUTPUT ->
; clc (cf=0) -> successfull
; stc (cf=1) -> error code in AX
; ES, AX, BX, CX, DX, SI, DI will be changed
cmp byte ptr CS:[Current_FATType], 0
ja short loc_rename_directory_entry
call proc_rename_fs_file_or_directory
retn
loc_rename_directory_entry:
push ds
pop es
push cs
pop ds
mov byte ptr [DelFile_LNEL], bl
mov word ptr [DelFile_EntryCounter], cx
mov word ptr [DelFile_FCluster], ax
mov word ptr [DelFile_FCluster]+2, dx
mov ax, cx
push si
push es
call proc_locate_current_dir_entry
jnc short loc_rename_direntry_check_fcluster
loc_rename_direntry_pop_retn:
pop dx
pop dx
retn
loc_rename_direntry_pop_invd_retn:
mov dx, ax
pop ax
pop ax
stc
loc_rename_direntry_invd_retn:
mov ax, 0Dh
loc_rename_retn:
retn
loc_rename_direntry_check_fcluster:
mov ax, word ptr ES:[DI]+26
mov dx, word ptr ES:[DI]+20
cmp ax, word ptr [DelFile_FCluster]
jne short loc_rename_direntry_pop_invd_retn
cmp dx, word ptr [DelFile_FCluster]+2
jne short loc_rename_direntry_pop_invd_retn
;mov bx, es
;mov dx, di
;push cs
;pop es
;mov di, offset Dir_File_name
pop ds
pop si
; NOTE: If file/dir name is more than 11 bytes
; without a dot, attributes (DI+11) byte will be overwritten !
; (Dot file name input must be proper
; for 11 byte dir entry type file name output)
call proc_convert_file_name
push cs
pop ds
;mov di, dx
;mov es, bx
;mov si, offset Dir_File_name
;mov cx, 11
;rep movsb
mov byte ptr [DirBuff_ValidData], 2
call proc_save_directory_buffer
jc short loc_rename_retn
loc_rename_direntry_del_ln:
xor dh, dh
mov dl, byte ptr [DelFile_LNEL]
or dl, dl
jz short loc_rename_direntry_update_parent_dir_lm_date
mov ax, word ptr [DelFile_EntryCounter]
sub ax, dx
jc short loc_rename_direntry_invd_retn
loc_rename_direntry_del_ln_continue:
; AX = Directory Entry Number of the long name last entry
call proc_delete_longname
loc_rename_direntry_update_parent_dir_lm_date:
call proc_update_parent_dir_lmdt
xor ax, ax
retn
proc_rename_directory_entry endp
proc_set_working_path proc near
; 08/02/2011
; 05/02/2011
; 27/01/2011
; Set/Changes current drive, directory and file
; depending on command tail
; (procedure is derivated from CMD_INTR.ASM
; file or dir locating code of internal commands)
; (This procedure is prepared for INT 21H file/dir
; functions and also to get compact code for
; internal mainprog -command interpreter- commands)
;
; INPUT: DS:SI -> Command tail (ASCIIZ string)
; AL= 0 -> any, AL > 0 -> file name is forced
; AH= CD -> Change directory permanently
; AH <> CD -> Change directory as temporary
;
; OUTPUT: ES=DS, FindFile structure has been set
; RUN_CDRV points previous current drive
; DS:SI = FindFile structure address
; (DS=CS)
; AX, BX, CX, DX, DI will be changed
; cf = 1 -> Error code in AX (AL)
; stc & AX = 0 -> Bad command or path name
;
push cs
pop es
mov word ptr CS:[SWP_Mode], ax
mov al, byte ptr CS:[Current_Drv] ; 05/02/2011
xor ah, ah
mov word ptr CS:[SWP_DRV], ax ; 05/02/2011
loc_swp_fchar:
mov al, byte ptr [SI]
cmp al, 20h
ja short loc_swp_parse_path_name
je short loc_swp_fchar_next
loc_swp_xor_retn:
xor ax, ax
stc
loc_swp_push_pop_retn:
push cs
pop ds
loc_swp_retn:
mov si, offset FindFile_Drv
retn
loc_swp_fchar_next:
inc si
jmp short loc_swp_fchar
loc_swp_parse_path_name:
mov di, offset FindFile_Drv
call proc_parse_pathname
jc short loc_swp_push_pop_retn
loc_swp_checkfile_name:
push cs
pop ds
cmp byte ptr [SWP_Mode], 0
jna short loc_swp_drv
cmp byte ptr [FindFile_Name], 20h
jna short loc_swp_xor_retn
loc_swp_drv:
mov dh, byte ptr [Current_Drv]
; 05/02/2011
;mov byte ptr [RUN_CDRV], dh
mov dl, byte ptr [FindFile_Drv]
;cmp dl, dh
cmp dl, byte ptr [Current_Drv]
je short loc_swp_change_directory
inc byte ptr [SWP_DRV_chg]
call proc_change_current_drive
jc short loc_swp_retn
loc_swp_change_directory:
cmp byte ptr [FindFile_Directory], 21h
cmc
jnc short loc_swp_retn
inc byte ptr [SWP_DRV_chg]
inc byte ptr [Restore_CDIR]
mov si, offset FindFile_Directory
mov ah, byte ptr [SWP_Mode]+1
call proc_change_current_directory
jc short loc_swp_retn
loc_swp_change_prompt_dir_string:
call proc_change_prompt_dir_string
mov ax, 0
jmp short loc_swp_retn
SWP_Mode: dw 0
;05/02/2011
SWP_DRV: db 0
;08/02/2011
SWP_DRV_chg: db 0
proc_set_working_path endp
proc_reset_working_path proc near
; 08/02/2011
; 06/02/2011
; 05/02/2011
; Restores current drive and directory
;
; INPUT: none
; OUTPUT: DL = SWP_DRV, AX = 0 -> OK
; DS= CS = ES
; BX, CX, DX, SI, DI will be changed
; AX = 0 -> DS:SI = Logical Dos Drv Desc. Table
mov dx, cs
mov ds, dx
mov es, dx
xor ax, ax
dec ax
mov dx, word ptr [SWP_DRV]
or dh, dh
jz short loc_rwp_return
cmp dl, byte ptr [Current_Drv]
je short loc_rwp_restore_cdir
loc_rwp_restore_cdrv:
call proc_change_current_drive
jmp short loc_rwp_restore_ok
loc_rwp_restore_cdir:
mov bh, dl
xor bl, bl
mov si, offset Logical_DOSDisks
add si, bx
call proc_restore_current_directory
loc_rwp_restore_ok:
mov dx, word ptr [SWP_DRV]
xor ax, ax
mov word ptr [SWP_DRV_chg], ax
loc_rwp_return:
retn
proc_reset_working_path endp
proc_return_current_directory_string proc near
; 27/03/2011
; INPUT:
; DS:SI = Path Array Address
; ES:DI = Current Directory String Buffer
; AH = Current Directory Level
;
; 09/10/2009 (proc_change_prompt_dir_string)
; OUTPUT => AX, BX, SI will be changed
; DI will be same with input
; CX = Current Directory String Length
;
push di
cmp ah,0
jna short pass_write_path
;mov byte ptr [DirLevel_Count], ah
add si, 16
mov bx, si
loc_write_path:
mov cx, 8
path_write_dirname1:
lodsb
cmp al, 20h
jna short pass_write_dirname1
mov byte ptr ES:[DI], al
inc di
cmp di, offset End_Of_Current_Dir_Str
jnb short pass_write_path
loop path_write_dirname1
cmp byte ptr [SI], 20h
jna short pass_write_dirname2
jmp short loc_put_dot_cont_ext
pass_write_dirname1:
mov si, bx
add si, 8
cmp byte ptr [SI], 20h
jna short pass_write_dirname2
loc_put_dot_cont_ext:
mov byte ptr ES:[DI],"."
mov cx, 3
loc_check_dir_name_ext:
lodsb
inc di
cmp al, 20h
jna short pass_write_dirname2
mov byte ptr ES:[DI], al
cmp di, offset End_Of_Current_Dir_Str
jnb short pass_write_path
loop loc_check_dir_name_ext
inc di
pass_write_dirname2:
; dec byte ptr [DirLevel_Count]
dec ah
jz short pass_write_path
add bx, 16
mov si, bx
mov byte ptr ES:[DI],"/"
inc di
jmp short loc_write_path
pass_write_path:
mov byte ptr ES:[DI],0
inc di
mov cx, di
pop di
sub cx, di
; CX = Current Directory String Length
retn
;DirLevel_Count: db 0
proc_return_current_directory_string endp
proc_get_current_directory proc near
; 27/03/2011
;
; INPUT-> DS:SI = Current Directory Buffer
; DL = TRDOS Logical Dos Drive Number + 1
; (0= Default/Current Drive)
;
; Note: Required dir buffer length may be <= 92 bytes
; for TRDOS (7*12 name chars + 7 slash + 0)
; OUTPUT -> DS:SI = Current Directory Buffer
; ES is same with input
; AX, BX, CX, DX, DI will be changed
; CX/CL = Current Directory String Length
; DL = Drive Number (1 based)
; (If input is 0, output is current drv number)
; DH= same with input
; clc (cf=0) -> AL = 0
; stc (cf=1) -> error code in AL
loc_get_current_drive_0:
cmp dl, 0
ja short loc_get_current_drive_1
mov dl, byte ptr CS:[Current_Drv]
jmp short loc_get_current_drive_3
loc_get_current_drive_1:
cmp dl, 13
jna short loc_get_current_drive_2
mov ax, 0Fh ; Invalid drive
cmc ; stc
retn
loc_get_current_drive_not_ready_retn:
pop si
mov ax, 15h ; Drive not ready
retn
loc_get_current_drive_2:
dec dl ; Zero based (TRDOS Logical Dos Drive Number)
loc_get_current_drive_3:
mov ah, dl
xor al, al
push si
mov si, offset Logical_DosDisks
add si, ax
mov al, byte ptr CS:[SI]+LD_Name
cmp al, 'A'
jb short loc_get_current_drive_not_ready_retn
loc_get_current_drive_4:
push ds ; Current dir buffer segment
push es
push cs
pop ds
mov ah, byte ptr [SI][LD_CDirLevel]
or ah, ah
jnz short loc_get_current_drive_6
loc_get_current_drive_5:
pop es
pop ds
pop si
;xor ah, ah ; mov ah, 0
mov byte ptr [SI], ah
xor cx, cx
jmp short loc_get_current_drive_9
loc_get_current_drive_6:
push cs
pop es
mov di, offset PATH_Array
push di
add si, LD_CurrentDirectory
mov cx, 64
rep movsw
pop si ; Path Array Address
pop bx ; pushed es
pop es ; pushed ds (current dir buffer segment)
pop di ; pushed si (current dir buffer offset)
push bx
loc_get_current_drive_7:
push di
call proc_return_current_directory_string
;cmp dl, byte ptr [Current_Drv]
;je short loc_get_current_drive_8
;mov bh, byte ptr [Current_Drv]
;xor bl, bl
;mov si, offset Logical_DOSDisks
;add si, bx
;push es
;push cs
;pop es
;mov di, offset PATH_Array
;push di
;add si, LD_CurrentDirectory
;mov cx, 64
;rep movsw
;pop es
loc_get_current_drive_8:
pop si
push es
pop ds
pop es
loc_get_current_drive_9:
xor al, al
inc dl ; 1 based drive number
retn
proc_get_current_directory endp
proc_delete_directory_entry proc near
; 01/08/2011
; 11/04/2011
; 10/04/2011
; this procedure is separated and moved here from
; proc_delete_file procedure (16/10/2010) in FILE.ASM
; for 'rename' compatibility
;
; INPUT ->
; DS:SI = Logical dos drv desc. table address
; ES:DI = Directory Buffer Entry Offset
; CX = Dir Buff Entry Counter
; BL = Longname Entry Length
; BH = Logical DOS Drv Number
; OUTPUT ->
; DS:SI = Logical dos drv desc. table address
; DX:AX = First cluster to be truncated/unlinked
; stc -> Error code in AL
; (ES), DI, BX, CX will be changed
; clc & BH <> 0 -> LMDT write error (BH = 1)
; clc & BL <> 0 -> Long name delete error (BL = FFh)
mov byte ptr [DelFile_LNEL], bl
mov word ptr [DelFile_EntryCounter], cx
; 03/04/2010
; ES:DI -> Directory buffer entry offset/address
mov ax, word ptr ES:[DI]+26 ; First Cluster Low Word
mov dx, word ptr ES:[DI]+20 ; First Cluster High Word
mov word ptr [DelFile_FCluster], ax
mov word ptr [DelFile_FCluster]+2, dx
loc_del_short_name:
; 28/03/2010
mov byte ptr ES:[DI], 0E5h ; Deleted sign
; 01/08/2011
mov byte ptr [DirBuff_ValidData], 2
; 10/04/2011
; 18/04/2010
call proc_save_directory_buffer
jc short loc_delete_direntry_err_return
loc_del_long_name:
; 03/04/2010
xor dh, dh
mov dl, byte ptr [DelFile_LNEL]
or dl, dl
; 16/10/2010
; 12/06/2010
jz short loc_del_dir_entry_update_parent_dir_lm_date
; 11/04/2011
mov byte ptr [DelFile_LNEL], dh ; 0
;
mov ax, word ptr [DelFile_EntryCounter]
sub ax, dx
;jnc short loc_del_long_name_continue
jc short loc_del_dir_entry_update_parent_dir_lm_date
;loc_del_direntry_inv_data_return:
; mov ax, 0Dh ; Invalid data
; retn
loc_del_long_name_continue:
; AX = Directory Entry Number of the long name last entry
call proc_delete_longname
;jc short loc_delete_direntry_err_return
loc_del_dir_entry_update_parent_dir_lm_date:
; 11/04/2011
sbb byte ptr [DelFile_LNEL], 0
; 16/10/2010
call proc_update_parent_dir_lmdt
; 11/04/2011
mov bh, 0
adc bh, 0
mov bl, byte ptr [DelFile_LNEL]
loc_delete_direntry_return:
mov ax, word ptr [DelFile_FCluster]
mov dx, word ptr [DelFile_FCluster]+2
loc_delete_direntry_err_return:
retn
;28/03/2010
;DelFile_DirEntryAddr: dw 0
DelFile_FCluster: dd 0
; 28/02/2010
DelFile_EntryCounter: dw 0
DelFile_LNEL: db 0
proc_delete_directory_entry endp
Dir_File_Name: db 13 dup(0)
File_Name:
db 12 dup(20h)
db 20h
Dir_Or_FileSize:
db 10 dup(20h)
db 20h
File_Attribute:
db 4 dup(20h)
db 20h
File_Day:
db 2 dup('0')
db '/'
File_Month:
db 2 dup('0')
db '/'
File_Year:
db 4 dup('0')
db 20h
File_Hour:
db 2 dup('0')
db ':'
File_Minute:
db 2 dup('0')
db 0
Type_Dir: db ' '
Dir_Drive_Str:
db "TR-DOS Drive "
Dir_Drive_Name:
db "0:"
db 0Dh, 0Ah
Vol_Str_Header:
db "Volume Name: "
Vol_Name: db 64 dup(0)
db 0
Vol_Serial_Header:
db 0Dh, 0Ah
db "Volume Serial No: "
Vol_Serial2: db "0000"
db "-"
Vol_Serial1: db "0000"
db 0Dh, 0Ah
Dir_Str_Header:
db "Directory: "
Dir_Str_Root: db "/"
Dir_Str: db 64 dup (0)
dd 0
db 0
PATH_Array: db 128 dup(0)
LFN_Checksum: db 0
LongFileName: db 132 dup(0)
LongNameFound: db 0
; 28/02/2010
LongName_EntryLength: db 0