%TITLE "Determine Current Directories - CHiPS bv 1997" ;********************************************************************** ;** ** ;** Program : DC_DIRS ** ;** Purpose : Determine Current Directories ** ;** Program assumes that Dir_Map table is initialized ** ;** ** ;** Author : B.F. Schreurs ** ;** Computer High Performance Software (CHiPS) bv ** ;** Date : September 4th, 1997 ** ;** ** ;** Calls : MEMSORT - Sort A (Memory) File ** ;** ** ;** Parameter : 1. Pass the address of the requested format. ** ;** The format specified how the data of the ** ;** available directories will be passed back. ** ;** Requested format size is 1 byte and may contain: ** ;** "1" = Return data in format as specified in ** ;** DIRENTRY.STR with size DIR_ENTRY_LENGTH. ** ;** "2" = Return data in format ** ;** ".. " ** ;** "ATARI " ** ;** "MYDIR " ** ;** "YOURDIR " ** ;** " " ** ;** " " ** ;** " " ** ;** etc. with size DIR_ENTRY_LENGTH ** ;** Parameter : 2. Pass the address of the data which contains the ** ;** path to be searched for the directories to be ** ;** retrieved. Path size is PATH_LENGTH. ** ;** Parameter : 3. Pass the address of the table where the data ** ;** containing the directory info will be stored. ** ;** Format "1": Table size: DIR_ENTRY_LENGTH * ** ;** number of expected libraries. ** ;** Format "2": Table size: DIR_ENTRY_LENGTH * ** ;** number of expected libraries. ** ;** ** ;** Language : Turbo Assembler ** ;** ** ;** Returncode: 0 - No error encountered ** ;** 1 - Drive was not ready ** ;** ** ;********************************************************************** IDEAL JUMPS ;---------------------------------------------------------------------- ;-- Functions which can be called -- ;---------------------------------------------------------------------- PUBLIC DC_DIRS ;---------------------------------------------------------------------- ;-- Equates -- ;---------------------------------------------------------------------- include ".\equ\attrib.equ" include ".\equ\dos.equ" include ".\equ\equipmnt.equ" include ".\equ\sysdep.equ" DIRECTORY_TEXT_LENGTH EQU 12 ;********************************************************************** SEGMENT SSeg Para Stack 'STACK' ;********************************************************************** db 64 dup (0) ; Stack ENDS SSeg ;********************************************************************** SEGMENT DSeg Word Public 'DATA' ;********************************************************************** ;---------------------------------------------------------------------- ;-- Structures -- ;---------------------------------------------------------------------- include ".\str\direntry.str" include ".\str\dta.str" include ".\str\sortkeys.str" ;---------------------------------------------------------------------- ;-- Working Storage -- ;---------------------------------------------------------------------- GLOBAL Return_Code:Byte:1 Parm_Format_ptr_es DW 1 dup (NULL) ; 1 = "DIRENTRY format .. " ; "DIRENTRY format ATARI " Parm_Format_ptr_di DW 1 dup (NULL) ; 2 = ".. " ; "ATARI " Parm_Path_Spec_ptr_es DW 1 dup (NULL) Parm_Path_Spec_ptr_di DW 1 dup (NULL) Parm_Dir_Map_ptr_es DW 1 dup (NULL) Parm_Dir_Map_ptr_di DW 1 dup (NULL) Parm_SortKeys SortKeys<> DOS_Find_Files_Or_Dirs DW 1 dup (DOS_FIND_DIRECTORIES) Requested_Format DB 1 dup (?) Directory_Above_Text DB ".. " Directory_Text DB " " Dir_Map_Entry Dir_Entry <> Dirs_In_Dir_Table DW 0 Old_Dta_Seg DW ? ; Old Dta Segment Address Old_Dta_Ofs DW ? ; Old Dta Segment Offset Own_Dta Dta <> ENDS DSeg ;********************************************************************** SEGMENT CSeg Word Public 'CODE' ;********************************************************************** ;---------------------------------------------------------------------- ;-- External Variables -- ;---------------------------------------------------------------------- EXTRN MEMSORT:proc ; Sort A (Memory) File ;********************************************************************** PROC DC_DIRS ;********************************************************************** ASSUME cs:CSeg ASSUME ds:DSeg mov ax, DSeg ; Initialize DS to address mov ds, ax ; of data segment mov bx, sp ; ; Parameter Directories ; mov di, [ss:bx+2] mov es, [ss:bx+4] mov [Parm_Dir_Map_ptr_es], es mov [Parm_Dir_Map_ptr_di], di ; ; Parameter Path ; mov di, [ss:bx+6] mov es, [ss:bx+8] mov [Parm_Path_Spec_ptr_es], es mov [Parm_Path_Spec_ptr_di], di ; ; Parameter Requested Format ; mov di, [ss:bx+10] mov es, [ss:bx+12] mov [Parm_Format_ptr_es], es mov [Parm_Format_ptr_di], di mov al, [byte es:di] mov [Requested_Format], al ; Init return code mov al, NULL mov [Return_Code], al ; Save Current Dta mov ah, DOS_GET_DTA ; Get Disk Transfer Area address int DOS_SERVICE mov [Old_Dta_Seg], es ; Save old Dta Segment Address mov [Old_Dta_Ofs], bx ; Save old Dta Segment Offset ; Specify Own Dta mov dx, offset Own_Dta ; Address of Own Dta mov ah, DOS_SET_DTA int DOS_SERVICE ; ; First entry in our map is always a pointer back to root = .. ; mov es, [Parm_Dir_Map_ptr_es] mov di, [Parm_Dir_Map_ptr_di] mov si, offset Directory_Above_Text mov cx, DIR_ENTRY_LENGTH rep movsb ; ; The directory search is split up in 2 parts ; Skip the Files, ; Retrieve ALL Directories ; mov [Dirs_In_Dir_Table], 1 ; First entry is .. mov ds, [Parm_Path_Spec_ptr_es] ; Use specified search path mov dx, [Parm_Path_Spec_ptr_di] mov cx, [DOS_Find_Files_Or_Dirs] ; Is one or the other xor ax, ax ; Reset ax mov ah, DOS_FIND_FIRST_FILE ; Find First File jmp @@20 ; Retrieve dir entries @@10: mov cx, [DOS_Find_Files_Or_Dirs] ; Is one or the other xor ax, ax ; Reset ax mov ah, DOS_FIND_NEXT_FILE ; Find Next File ; Read VTOC @@20: int DOS_SERVICE ; Find First/Next Entry jc @@50 ; No more Entries? ; Check for "." or ".." entry mov si, offset Own_Dta.File_Name ; Load address of filename cmp [byte ds:si], DOT ; Is this a ". " Entry? je @@10 ; Retrieve next Entry ; Check Entry for being a directory entry mov si, offset Own_Dta.File_Attribute ; Load address of attribute xor ax, ax ; Reset ax mov al, [byte ds:si] ; Load attribute and al, ATTRIB_FILE_DIRECTORY cmp al, ATTRIB_FILE_DIRECTORY ; Entry is a directory? jne @@10 ; No ; Yes, so ; ; Move entry to our dir entry ; ; Init dir entry first mov si, offset Dir_Map_Entry push ds si pop di es mov cx, DIR_ENTRY_LENGTH xor ax, ax rep stosb ; Search the null terminator mov si, offset Own_Dta.File_Name push ds si pop di es mov cx, DIR_NAME_LENGTH ; Search length inc cx xor ax, ax ; Search for null character repne scasb ; Search uses es:di mov bx, cx ; File_Name mov si, offset Dir_Map_Entry.File_Name push ds si pop di es mov si, offset Own_Dta.File_Name mov cx, DIR_NAME_LENGTH sub cx, bx rep movsb cmp [Requested_Format], "1" ; DIRENTRY format? je @@30 ; Yes ; No, so ; ; Replace remaining nulls from VTOC read by spaces ; mov cx, bx mov al, SPACE rep stosb ; ; ; Format is ".. " ; "ATARI " ; etc. ; mov si, offset Directory_Text mov cx, DIRECTORY_TEXT_LENGTH rep movsb jmp @@40 @@30: ; File_Size mov si, offset Dir_Map_Entry.File_Size push ds si pop di es mov si, offset Own_Dta.File_Size mov cx, 4 rep movsb ; File_Date mov si, offset Dir_Map_Entry.File_Date push ds si pop di es mov si, offset Own_Dta.File_Date mov cx, 2 rep movsb ; File_Time mov si, offset Dir_Map_Entry.File_Time push ds si pop di es mov si, offset Own_Dta.File_Time mov cx, 2 rep movsb ; File_Attribute mov al, offset Own_Dta.File_Attribute mov [offset Dir_Map_Entry.File_Attribute], al @@40: ; Calculate location where to store the entry mov ax, DIR_ENTRY_LENGTH xor bx, bx mov cx, [Dirs_In_Dir_Table] xor dx, dx mul cx ; Store Entry mov cx, ax mov es, [Parm_Dir_Map_ptr_es] mov di, [Parm_Dir_Map_ptr_di] add di, cx mov si, offset Dir_Map_Entry mov cx, DIR_ENTRY_LENGTH rep movsb ; Increase Entry count inc [Dirs_In_Dir_Table] cmp [Dirs_In_Dir_Table], MAX_DIRS ; Max nr of Entries reached? jne @@10 ; No ; Yes, so @@50: mov es, [Old_Dta_Seg] ; Restore old Dta Address mov dx, [Old_Dta_Ofs] mov ah, DOS_SET_DTA int DOS_SERVICE cmp [Dirs_In_Dir_Table], 0 ; Files found? je @@90 ; No ; Yes, so cmp [Dirs_In_Dir_Table], 1 ; Do we need to sort? je @@99 ; No ; Yes, so ; ; Set up sort keys ; mov si, offset Parm_SortKeys push ds si pop di es mov ax, [Parm_Dir_Map_ptr_es] mov bx, [Parm_Dir_Map_ptr_di] mov [(SortKeys ptr di).Memory_Address_Hi], ax mov [(SortKeys ptr di).Memory_Address_Lo], bx mov ax, [Dirs_In_Dir_Table] mov [(SortKeys ptr di).Record_Count], ax mov [(SortKeys ptr di).Record_Size], DIR_ENTRY_LENGTH mov [(SortKeys ptr di).Key_Count], 1 mov [(SortKeys ptr di).Key_1_Position], 1 mov [(SortKeys ptr di).Key_1_Size], DIR_NAME_LENGTH mov [(SortKeys ptr di).Key_1_A_D], SORT_ASCENDING ; ; Bubble Sort Directories in alphabetic order ; push es di call MEMSORT pop bx bx @@90: mov al, 1 mov [Return_Code], al @@99: ret ENDP DC_DIRS ENDS CSeg ; End of Code segment END ; End of Program