%TITLE "Atari 8bit Directory Lister with path - CHiPS bv 1997" ;********************************************************************** ;** ** ;** Program : XdirList ** ;** Purpose : Atari 8bit Directory Lister with path ** ;** ** ;** Author : B.F. Schreurs ** ;** Computer High Performance Software (CHiPS) bv ** ;** Date : October 29th, 1997 ** ;** ** ;** Calls : DC_DIRS - Determine Current Directories ** ;** DC_FILES - Determine Current Files ** ;** TO_UPPER - Convert string to UpperCase ** ;** ** ;** Language : Turbo Assembler ** ;** ** ;********************************************************************** IDEAL JUMPS ;---------------------------------------------------------------------- ;-- Equates -- ;---------------------------------------------------------------------- include ".\equ\at_drive.equ" include ".\equ\dos.equ" include ".\equ\sysdep.equ" EIGHTBIT_FILE_NAME_LENGTH EQU 11 ;********************************************************************** SEGMENT SSeg Para Stack 'STACK' ;********************************************************************** db 128 dup (0) ; Stack ENDS SSeg ;********************************************************************** SEGMENT DSeg Word Public 'DATA' ;********************************************************************** ;---------------------------------------------------------------------- ;-- Structures -- ;---------------------------------------------------------------------- include ".\str\direntry.str" include ".\str\psp.str" Struc Loc_Entry ; Output record Layout File_Name DB 12 dup (SPACE) Filler_1 DB 1 dup (SPACE) File_Size DB 4 dup (SPACE) Filler_2 DB 1 dup (SPACE) File_Lck DB 3 dup (SPACE) Filler_3 DB 1 dup (SPACE) File_Ext DB 3 dup (SPACE) Filler_4 DB 1 dup (SPACE) File_Del DB 3 dup (SPACE) Filler_5 DB 1 dup (SPACE) File_Path DB PATH_LENGTH dup (SPACE) ends ; Locator_Entry ;---------------------------------------------------------------------- ;-- Working Storage -- ;---------------------------------------------------------------------- Dir_Map_Length = ( MAX_DIRS * DIR_ENTRY_LENGTH ) File_Map_Length = ( MAX_FILES * FILE_ENTRY_LENGTH ) Work_Dir_Map_Length = ( MAX_DIRS * PATH_LENGTH) Locator_Entry_Length = ( 30 + PATH_LENGTH ) GLOBAL Dir_Map:Byte:Dir_Map_Length GLOBAL File_Map:Byte:File_Map_Length GLOBAL Path_Spec:Byte:PATH_LENGTH GLOBAL Return_Code:Byte:1 Work_Dir_Map DB Work_Dir_Map_Length dup (SPACE) Path_Spec DB PATH_LENGTH dup (SPACE) Input_Spec DB PATH_LENGTH dup (SPACE) Return_Code DB 0 Locator_File_Opened DB 1 dup (FALSE) Locator_File_Spec DB "C:\LOCATOR.TXT" DB 1 dup (0) File_Map_Entry Dir_Entry <> Locator_Entry Loc_Entry <> Search_Spec DB PATH_LENGTH dup (NULL) DB 1 dup (0) File_Mask DB "*.* " Dir_Mask DB "*.* " Dirs_To_Process DB 0 Input_File DW 0 Output_File DW 0 Disk_I_O_Buffer DB DISK_BLOCK_SIZE dup (NULL) ATR_Header_Single DB 96h,02h,80h,16h,80h,00h,00h,00h ATR_Header_Medium DB 96h,02h,80h,20h,80h,00h,00h,00h ATR_Header_Enhanced DB 96h,02h,00h,23h,80h,00h,00h,00h ATR_Header_Double DB 96h,02h,00h,2Dh,80h,00h,00h,00h Output_Header_1 DB "Atari File Size Lck Ext Del Pc Path" Output_Space DB Locator_Entry_Length dup (SPACE) Output_Header_2 DB "------------ ---- --- --- --- -------" Output_Underline DB Locator_Entry_Length dup (UNDERLINE) Output_Yes DB "Yes" Output_No DB "No " Output_File_Size DB " " Output_Return_Linefeed DB CR, LF Msg_Listing DB CR, LF, "XDIRLIST version 01.00.00 by B.F. Schreurs, CHiPS bv, November 1997" DB CR, LF, "Atari 8 bit ATR/XFD Image Directory Lister." DB CR, LF DB CR, LF DB CR, LF, "Directory Listing now in progress..." DB NULL Msg_Processing DB CR, LF, "Processing " DB NULL Msg_Listing_Completed DB CR, LF DB CR, LF DB CR, LF, "Directory Listing completed." DB NULL Msg_Look DB CR, LF, "Look at the C:\LOCATOR.TXT file to view the results." DB NULL Msg_No_Look DB CR, LF, "No Atari 8 bit Disk Image found!" DB NULL Msg_Thank_You DB CR, LF, "Thank you for using XDIRLIST!" DB CR, LF, NULL ENDS DSeg ;********************************************************************** SEGMENT CSeg Word Public 'CODE' ;********************************************************************** ;---------------------------------------------------------------------- ;-- External Variables -- ;---------------------------------------------------------------------- EXTRN DC_DIRS:proc EXTRN DC_FILES:proc EXTRN TO_UPPER:proc ;********************************************************************** Main: ;********************************************************************** ASSUME cs:CSeg ASSUME ds:DSeg mov ax, DSeg ; Initialize DS to address mov ds, ax ; of data segment call Check_Command_Line_Syntax call Show_Msg_Listing call Init_Program call Process_Dirs_Files call Show_Msg_Thank_You call Exit_Program ;********************************************************************** PROC Check_Command_Line_Syntax ;********************************************************************** ; Check Command Line xor cx, cx ; Clear cx mov cl, [es:Psp.LengthByte] ; Check if command line is empty cmp cl, 0 ; Parameter specified? je @@50 ; No ; Yes, so ; Copy Command Line To File Specification Buffer push ds es push es dec cx mov dx, cx ; Save Length mov si, offset Search_Spec push ds si pop di es mov si, Offset (es:Psp).CommandTail ; Position to command line inc si ; but skip space character pop ds cld rep movsb ; Copy Command_Tail pop es ds ; Determine specified search file mask mov si, offset Search_Spec push ds si pop di es mov cx, dx ; Search length add di, cx ; Go to end of path inc cx inc cx std ; Search direction is down xor ax, ax ; Reset ax mov al, BACKSLASH ; Search for the "\" character repne scasb ; Search uses es:di cld ; Cancel the std setting mov si, offset File_Mask push ds si pop di es mov si, offset Search_Spec add si, cx mov cx, FILE_NAME_LENGTH ; Copy length rep movsb ; Copy path to search path @@10: ; Check input for "*." mov si, offset Search_Spec cmp [byte ds:si], ASTERISK jne @@20 cmp [byte ds:si + 1], DOT je @@50 @@20: ; Check input for ".\" mov si, offset Search_Spec cmp [byte ds:si], DOT jne @@30 cmp [byte ds:si + 1], BACKSLASH jne @@30 mov di, offset Input_Spec mov cx, PATH_LENGTH rep movsb ; Get current drive and directory mov si, offset Search_Spec ; Get default drive xor ax, ax ; Reset ax mov ah, DOS_GET_DEFAULT_DRIVE ; Get Default Drive int DOS_SERVICE add al, 041h ; Because of 0-based stuff ; Process Drive mov [byte ds:si], al ; Process Drive letter inc si mov [byte ds:si], COLON inc si mov [byte ds:si], BACKSLASH inc si ; Get current directory push dx xor ax, ax ; Reset ax mov ah, DOS_GET_CURRENT_DIRECTORY xor dx, dx ; Reset dx mov dl, DOS_DEFAULT_DRIVE int DOS_SERVICE pop dx ; Add "\" character to end of current directory? mov si, offset Search_Spec push ds si pop di es mov cx, PATH_LENGTH ; Search length xor ax, ax ; Search for null character repne scasb ; Search uses es:di dec di ; Pointer adjustment after search cmp [byte es:di - 1], BACKSLASH ; Is there a "\" already? je @@25 ; Yes ; No, so ; Add "\" character to end of current directory mov [byte es:di], BACKSLASH inc di @@25: mov si, offset Input_Spec inc si inc si mov cx, dx rep movsb jmp @@99 @@30: ; Check input for ":\" mov si, offset Search_Spec cmp [byte ds:si + 1], COLON jne @@50 cmp [byte ds:si + 2], BACKSLASH je @@99 @@50: ; No parameters specified mov si, offset Search_Spec ; Get default drive xor ax, ax ; Reset ax mov ah, DOS_GET_DEFAULT_DRIVE ; Get Default Drive int DOS_SERVICE add al, 041h ; Because of 0-based stuff ; Process Drive mov [byte ds:si], al ; Process Drive letter inc si mov [byte ds:si], COLON inc si mov [byte ds:si], BACKSLASH inc si ; Get current directory xor ax, ax ; Reset ax mov ah, DOS_GET_CURRENT_DIRECTORY xor dx, dx ; Reset dx mov dl, DOS_DEFAULT_DRIVE int DOS_SERVICE ; Add "\" character to end of current directory? mov si, offset Search_Spec push ds si pop di es mov cx, PATH_LENGTH ; Search length xor ax, ax ; Search for null character repne scasb ; Search uses es:di dec di ; Pointer adjustment after search cmp [byte es:di - 1], BACKSLASH ; Is there a "\" already? je @@99 ; Yes ; No, so ; Add "\" character to end of current directory mov [byte es:di], BACKSLASH @@99: ret ENDP Check_Command_Line_Syntax ;********************************************************************** PROC Show_Msg_Listing ;********************************************************************** mov si, offset Msg_Listing push ds si pop di es call Display_String ret ENDP Show_Msg_Listing ;********************************************************************** PROC Init_Program ;********************************************************************** ; Init Directory Map mov si, offset Work_Dir_Map push ds si pop di es xor ax, ax ; Reset table mov cx, Work_Dir_Map_Length ; Nr of Bytes in Dir Table rep stosb ; ; Set up search path ; mov si, offset Path_Spec push ds si pop di es mov si, offset Search_Spec mov cx, PATH_LENGTH ; Copy length rep movsb ; Copy path to search path call Setup_Path_Spec_Dir ; ; Determine Current Directories ; call DC_DIRS ; ; Process found directories ; mov si, offset Work_Dir_Map push ds si pop di es call Process_Pc_Dirs ret ENDP Init_Program ;********************************************************************** PROC Process_Dirs_Files ;********************************************************************** @@00: ; ; Process Files in Dir ; ; ; Set up search path ; mov si, offset Path_Spec push ds si pop di es mov si, offset Search_Spec mov cx, PATH_LENGTH ; Copy length rep movsb ; Copy path to search path call Setup_Path_Spec_File ; ; Show which directory we are processing ; mov si, offset Msg_Processing push ds si pop di es call Display_String mov si, offset Path_Spec push ds si pop di es call Display_String ; ; Determine Current Files ; call DC_FILES call Process_Pc_Files @@10: cmp [Dirs_To_Process], 0 ; Are there dirs to process? je @@99 ; No ; Yes, so ; ; Process last subdir ; dec [Dirs_To_Process] ; ; Set up search path ; xor cx, cx ; Reset cx mov cl, [Dirs_To_Process] xor ax, ax ; Reset ax mov al, PATH_LENGTH mul cx ; Calculate correct entry mov di, offset Search_Spec mov si, offset Work_Dir_Map add si, ax ; Correct entry reached push ds si mov cx, PATH_LENGTH ; Copy length rep movsb ; Copy path to search path mov di, offset Path_Spec mov si, offset Search_Spec mov cx, PATH_LENGTH ; Copy length rep movsb ; Copy path to search path call Setup_Path_Spec_Dir ; ; Determine Current Directories ; call DC_DIRS pop di es call Process_Pc_Dirs jmp @@00 @@99: ret ENDP Process_Dirs_Files ;********************************************************************** PROC Process_Pc_Dirs ;********************************************************************** mov si, offset Dir_Map @@10: ; ; Check if we have to process a found directory ; cmp [byte ds:si], NULL ; Something to process? je @@99 ; No ; Yes,so ; ; Determine specified search file mask ; push es di ; Save Work_Dir_Map pointer push ds si ; Save Dir_Map pointer push es di ; Another copy of Work_Dir_Map mov si, offset Search_Spec push ds si pop di es mov cx, PATH_LENGTH ; Search length dec cx ; Because of null terminator add di, cx ; Go to end of path std ; Search direction is down xor ax, ax ; Reset ax mov al, BACKSLASH ; Search for the "\" character repne scasb ; Search uses es:di cld ; Cancel the std setting inc cx ; Pointer adjustment after search inc cx ; Include the "\" character pop di es ; Restore Work_Dir_Map pointer mov si, offset Search_Spec rep movsb ; Copy search spec to work map ; Add directory name to search spec pop si ds push ds si mov cx, DIR_NAME_LENGTH rep movsb ; Search the null terminator mov cx, DIR_NAME_LENGTH ; Search length sub di, cx xor ax, ax ; Search for null character repne scasb ; Search uses es:di dec di ; Pointer adjustment after search ; Add the "\" character to search spec mov [byte es:di], BACKSLASH ; Increase number of directories to process inc [Dirs_To_Process] ; Go to next entry pop si ds di es add si, DIR_ENTRY_LENGTH add di, PATH_LENGTH jmp @@10 @@99: ret ENDP Process_Pc_Dirs ;********************************************************************** PROC Process_Pc_Files ;********************************************************************** mov si, offset File_Map @@10: ; ; Check if we have to process a found file ; cmp [byte ds:si], NULL ; Something to process? je @@99 ; No push ds si ; Save File_Map pointer ; ; Copy Entry ; mov si, offset File_Map_Entry push ds si pop di es pop si ds push ds si mov cx, FILE_ENTRY_LENGTH rep movsb ; ; Determine specified search file mask ; mov di, offset Path_Spec mov cx, PATH_LENGTH ; Search length dec cx ; Because of null terminator add di, cx ; Go to end of path std ; Search direction is down xor ax, ax ; Reset ax mov al, BACKSLASH ; Search for the "\" character repne scasb ; Search uses es:di cld ; Cancel the std setting inc di ; Pointer adjustment after search inc di ; Skip the "\" character ; Add FileName to Path Spec mov si, offset File_Map_Entry.File_Name mov cx, FILE_NAME_LENGTH rep movsb mov [byte es:di], NULL ; ; Is this an Atari 8bit Disk Image File? ; call Process_Atari_8bit_Image ; ; Go to next entry ; pop si ds add si, FILE_ENTRY_LENGTH jmp @@10 @@99: ret ENDP Process_Pc_Files ;********************************************************************** PROC Process_Atari_8bit_Image ;********************************************************************** ; Check for valid 8bit image disk here ; Check file size ; ahal bhbl ; File Size Single -> 0001:6800 for .XFD and 0001:6810 for .ATR ; File Size Medium -> 0002:0800 for .XFD and 0002:0810 for .ATR ; File Size Enhanced -> 0002:3000 for .XFD and 0002:3010 for .ATR ; File Size Double -> 0002:D000 for .XFD and 0002:D010 for .ATR @@30: mov si, offset File_Map_Entry.File_Size mov bx, [ds:si] mov ax, [ds:si + 2] cmp ah, 000h ; 00xx:xxxx? jne @@99 ; No ; Yes cmp bl, 000h ; xxxx:xx00? je @@31 ; Yes ; No, so cmp bl, 010h ; xxxx:xx10? jne @@99 ; No, incorrect disk size ; Yes ; Check Single @@31: cmp bh, 068h ; xxxx:68xx? jne @@32 ; No ; Yes, so cmp al, 001h ; xx01:xxxx? je @@40 ; Yes ; No, so ; Check Medium @@32: cmp bh, 008h ; xxxx:08xx? jne @@33 ; No ; Yes, so cmp al, 002h ; xx02:xxxx? je @@40 ; Yes ; No, so ; Check Enhanced @@33: cmp bh, 030h ; xxxx:30xx? jne @@34 ; No ; Yes, so cmp al, 002h ; xx02:xxxx? je @@40 ; Yes ; No, so ; Check Double @@34: cmp bh, 0D0h ; xxxx:D0xx? jne @@99 ; No ; Yes, so cmp al, 002h ; xx02:xxxx? jne @@99 ; No ; Yes, so @@40: ; Open file mov dx, offset Path_Spec mov ah, DOS_OPEN_FILE mov al, DOS_FILE_READ_ONLY int DOS_SERVICE jc @@99 ; Open ERROR! mov [Input_File], ax ; Load handle cmp bl, 000h ; xxxx:xx00? je @@50 ; Yes, .XFD file ; No, so ; Read file header mov ah, DOS_READ_FROM_HANDLE mov bx, [Input_File] mov cx, ATR_HEADER_SIZE ; Header size mov dx, offset Disk_I_O_Buffer int DOS_SERVICE ; Read header jc @@80 ; Stop on error or ax, ax ; End of file? jz @@80 ; Yes ; No, so ; Check file header single mov si, offset ATR_Header_Single push ds si pop di es mov si, offset Disk_I_O_Buffer mov cx, ATR_HEADER_SIZE_COMPARE rep cmpsb ; Header is .ATR Single? je @@50 ; Yes ; No, so ; Check file header medium mov si, offset ATR_Header_Medium push ds si pop di es mov si, offset Disk_I_O_Buffer mov cx, ATR_HEADER_SIZE_COMPARE rep cmpsb ; Header is .ATR Medium? je @@50 ; Yes ; No, so ; Check file header enhanced mov si, offset ATR_Header_Enhanced push ds si pop di es mov si, offset Disk_I_O_Buffer mov cx, ATR_HEADER_SIZE_COMPARE rep cmpsb ; Header is .ATR Enhanced? je @@50 ; Yes, ; No, so ; Check file header double mov si, offset ATR_Header_Double push ds si pop di es mov si, offset Disk_I_O_Buffer mov cx, ATR_HEADER_SIZE_COMPARE rep cmpsb ; Header is .ATR Double? je @@50 ; Yes ; No, so jmp @@80 @@50: ; Move to 8bit vtoc location (offset B400h, 8 sectors wide) mov ah, DOS_MOVE_FILE_POINTER mov al, DOS_MOVE_FILE_POINTER_CURR mov bx, [Input_File] xor cx, cx ; Reset Offset cx:dx mov dx, EIGHTBIT_VTOC_OFFSET int DOS_SERVICE ; Position in dx:ax ; Read 8bit vtoc mov ah, DOS_READ_FROM_HANDLE mov bx, [Input_File] mov cx, EIGHTBIT_VTOC_SIZE ; Sector size mov dx, offset Disk_I_O_Buffer int DOS_SERVICE ; Read header jc @@80 ; Stop on error or ax, ax ; End of file? jz @@80 ; Yes @@54: ; ; Create locator file, if not done already ; cmp [Locator_File_Opened], TRUE je @@56 ; ; Create Locator File ; ; Open output file mov dx, offset Locator_File_Spec xor cx, cx ; Normal attributes mov ah, DOS_CREATE_FILE int DOS_SERVICE jc @@80 ; Skip processing on error mov [Output_File], ax ; Store handle mov [Locator_File_Opened], TRUE ; ; Write Headers ; mov ah, DOS_WRITE_TO_HANDLE mov bx, [Output_File] mov cx, Locator_Entry_Length mov dx, offset Output_Header_1 int DOS_SERVICE ; Write character(s) call Write_Return_Linefeed mov ah, DOS_WRITE_TO_HANDLE mov bx, [Output_File] mov cx, Locator_Entry_Length mov dx, offset Output_Header_2 int DOS_SERVICE ; Write character(s) call Write_Return_Linefeed @@56: ; ; Process 8 bit files ; mov cx, EIGHTBIT_VTOC_FILES ; Maximum nr of 8bit vtoc files mov si, offset Disk_I_O_Buffer @@58: push cx ds si ; ; Init Output Line ; push ds si mov si, offset Locator_Entry push ds si pop di es mov ax, SPACE mov cx, Locator_Entry_Length rep stosb pop si ds ; ; Entry present? ; cmp [byte ds:si], NULL ; Entry present? je @@78 ; No ; Yes, so ; ; Process Atari 8 bit filename ; xor ax, ax ; Reset ax mov al, [byte ds:si] ; File Status mov bh, [byte ds:si + 2] ; File Size hi mov bl, [byte ds:si + 1] ; File Size lo ; ; Validate Filename ; add si, 5 ; Begin of filename, i.e. MYFILE TXT push ds si pop di es mov cx, EIGHTBIT_FILE_NAME_LENGTH @@59: cmp [byte ds:si], " " ; Less than or equal " "? jl @@77 ; Yes ; No, so cmp [byte ds:si], "Z" ; greater than "Z"? jnle @@77 ; Yes ; No, so inc si ; Next byte loop @@59 push es di ; ; Move filename ; mov si, offset Locator_Entry.File_Name push ds si pop di es pop si ds mov cx, 8 ; Size of filename rep movsb ; Move "MYFILE" part ; ; Search for space character ; cmp [byte ds:si], SPACE ; Is there an extension je @@60 ; No ; Yes, so push ds si push ax mov si, offset Locator_Entry.File_Name push ds si pop di es mov cx, FILE_NAME_LENGTH ; Size of filename add di, cx ; Go to end of filename inc cx ; Because of search down std ; Search direction is down xor ax, ax mov ax, SPACE repe scasb ; Find the non space cld ; Reset search direction inc di ; Adjustment after search inc di ; Adjustment after search pop ax pop si ds ; ; Append extension ; mov [byte es:di], DOT ; Insert a "." inc di ; Move to extender part mov cx, 3 ; Size of extender rep movsb ; Move "TXT" part @@60: ; ; Check Atari 8 bit File Status ; ; ; Atari 8 bit File deleted? ; mov di, offset Locator_Entry.File_Del mov si, offset Output_No mov cx, 3 rep movsb push ax and al, 080h ; Check Delete Status cmp al, 080h ; File Deleted? pop ax jne @@63 ; No ; Yes , so mov di, offset Locator_Entry.File_Del mov si, offset Output_Yes mov cx, 3 rep movsb @@63: ; ; Atari 8 bit File locked? ; mov di, offset Locator_Entry.File_Lck mov si, offset Output_No mov cx, 3 rep movsb push ax and al, 020h ; Check Lock Status cmp al, 020h ; File Locked? pop ax jne @@64 ; No ; Yes , so mov di, offset Locator_Entry.File_Lck mov si, offset Output_Yes mov cx, 3 rep movsb @@64: ; ; Atari 8 bit File extended? ; mov di, offset Locator_Entry.File_Ext mov si, offset Output_No mov cx, 3 rep movsb and al, 001h ; Check Extended Status cmp al, 001h ; File Extended? jne @@65 ; No ; Yes , so mov di, offset Locator_Entry.File_Ext mov si, offset Output_Yes mov cx, 3 rep movsb @@65: ; ; Atari 8 bit File Size ; mov di, offset Locator_Entry.File_Size add di, 3 mov ax, bx ; File Size mov bx, 10 ; Extract digits ; Convert hexadecimal size to textual digits call Extract_Digit ; Convert value below 10000 call Extract_Digit call Extract_Digit call Extract_Digit ; ; Surpress leading zeroes ; mov bx, 4 @@67: inc di ; Move to digital character cmp [byte es:di], ZERO ; Character is leading zero? jne @@68 ; No ; Yes, so mov [byte es:di], SPACE ; Replace leading zero by space dec bx ; More characters to check? jnz @@67 ; Yes ; No, so ; ; We have a comment here, skip processing ; jmp @@77 @@68: ; ; Uppercase Path Spec ; mov di, offset Path_Spec ; set es:di to string to be upper-ed push es di call TO_UPPER pop di es ; ; Specify Pc Pathname ; mov di, offset Locator_Entry.File_Path mov si, offset Path_Spec mov cx, PATH_LENGTH rep movsb ; ; Write this puppy ; mov ah, DOS_WRITE_TO_HANDLE mov bx, [Output_File] mov cx, Locator_Entry_Length mov dx, offset Locator_Entry int DOS_SERVICE ; Write character(s) jc @@80 ; Close files on error or ax, ax ; Disk full? jz @@80 ; Yes ; No, so call Write_Return_Linefeed @@77: pop si ds cx add si, EIGHTBIT_FILE_ENTRY_SIZE ; Move to next vtoc entry dec cx ; Complete vtoc scanned? jnz @@58 ; No ; Yes, so jmp @@80 @@78: pop si ds cx @@80: ; Close file mov bx, [Input_File] mov al, NULL mov ah, DOS_CLOSE_FILE int DOS_SERVICE @@99: ret ENDP Process_Atari_8bit_Image ;********************************************************************** PROC Write_Return_Linefeed ;********************************************************************** mov ah, DOS_WRITE_TO_HANDLE mov bx, [Output_File] mov cx, 2 mov dx, offset Output_Return_Linefeed int DOS_SERVICE ; Write character(s) ret ENDP Write_Return_Linefeed ;********************************************************************** PROC Setup_Path_Spec_Dir ;********************************************************************** mov di, offset Path_Spec mov cx, PATH_LENGTH ; Search length dec cx ; Because of null terminator add di, cx ; Go to end of path std ; Search direction is down xor ax, ax ; Reset ax mov al, BACKSLASH ; Search for the "\" character repne scasb ; Search uses es:di cld ; Cancel the std setting inc di ; Pointer adjustment after search inc di ; Skip the "\" character ; Add Dir Mask to Path Spec mov si, offset Dir_Mask mov cx, FILE_NAME_LENGTH ; Copy length rep movsb ; Copy path to search path ret ENDP Setup_Path_Spec_Dir ;********************************************************************** PROC Setup_Path_Spec_File ;********************************************************************** mov di, offset Path_Spec mov cx, PATH_LENGTH ; Search length dec cx ; Because of null terminator add di, cx ; Go to end of path std ; Search direction is down xor ax, ax ; Reset ax mov al, BACKSLASH ; Search for the "\" character repne scasb ; Search uses es:di cld ; Cancel the std setting inc di ; Pointer adjustment after search inc di ; Skip the "\" character ; Add File Mask to Path Spec mov si, offset File_Mask mov cx, FILE_NAME_LENGTH ; Copy length rep movsb ; Copy path to search path ret ENDP Setup_Path_Spec_File ;********************************************************************** PROC Extract_Digit ;********************************************************************** xor dx, dx ; Reset result div bx ; Extract digit add dx, 030h ; Turn digit into character cmp [byte es:di], DECIMAL_SEPERATOR ; Character is decimal? jne @@10 ; No ; Yes, so dec di ; Move to previous character @@10: mov [byte es:di], dl ; Move character to text dec di ; Move to previous character ret ENDP Extract_Digit ;********************************************************************** PROC Show_Msg_Thank_You ;********************************************************************** mov si, offset Msg_Listing_Completed push ds si pop di es call Display_String cmp [Locator_File_Opened], TRUE ; Locator.txt file present? je @@10 ; Yes ; No, so mov si, offset Msg_No_Look push ds si pop di es call Display_String jmp @@20 @@10: mov si, offset Msg_Look push ds si pop di es call Display_String @@20: mov si, offset Msg_Thank_You push ds si pop di es call Display_String ret ENDP Show_Msg_Thank_You ;********************************************************************** PROC Display_String ;********************************************************************** @@00: cmp [byte es:di], NULL ; Check for the NULL character je @@99 mov dl, [byte es:di] mov ah,DOS_WRITE_CHARACTER int DOS_SERVICE inc di ; Point to the next character jmp @@00 @@99: ret ENDP Display_String ;********************************************************************** PROC Exit_Program ;********************************************************************** mov ah, DOS_TERMINATE_EXE mov al, [Return_Code] ; Return code value int DOS_SERVICE ENDP Exit_Program ENDS CSeg ; End of Code segment END Main