From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/CMD/LABEL/LABEL.ASM | 1351 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1351 insertions(+) create mode 100644 v4.0/src/CMD/LABEL/LABEL.ASM (limited to 'v4.0/src/CMD/LABEL/LABEL.ASM') diff --git a/v4.0/src/CMD/LABEL/LABEL.ASM b/v4.0/src/CMD/LABEL/LABEL.ASM new file mode 100644 index 0000000..c29d5b7 --- /dev/null +++ b/v4.0/src/CMD/LABEL/LABEL.ASM @@ -0,0 +1,1351 @@ + PAGE 90,132 ;A2 + title LABEL.SAL - DOS LABEL COMMAND +;***************************************************************************** +;* * +;* MODULE NAME: LABEL * +;* * +;* DESCRIPTIVE NAME: LABEL a diskette or disk * +;* * +;* FUNCTION: Create, change or delete a volume label on a disk. * +;* * +;* ENTRY POINT: Start * +;* * +;* INPUT: (DOS command line parameters) * +;* [d:][path]LABEL [d:][volume label] * +;* where: * +;* [d:][path] before LABEL specifies the drive and path that contains * +;* the LABEL command file. * +;* * +;* [d:][volume label] specifies the volume label. Volume labels are * +;* used to identify a disk. They can be up to 11 characters and are in * +;* the same format as volume labels created by FORMAT/V. * +;* * +;* EXIT-NORMAL: ERRORLEVEL 0 - Normal completion * +;* * +;* EXIT-ERROR: ERRORLEVEL 1 - Any error * +;* * +;* EFFECTS: The volume label is set to the indicated string. The volume * +;* serial number, if present, is also displayed. * +;* * +;* INCLUDED FILES: None * +;* * +;* INTERNAL REFERENCES: * +;* * +;* Routines: * +;* CHARACTER_CHECK - See if char is valid for filename * +;* CHECK_DELETE - Get user Y/N if to delete old label * +;* CHECK_FOR_DRIVE_LETTER - Parse for drive in string * +;* CHECK_TRANSLATE_DRIVE - See if drive is SUBST or ASSIGN * +;* CHK_DBCS -See if specified byte is a DBCS lead byte * +;* CHK_DBCS_BLANK - Process DBCS blank char * +;* CREATE_NEW_LABEL - Output new vol label * +;* DATA AREAS - STACK, buffers, FCB'S, message sublists * +;* DELETE_OLD_LABEL - Delete original volume label * +;* DISPLAY_MSG - Send msg to system message handler * +;* DRIVE_SETUP - Verify drive, get default, setup drive ID * +;* ERROR_EXIT - Abnormal return to DOS * +;* FIND_FIRST_CHAR - Locate first non blank in input * +;* FIND_OLD_LABEL - Get the existing volume label * +;* GET_NEW_LABEL - Parse new vol label name into path * +;* GET_SERIAL_NUM - Get vol ser number from "GET_MEDIA_ID" * +;* GET_USER_INPUT - Read from user new vol label * +;* MAIN CODE - PSP, entry point * +;* MAIN_BEGIN - High level function control * +;* OUTPUT_OLD_LABEL - Display the original vol label * +;* PRELOAD_MESSAGES - Set up sys msgs, DOS version check * +;* PROCESS_STRING - Mov string to buf, check bad chars * +;* SETUP_CRLF - Carriage return, line feed * +;* SETUP_DELLABEL - "Delete current volume label (Y/N)?" * +;* SETUP_HASLABEL - "Volume in drive %1 is %2" * +;* SETUP_INVCHAR - "Invalid characters in volume label" * +;* SETUP_INVDRIVE - "Invalid drive specification" * +;* SETUP_NETDRIVE - "Cannot %1 a Network drive" * +;* SETUP_NEWLABEL - "Volume label (11 characters, ENTER for none)?" * +;* SETUP_NOLABEL - "Volume in drive %1 has no label" * +;* SETUP_NOROOM - "Cannot make directory entry" * +;* SETUP_SERIALNUM - "Volume Serial Number is %1-%2" * +;* SETUP_SUBSTASGN - "Cannot %1 a SUBSTed or ASSIGNed drive" * +;* SETUP_TOOMANY - "Too many files open" * +;* * +;* Data Areas: * +;* CONTROL BLOCKS - SUBLISTS for message parameters * +;* BUFFERS - For GET_MEDIA_ID, several FCB'S * +;* PSP - Contains the DOS command line parameters. * +;* STACK - Temporary save area * +;* * +;* EXTERNAL REFERENCES: * +;* * +;* Routines: * +;* SYSDISPMSG (NEAR) - Message display routine * +;* SYSLOADMSG (NEAR) - System message loader * +;* * +;* Data Areas: * +;* DTA - defined for the DOS FINDFIRST function. * +;* * +;* NOTES: LABEL should not be used with SUBSTed drives. The root directory * +;* of the actual drive will be the target of LABEL. LABEL should * +;* not be used with ASSIGNed drives or to label network drives. * * +;* * +;* This module should be processed with the SALUT pre-processor * +;* with the re-alignment not requested, as: * +;* * +;* SALUT LABEL,NUL * +;* * +;* To assemble these modules, the sequential or alphabetical * +;* ordering of segments may be used. * +;* * +;* Sample LINK command: * +;* * +;* LINK @LABEL.ARF * +;* * +;* Where the LABEL.ARF is defined as: * +;* * +;* LABEL+ * +;* LABELM * +;* * +;* These modules should be linked in this order. The load module is * +;* a COM file. It should be converted via EXE2BIN to a .COM file. * +;* * +;* REVISION HISTORY: * +;* * +;* AN000;D DBCS Support (New LOC) 06/87 S. Maes * +;* AN000;M Message service routine (New LOC) 06/87 S. Maes * +;* AC000;M Message service routine (Changed LOC) 06/87 S. Maes * +;* AN000;S Serial Number (New LOC) 06/87 S. Maes * +;* AC000;K SALUT 08/87 E. Kiser * +;* Ax001; DCR0524 - enable deletion of labelID 04/88 S. Maes * +;* Ax002; PTM4282 - parse complete line for invalids 04/88 S. Maes * +;* AN003; PTM4588 - scan entire line fails DBCS 05/88 S. Maes * +;* * +;* COPYRIGHT: The following notice is found in the OBJ code generated * +;* in the LABELM.SAL module. * +;* * +;* "Version 4.00 (C)Copyright 1988 Microsoft +;* "Licensed Material - Program Property of Microsoft" * +;* * +;***************************************************************************** + HEADER +IF1 + %OUT COMPONENT=LABEL, MODULE=LABEL.SAL +ENDIF +HEADER MACRO TEXT +.XLIST + SUBTTL &TEXT +.LIST + PAGE + ENDM +;***************************************************************************** +; Equate Area +;***************************************************************************** +; $SALUT (4,20,25,36) ;AN000;K +; DOS FUNCTION CALLS +FCB_SEARCH equ 11h +FCB_DELETE equ 13h +GET_DEFAULT equ 19h +SET_DTA equ 1Ah +CLOSE equ 3Eh +READ equ 3Fh +IOCTL equ 44h +LOC_OR_NET equ 9h ;AN000;K Local or network, subfunc of IOCTL +EXIT equ 4Ch +CREATE_FILE equ 5Bh +YN_CHECK equ 6523h ;AN001; 65=GetExtCtry 23=Y/NCheck +GET_MEDIA_ID equ 6900h ;AN000;S Int 21 for Serial Number +GET_DBCS_ENV equ 6300h ;AN000;D DBCS support +XNAMETRANS equ 60h ;AN000; + +; DBCS SPECIAL CHARACTER DEFINITIONS + +DBCSBLK_BYTEONE equ 81h ;AN000;D 1st byte of DBCS blank +DBCSBLK_BYTETWO equ 40h ;AN000;D 2nd byte of DBCS blank +SBCSBLANKS equ 2020h ;AN000;D 2 SBCS blanks + +; MISCELLANEOUS EQUATES + +ASCII_DRV equ "A"-1 ;AN000;D Convert to Ascii drive +BLANK equ " " +CHAR_ZERO equ "0" ;AN000;K Padding for serial number +COLON equ ":" +DEFAULT_DRIVE equ 0 +DOT_LOCATION equ 8 +DRIVE_INVALID equ 0FFh +END_OF_STRING equ 0 +MAX_CHARS equ 11 +MAX_INPUT equ 100h-81h ;Size of input buffer +NO equ 0 ;AN001; Compare for Y/N response +PERIOD equ "." +YES equ 1 ;AN001; Compare for Y/N response +ZERO equ 0 + +; ERROR LEVEL RETURN CODES + +ERRORLEVEL_0 equ 0 +ERRORLEVEL_1 equ 1 + +; ATTRIBUTE OF DIRECTORY ENTRY + +VOL_ATTRIBUTE equ 8 + +; ERROR CODES FROM DOS FUNCTIONS + +VOL_NOT_FOUND equ 0FFh +TOO_MANY_FILES equ 4 + +; ID IF MESSAGES DISPLAYED BY "LABEL" + +TOO_MANY_MSG equ 1 ;AN000;M Too many files open +NO_ROOM_MSG equ 2 ;AN000;M Cannot make directory entry +INV_CHAR_MSG equ 3 ;AN000;M Invalid characters in volume label +NEW_LABEL_MSG equ 4 ;AN000;M Vol label (11 chars, ENTER for none)? +INV_DRIVE_MSG equ 5 ;AN000;M Invalid drive specification +NETWORKDRIVEMSG equ 6 ;AN000;M Cannot %1 a Network drive +SUBSTASSIGNMSG equ 7 ;AN000;M Cannot %1 a SUBSTed or ASSIGNed drive +NO_LABEL_MSG equ 8 ;AN000;M Volume in drive %1 has no label +SERIAL_NUM_MSG equ 9 ;AN000;M Volume Serial Number is %1 +HAS_LABEL_MSG equ 10 ;AN000;M Volume in Drive %1 is %2 +DEL_LABEL_MSG equ 11 ;AN001;M Delete current volume label (Y/N)? +CRLF_MSG equ 12 ;AN001;M CR,LF + +; DEFINITIONS OF FIELDS WITHIN MSG SUBLISTS + +MAXWIDTH equ 0 ;AN000;M 0 will ensure no padding +MINWIDTH equ 1 ;AN000;M At least 1 char to insert in msg +STR_INPUT equ 16 ;AN000;M Byte definition for s?_flags +SUBLIST_LENGTH equ 11 ;AN000;M Length of sublist structure +RESERVED equ 0 ;AN000;M Reserved byte field +CR equ 0Dh ;Carriage Return +NO_INPUT equ 00h ;AN000;M No input characters +DOS_CON_INPUT equ 00C8h ;AN000;M No input characters +EXT_ERR_CLASS equ 01h ;AN000;M DOS Extended error class +UTILITY_MSG_CLASS equ 0FFh ;AN000;M Utility message class +STDIN equ 0000h ;File handle +STDOUT equ 0001h ;Standard Output device handle +STDERR equ 0002h ;Standard Error Output device handle +BIN_HEX_WORD equ 23h ;AN000;M a0100011 +RIGHT_ALIGN equ 80h ;AN000;M 10xxxxxx +CHAR_FIELD_CHAR equ 0 ;AN000;M a0000000 + HEADER
+CSEG segment public + + ASSUME cs:CSEG,ds:CSEG,es:CSEG,ss:CSEG + + EXTRN SYSDISPMSG:NEAR ;SYSTEM DISPLAY MESSAGE ROUTINE + EXTRN SYSLOADMSG:NEAR ;SYSTEM MESSAGE LOADER ROUTINE + + org 5Ch +FCB1 label byte + + org 80h +Num_Parms label byte + + org 81h +Parm_Area label byte + + org 100h +Start: ;DOS ENTRY POINT + jmp Main_Begin ;SKIP CONSTANTS + HEADER + EVEN +Stack_Area db 512 dup ("S") ;Added in DOS 3.20 to support hardware requiring +End_Stack_Area db 0 ;large stacks. DO NOT PUT DATA ABOVE THIS ! +New_Vol_Path db " :\" ;Path for new vol label +New_Vol_Name db " " ;Where first 8 chars go +New_Vol_Ext db ". ",0 ;Dot and extension +End_Parameters dw 0 ;End of input string + +Program_Flag db 0 ;Status Flag +USER_INPUT equ 01h ;User has input already +LABEL_FND equ 02h ;Volume label found +NO_DELETE equ 04h ;No need for label delete +GET_INPUT equ 08h ;Need user input +CHAR_BAD equ 10h ;Invalid character in string +FOUND_DBCS equ 20h ;AN000;K in process of handling DBCS chars + +Vol_FCB db 0FFh ;Extended FCB + db 0,0,0,0,0 + db VOL_ATTRIBUTE ;Attribute for vol label +FCB_Drive db 0 ;Drive number +Vol_Name db "???????????" ;Match any vol name found + db 25 dup (0) ;Rest of the opened FCB +Label_Name db "???????????",0 ;AN000; +FCB_Drive_Char db " " ;AN000;K printable version of FCB_Drive above + +TranSrc db "A:CON",0,0 ;AN000;A Device so we don't hit the drive +TranDst db 64 dup(' ') ;AN000;A +Label_Word db "LABEL",0 ;AN000;M Message substitution parm + +Del_FCB db 0FFh ;Extended FCB + db 0,0,0,0,0 + db VOL_ATTRIBUTE ;Attribute for vol label +Del_Drive db 0 ;Drive number +Del_Name db "???????????" ;Match any vol name found + +; MESSAGE SUBLIST STRUCTURES + +Sublist1 Label Dword ;AN000;M Substitution list +s1_nxtlst db SUBLIST_LENGTH ;AN000;M (11)Ptr to next sublist +s1_reserve db RESERVED ;AN000;M (0)Reserved +s1_offset dw ? ;AN000;M Time/date or data pointer +s1_segment dw ? ;AN000;M Time/date or data pointer +s1_id db 1 ;AN000;M N of %n +s1_flags db ? ;AN000;M Data-type flags (a0sstttt) +s1_maxwidth db ? ;AN000;M Maximum field width +s1_minwidth db ? ;AN000;M Minimum field width +s1_padchar db ? ;AN000;M Char to pad field + +Sublist2 Label Dword ;AN000;M Substitution list +s2_nxtlst db SUBLIST_LENGTH ;AN000;M (11)Ptr to next sublist +s2_reserve db RESERVED ;AN000;M (0)Reserved +s2_offset dw ? ;AN000;M Time/date or data pointer +s2_segment dw ? ;AN000;M Time/date or data pointer +s2_id db 2 ;AN000;M N of %n +s2_flags db ? ;AN000;M Data-type flags (a0sstttt) +s2_maxwidth db ? ;AN000;M Maximum field width +s2_minwidth db ? ;AN000;M Minimum field width +s2_padchar db ? ;AN000;M Char to pad field + +; GET_MEDIA_ID STRUCTURE + +SerNumBuf Label Byte ;AN000;S GET_MEDIA_ID buffer + dw 0 ;AN000;S Info level (set on input) +SerNum dd 0 ;AN000;S Serial # + db 11 DUP(' ') ;AN000;S Volume label + db 8 DUP(' ') ;AN000;S File system type + +; CHK_DBCS STRUCTURE +DBCSev_Off dw 0 ;AC000;D offset of DBCS EV +DBCSev_Seg dw 0 ;AC000;D segment of DBCS EV + + HEADER +; $SALUT (4,4,9,36) ;AN000;K +;***************************************************************************** +;* * +;* SUBROUTINE NAME: main_begin * +;* * +;* SUBROUTINE FUNCTION: Preload message file and check DOS version * +;* by calling SYSLOADMSG * +;* Get the command line parameters * +;* Parse command line * +;* Verify the correctness of the parameters * +;* Get label if exists * +;* Get serial number if exists * +;* Get new volume name * +;* Make new volume file * +;* Print messages by calling SYSDISPMSG * +;* * +;* EXTERNAL ROUTINES: SYSDISPMSG * +;* SYSLOADMSG * +;* * +;* INTERNAL ROUTINES: Character_Check Main_Begin * +;* Check_Delete Output_Old_Label * +;* Check_For_Drive_Letter Preload_Messages * +;* Check_Trans_Drive Process_String * +;* Chk_DBCS Setup_CRLF * +;* Chk_DBCS_Blank Setup_DelLabel * +;* Create_New_Label Setup_HasLabel * +;* Delete_Old_Label Setup_InvChar * +;* Display_Msg Setup_InvDrive * +;* Drive_Setup Setup_NetDrive * +;* Error_Exit Setup_NewLabel * +;* Find_First_Char Setup_NoLabel * +;* Find_Old_Label Setup_NoRoom * +;* Get_New_Label Setup_SerialNum * +;* Get_Serial_Num Setup_SubstAsgn * +;* Get_User_Input Setup_TooMany * +;* * +;***************************************************************************** + PUBLIC MAIN_BEGIN +Main_Begin Proc Near + mov sp,offset End_Stack_Area ;Move stack to user area(Added in DOS 3.20) + cld + call Preload_Messages ;AN000;M Check DOS version & load msgs + call Drive_Setup ;Get Drive letters + call Find_Old_Label ;Get label if exist + call Get_New_Label ;Get New Name + call Check_Delete ;AN001; See if delete needed or wanted + call Delete_Old_Label ;Del the old label if it exists + call Create_New_Label ;Make new Vol file + mov ax,(EXIT shl 8)+ERRORLEVEL_0 ;all done, pass back zero ret code + INT 21H +Main_Begin ENDP + + HEADER +;***************************************************************************** +; Verify specified drive, get default if needed, setup drive letters +;***************************************************************************** + + PUBLIC DRIVE_SETUP +Drive_Setup PROC NEAR + cmp al,DRIVE_INVALID ;Was specified drive ok ? +; $if e ;AN000;K No + JNE $$IF1 + mov ax,INV_DRIVE_MSG ;Nope, tell & quit + call Setup_InvDrive ;AN000;M + call Display_Msg ;AN000;M Set up msg & display + call Error_Exit +; $endif ;AN000;K +$$IF1: +; Get_Drive: + mov al,FCB1 ;Get specified drive + cmp al,DEFAULT_DRIVE ;Was drive given ? +; $if e ;AN000;K No + JNE $$IF3 + mov ah,GET_DEFAULT ;No, get default drive + INT 21H + inc al ;Get a: based on 1, not 0 +; $endif ;AN000;K +$$IF3: +; Drive_Letter: + mov FCB_Drive,al ;Put drive number in FCB + mov Del_Drive,al ;Put drive number in FCB + mov bl,al + mov al,FCB_Drive ;AN000;K get numeric value of drive letter + add al,ASCII_DRV ;AN000;M ("A"-1) + mov FCB_Drive_Char,al ;AN000;K make drive printable + mov ax,(IOCTL SHL 8)+LOC_OR_NET ;(4409h)determine drive type + INT 21H + test dx,1000h ;bit 12 on means network drive +; $if nz ;AN000;K + JZ $$IF5 + mov ax,NETWORKDRIVEMSG + call Setup_NetDrive ;AN000;M + call Display_Msg ;AN000;M First display the msg + call Error_Exit +; $endif ;AN000;K +$$IF5: + call Check_Trans_Drive ;AN000;A Is drv SUBSTed/ASSIGNed? +; $if nz ;AN000;K Yes + JZ $$IF7 + mov ax,SUBSTASSIGNMSG ;AN000;A Prepare SUBST/ASSIGN msg + call Setup_SubstAsgn ;AN000;M + call Display_Msg ;AN000;A Display the message + call Error_Exit ;AN000;A Then exit +; $endif ;AN000;K +$$IF7: + mov al,Del_Drive + add al,ASCII_DRV ;AN000;K ("A"-1) Convert to Ascii + mov New_Vol_Path,al ;Put drive letter in path + ret +Drive_Setup ENDP + + HEADER +;***************************************************************************** +; Routine name: Check_Translate_Drive +;***************************************************************************** +; Descr: Do a name translate call on the drive letter to see if it is +; assigned by SUBST or ASSIGN +; Input: Drive + + PUBLIC CHECK_TRANS_DRIVE +Check_Trans_Drive PROC NEAR ;AN000;A + mov bl,FCB_Drive_Char ;AN000;A Get drive + mov byte ptr [TranSrc],bl ;AN000;A Make string "x:\" + mov si,offset TranSrc ;AN000;A Point to translate string + mov di,offset TranDst ;AN000;A Point at output buffer + mov ah,XNAMETRANS ;AN000;A (60H) Get real path + INT 21H ;AN000;A + mov bl,byte ptr [TranSrc] ;AN000;A Get drive letter from path + cmp bl,byte ptr [TranDst] ;AN000;A Did drive letter change? + ret ;AN000;A +Check_Trans_Drive ENDP ;AN000;A + + HEADER +;***************************************************************************** +; Find old volume label +;***************************************************************************** +; Input: VOL_FCB set to find any vol label +; Output: VOL_FCB has label name if one found +; PROGRAM_FLAG = LABEL_FND if one is found +; LABEL_NAME gets found label name + + PUBLIC FIND_OLD_LABEL +Find_Old_Label PROC NEAR + mov dx,offset Vol_FCB ;Point at FCB to find vol + mov ah,SET_DTA ;(1AH) + INT 21H + mov dx,offset Vol_FCB ;Point at FCB to find vol + mov ah,FCB_SEARCH ;(11H) + INT 21H ;Find vol label + cmp al,VOL_NOT_FOUND ;Find one +; $if ne ;AN000;K Yes + JE $$IF9 + or Program_Flag,LABEL_FND ;Yes, set flag + mov si,offset Vol_Name ;Found name + mov di,offset Label_Name ;Where to put it + mov cx,MAX_CHARS ;How many characters + rep movsb ;Move the string +; $endif ;AN000;K +$$IF9: +; Find_Return: + ret +Find_Old_Label ENDP + + HEADER +;***************************************************************************** +; Parse new volume label name into path. +;***************************************************************************** +; Input: PARM_AREA has input string +; Output: NEW_VOL_NAME has ASCIIZ string for new label, or an END_OF_STRING +; if nothing entered + + PUBLIC GET_NEW_LABEL +Get_New_Label PROC NEAR +; $do ;AN000;K +$$DO11: + xor cx,cx ;Zero counter + mov si,offset Parm_Area ;Input buffer + mov di,offset New_Vol_Name ;Target Buffer + call Find_First_Char ;Get first not blank char + test Program_Flag,GET_INPUT ;Find input? + jnz Need_User_Input ;No, go get it + call Process_String ;Scan string, move it + test Program_Flag,CHAR_BAD ;Invalid characters? + jnz Need_User_Input ;Yes, get user to input + mov al,END_OF_STRING ;Mark end of ASCIIZ string + stosb + cmp New_Vol_Name,END_OF_STRING ;Any chars entered? +; $leave ne ;Yes, all done here + JNE $$EN11 + test Program_Flag,USER_INPUT ;See if command line parse +; $leave nz ;No, user had his chance + JNZ $$EN11 +Need_User_Input: + test Program_Flag,USER_INPUT ;Is this the first time here? +; $if z ;AN000;K Yes, label not already gone out + JNZ $$IF14 + call Output_Old_Label ;Yes, print current vol label +; $endif ;AN000;K +$$IF14: +Input_New_Label: + call Get_User_Input ;Get new string +; $enddo ;AN000;K Go parse it again + JMP SHORT $$DO11 +$$EN11: + ret +Get_New_Label ENDP + + HEADER +;***************************************************************************** +; Find the first non blank character in input string +;***************************************************************************** +; Input: SI = pointer to next character +; Output: PROGRAM_FLAG = GET_INPUT if user input needed +; AL = First not blank character +; Notes: GET_INPUT set if nothing follows drive letter + + PUBLIC FIND_FIRST_CHAR +Find_First_Char PROC NEAR +; $do ;AN000;K +$$DO17: + and Program_Flag,not GET_INPUT ;Clear flag + lodsb ;Get char + call Chk_DBCS ;AN000;D Check DBCS env +; $if c ;AN000;K + JNC $$IF18 + call Chk_DBCS_Blank ;AN000;D Is it a DBCS blank? +; $endif ;AN000;K +$$IF18: + cmp al,BLANK ;Is it a blank? +; $enddo ne ;AN000;K No, quit + JE $$DO17 + call Check_For_Drive_Letter ;Parse out drive letter + call Chk_DBCS ;AN000;D Check DBCS env +; $if c ;AN000;K + JNC $$IF21 + call Chk_DBCS_Blank ;AN000;D Is it a DBCS blank? + and Program_Flag,not FOUND_DBCS ;AN000;K forget this was a dbcs for now +; $endif ;AN000;K +$$IF21: + cmp al,BLANK ;Blank following drive letter? +; $if e ;AN000;K + JNE $$IF23 + or Program_Flag,GET_INPUT +; $endif ;AN000;K +$$IF23: + ret +Find_First_Char ENDP + + HEADER +;***************************************************************************** +; Check DBCS environment +;***************************************************************************** +; Function: Check if a specified byte is in ranges of the DBCS lead bytes +; Input: AL = Code to be examined +; Output: If CF is on then a lead byte of DBCS +; Register: FL is used for the output, others are unchanged. + + PUBLIC CHK_DBCS +Chk_DBCS PROC ;AC000;D + push ds ;AC000;D save regs, about to be clobbered + push si ;AC000;D + cmp DBCSev_Seg,ZERO ;AC000;D Already set ? +; $if e ;AN000;K if the vector not yet found + JNE $$IF25 + push ax ;AC000;D + mov ax,GET_DBCS_ENV ;AC000;D GET DBCS EV call + INT 21H ;AC000;D ds:si points to the dbcs vector + ASSUME ds:NOTHING ;AN000;K that function clobbered old DS + mov DBCSev_Off,si ;AC000;D remem where dbcs vector is so next + mov DBCSev_Seg,ds ;AC000;D time don't have to look for it + pop ax ;AC000;D +; $endif ;AN000;K +$$IF25: + mov si,DBCSev_Off ;AC000;D set DS:SI to point to + mov ds,DBCSev_Seg ;AC000;D the dbcs vector +; $search ;AN000;K +$$DO27: + cmp word ptr [si],ZERO ;AC000;D vec ends with nul terminator entry +; $leave e ;AN000;K if that was terminator entry, quit + JE $$EN27 + cmp al,[si] ;AC000;D look at LOW value of vector +; $exitif nb,and ;AN000;K if this byte in range of LOW + JB $$IF27 + cmp al,[si+1] ;AC000;D look at HIGH value of vector +; $exitif na ;AN000;K if this byte is still in range + JA $$IF27 + or Program_Flag,FOUND_DBCS ;AN000;K remember we found one of a pair + stc ;AC000;D set flag to say, found a DBCS char +; $orelse ;AN000;K since char not in this vector + JMP SHORT $$SR27 +$$IF27: + add si,2 ;AC000;D go look at next vec in dbcs table +; $endloop ;AN000;K go back and ck out new vector entry + JMP SHORT $$DO27 +$$EN27: + clc ;AC000;D set flag to say not a DBCS char +; $endsrch ;AN000;K +$$SR27: + pop si ;AC000;D restore the regs + pop ds ;AC000;D + ASSUME ds:CSEG ;AN000;K tell masm, DS back to normal + ret ;AC000;D +Chk_DBCS ENDP ;AC000;D + + HEADER +;***************************************************************************** +; Check DBCS char for a blank (8140) +;***************************************************************************** +; Function: Check if a specified byte is a DBCS blank +; Input: AL = Byte to be examined +; SI = Points to next byte +; Output: SI = UNchanged + + PUBLIC CHK_DBCS_BLANK +Chk_DBCS_Blank PROC NEAR ;AN000;D + cmp al,DBCSBLK_BYTEONE ;AN000;D Is the leading byte 81h? +; $if e,and ;AN000;K + JNE $$IF33 + cmp byte ptr [si],DBCSBLK_BYTETWO ;AN000;D Is the 2nd byte 40h? +; $if e ;AN000;K Yes, change to 2 SBCS blanks + JNE $$IF33 +; Convert_DBCS_Blank: ;AN000;D + mov word ptr es:[si]-1,SBCSBLANKS ;AN000;D Fill it up with blank-blank + mov al,BLANK ;AN000;K pretend this char is a blank +; $endif ;AN000;K +$$IF33: +; DBCS_Blank_Exit: ;AN000;D + ret ;AN000;D And leave +Chk_DBCS_Blank ENDP ;AN000;D + + HEADER +;***************************************************************************** +; Parse a drive letter out of the string [Check_For_Drive_Letter] +;***************************************************************************** +; Input: SI = pointer to next character +; CX = character count +; Output: SI = SI+1 if drive letter entered + + PUBLIC CHECK_FOR_DRIVE_LETTER +Check_For_Drive_Letter PROC NEAR + test Program_Flag,USER_INPUT ;Input not from command line? +; $if z ;AN000;K + JNZ $$IF35 + cmp cx,END_OF_STRING ;Anything parsed yet +; $if e ;AN000; + JNE $$IF36 + cmp al,CR ;First char a CR ? +; $if ne + JE $$IF37 + cmp byte ptr [si],COLON ;Drive letter entered? +; $if e ;AN000;K + JNE $$IF38 + inc si ;Yes, point past the colon + lodsb ;And get next character +; $endif ;AN000;K +$$IF38: +; $endif ;AN000;K +$$IF37: +; $endif ;AN000;K +$$IF36: +; $endif ;AN000;K +$$IF35: +Drive_Letter_Ret: + ret +Check_For_Drive_Letter ENDP + + HEADER +;***************************************************************************** +; Move the input string into buffer, checking for bad characters +;***************************************************************************** +; Input: SI = pointer to next character +; DI = pointer to buffer +; AL = current character in string +; Output: PROGRAM_FLAG = CHAR_BAD if invalid char in string (Flag set in +; called Character_Check routine) +; Notes: Insert a "." in string to seperate 8th and 9th characters so +; ASCIIZ string is the result. + + PUBLIC PROCESS_STRING +Process_String PROC NEAR + cmp al,CR ;is it an ENTER ? +; $if e + JNE $$IF43 + test Program_Flag,USER_INPUT ;has user been told to provide input? +; $if nz ;If user has been prompted for input + JZ $$IF44 + cmp cx,ZERO ;And he said - nothing +; $if e + JNE $$IF45 + jmp Process_String_Return ;AN001; ENTER is acceptable +; $endif +$$IF45: +; $endif +$$IF44: +; $else ;Since got other than just ENTER + JMP SHORT $$EN43 +$$IF43: + test Program_Flag,FOUND_DBCS ;AN000;K If prev char not 1st of DBCS pair + jz Do_More_Check ;AN000;K then go check it out + and Program_Flag,not FOUND_DBCS ;AN000; Reset flag, found its partner + cmp cx,11 ;AC003; Continue to check chars but don't + jge Scan_Continue ;AC003; store anything more + jmp short Got_Ok_Character ;AN000; Partner is ok +Do_More_Check: + call Chk_DBCS ;AN000;D Check DBCS env + jnc Check_Char ;AN000;D If carry, it's a DBCS char + cmp cx,10 ;AC003; If previous char was the 10th + jge Scan_Continue ;AC003; then there is no room for 11th DBCS + call Chk_DBCS_Blank ;AN000;D Is it a DBCS blank? + jmp Got_Ok_Character ;AN000;D +Check_Char: + call Character_Check ;Is it a valid char ? + test Program_Flag,CHAR_BAD + jnz Process_String_Return ;Flag was set, char was invalid + cmp cx,11 ;AN003; Continue to check chars but don't + jge Scan_Continue ;AN003; store anything more +Got_Ok_Character: + stosb ;Good char, store it +Scan_Continue: ;AN003; Skip storing chars since past limit + inc cx ;Inc character count + cmp cx,DOT_LOCATION ;Do we need "." for extension? + jne Get_Next_Char ;No + mov al,PERIOD ;Get a "." for extension + stosb ;And save it +Get_Next_Char: + lodsb ;Get next character + cmp cx,MAX_INPUT ;AN002; Have we reached end? + jne Process_String ;No, go diddle with it +; $endif +$$EN43: +Process_String_Return: + ret +Process_String ENDP + + HEADER +;***************************************************************************** +; See if a character is valid for filename [Character_Check] +;***************************************************************************** +; Input: AL = character to be checked +; Output: AL = character +; PROGRAM_FLAG = CHAR_BAD if invalid characters found + + PUBLIC CHARACTER_CHECK +Character_Check PROC NEAR + or Program_Flag,CHAR_BAD ;Assume bad character + cmp al,"*" + je Char_Check_Done + cmp al,"?" + je Char_Check_Done + cmp al,"[" + je Char_Check_Done + cmp al,"]" + je Char_Check_Done + cmp al,":" + je Char_Check_Done + cmp al,"<" + je Char_Check_Done + cmp al,"|" + je Char_Check_Done + cmp al,">" + je Char_Check_Done + cmp al,"+" + je Char_Check_Done + cmp al,"=" + je Char_Check_Done + cmp al,";" + je Char_Check_Done + cmp al,"," + je Char_Check_Done + cmp al,"/" + je Char_Check_Done + cmp al,"\" + je Char_Check_Done + cmp al,'.' + je Char_Check_Done + cmp al,'"' + je Char_Check_Done + cmp al," " + jb Char_Check_Done + and Program_Flag,not CHAR_BAD ;Char is ok +Char_Check_Done: + ret +Character_Check ENDP + + HEADER +;***************************************************************************** +; Print the old volume label +;***************************************************************************** +; Input: PROGRAM_FLAG = LABEL_FND if there is a label +; Output: None +; Notes: Print the volume label + + PUBLIC OUTPUT_OLD_LABEL +Output_Old_Label PROC NEAR + mov ax,HAS_LABEL_MSG ;Assume label + call Setup_HasLabel ;AN000;M + test Program_Flag,LABEL_FND ;Is there one? +; $if z ;AN000;K If no label found, then + JNZ $$IF50 + mov ax,NO_LABEL_MSG ;No, other message + call Setup_NoLabel ;AN000;M +; $endif ;AN000;K +$$IF50: + call Display_Msg ;AC000;M Set up msg and display + call Get_Serial_Num ;AN000;S Since LABEL_FND, ck for SN +; $if nc ;AN000;K SN must be known + JC $$IF52 + mov ax,SERIAL_NUM_MSG ;AN000;S Prepare for SN message + call Setup_SerialNum ;AN000;M + call Display_Msg ;AC000;M Set up msg and display +; $endif ;AN000;K +$$IF52: + ret +Output_Old_Label ENDP + + HEADER +;***************************************************************************** +; Get the volume serial number +;***************************************************************************** +; Input: FCB_Drive +; Output: SerNum if no carry +; Notes: Only DOS Version 4.0 and above will contain serial numbers + + PUBLIC GET_SERIAL_NUM +Get_Serial_Num PROC NEAR ;AN000;S + mov ax,GET_MEDIA_ID ;AN000;S + mov bh,0 ;AN000;S + mov bl,FCB_Drive ;AN000;S Which drive to check + lea dx,SerNumBuf ;AN000;S Pt to the buffer + INT 21H ;AN000;S Make the call + ret ;AN000;S +Get_Serial_Num ENDP ;AN000;S + + HEADER +;***************************************************************************** +; Input from user a new volume label string +;***************************************************************************** +; Input: PROGRAM_FLAG = CHAR_BAD if there were invalid characters in string +; Output: New string placed in PARM_AREA +; Notes: Print bad character message if needed and prompt and get user input + + PUBLIC GET_USER_INPUT +Get_User_Input PROC NEAR + test Program_Flag,CHAR_BAD ;Do we need bad char message +; $if nz ;AN000;K + JZ $$IF54 + mov ax,INV_CHAR_MSG ;Yes + call Setup_InvChar ;AN000;M + call Display_Msg ;AC000;M Set up msg and display + and Program_Flag,not CHAR_BAD ;Char is ok +; $endif ;AN000;K +$$IF54: + mov ax,NEW_LABEL_MSG ;Tell user to input new label + call Setup_NewLabel ;AN000;M + call Display_Msg ;AC000;M Set up msg and display + mov dx,offset Parm_Area ;Point where to put new name + mov cx,MAX_INPUT ;Number of characters to read + mov bx,STDIN ;Read from keyboard + mov ah,READ ;(3FH) + INT 21H + or Program_Flag,USER_INPUT ;Indicate user input has been received + ret +Get_User_Input ENDP + + HEADER +;***************************************************************************** +; Check to see if old label should be deleted +;***************************************************************************** +; Input: PROGRAM_FLAG = LABEL_FND if there is a label +; Output: PROGRAM_FLAG = NO_DELETE if label should not be deleted +; Notes: Get user Y/N if to delete previous label + + PUBLIC CHECK_DELETE +Check_Delete PROC NEAR + test Program_Flag,LABEL_FND ;AN001; Is there a vol label + jz Check_Delete_Return ;AN001; No, no need for prompt + cmp New_Vol_Name,END_OF_STRING ;AN001; Did user enter label + jne Check_Delete_Return ;AN001; Yes, no need for prompt +Delete_Prompt: ;AN001; + mov ax,DEL_LABEL_MSG ;AN001; Point at Y/N prompt + call Setup_DelLabel ;AN001;M Prepare message + call Display_Msg ;AN001;M Call to Sysdispmsg + mov dx,ax ;AN001; Char ret'd, prep for ck + mov ax,YN_CHECK ;AN001; GetExtCtry,Y/NCheck + INT 21H ;AN001; + cmp ax,YES ;AN001; Delete label ? + je Check_Delete_Return ;AN001; Yes + cmp ax,NO ;AN001; Delete label ? + je Delete_Label ;AN001; Yes + jne Delete_Prompt ;AN001; No, try again +Delete_Label: ;AN001; + or Program_Flag,NO_DELETE ;AN001; Yes, set flag +Check_Delete_Return: ;AN001; + mov ax,CRLF_MSG ;AN001; Point at CRLF message + call Setup_CRLF ;AN001;M Prepare message + call Display_Msg ;AN001;M Call to Sysdispmsg + ret ;AN001; +Check_Delete ENDP + + HEADER +;***************************************************************************** +; Delete old volume label +;***************************************************************************** +; Input: VOL_FCB has name of label if one found +; PROGRAM_FLAG = NO_DELETE if label doesn't need to be deleted +; Output: Vol label deleted if it exists and user say's it is okay +; Notes: Ask user if old label should be deleted. + + PUBLIC DELETE_OLD_LABEL +Delete_Old_Label PROC NEAR + test Program_Flag,NO_DELETE ;Need to delete label ? +; $if z ;AN000;K + JNZ $$IF56 + lea dx,Del_FCB ;Point at FCB to delete vol + mov ah,FCB_DELETE ;(13H) label and delete it + INT 21H ;Can't use handle cause Chmod won't find it +; $endif ;AN000;K +$$IF56: + ret +Delete_Old_Label ENDP + + HEADER +;***************************************************************************** +; Create new volume label file if user specified one +;***************************************************************************** + + PUBLIC CREATE_NEW_LABEL +Create_New_Label PROC NEAR + cmp New_Vol_Name,END_OF_STRING ;Did user enter a vol label +; $if ne ;AN000;K + JE $$IF58 + mov dx,offset New_Vol_Path ;Point at path for file + mov cx,VOL_ATTRIBUTE ;Set it as a volume label + mov ah,CREATE_FILE ;(5BH) Go make it + INT 21H +; $if nc ;AN000;K + JC $$IF59 + mov bx,ax ;shift file handle + mov ah,CLOSE ;And close the file + INT 21H +; $else ;AN000;K since there was creation error, + JMP SHORT $$EN59 +$$IF59: + cmp ax,TOO_MANY_FILES ;Is it +; $if ne ;AN000;K if not "too many files", then + JE $$IF61 + mov ax,NO_ROOM_MSG ;AN000;M + call Setup_NoRoom ;AN000;M + call Display_Msg ;AN000;M + test Program_Flag,LABEL_FND ;AN000;K was an old label found? +; $if ne ;AN000;K if there was an old one, + JE $$IF62 + ;need to restore the previous label + ;because the new one did not stick + mov si,offset Label_Name ;AN000;K where old name was kept + mov di,offset New_Vol_Name ;AN000;K where to put old name + mov cx,8 ;AN000;K count of filename up to "." + rep movsb ;AN000;K + inc di ;AN000;K skip the "." + mov cx,3 ;AN000;K length of extension + rep movsb ;AN000;K + mov dx,offset New_Vol_Path ;AN000;K drive\path\filename + mov cx,VOL_ATTRIBUTE ;AN000;K make it a label + mov ah,CREATE_FILE ;AN000;K make a label + INT 21H ;AN000;K at least, try to, anyway... +; $endif ;AN000;K old label? +$$IF62: +; $else ;AN000;K since is "too many files", then... + JMP SHORT $$EN61 +$$IF61: + mov ax,TOO_MANY_MSG ;AN000;M + call Setup_TooMany ;AN000;M + call Display_Msg ;AN000;M +; $endif ;AN000;K +$$EN61: + jmp Error_Exit ;Tell user bad news and quit +; $endif ;AN000;K +$$EN59: +; $endif ;AN000;K +$$IF58: + ret +Create_New_Label ENDP + + HEADER +;***************************************************************************** +; Preload utility messages +;***************************************************************************** +; Input: None +; Output: None +; Notes: Checks DOS version, if incorrect, or if error loading messages, will +; display error message and terminate + + PUBLIC PRELOAD_MESSAGES +Preload_Messages PROC NEAR ;AN000;M + push ax ;AN000;M + push bp ;AN000;M + mov bp,sp ;AN000;M + push di ;AN000;M + push si ;AN000;M + call SYSLOADMSG ;AN000;M Load msgs & chk DOS ver +; $if c ;AN000;K + JNC $$IF68 + call SYSDISPMSG ;AN000;M + pop si ;AN000;M + pop di ;AN000;M + mov sp,bp ;AN000;M + pop bp ;AN000;M + pop ax ;AN000;M + call Error_Exit ;AN000;M +; $endif ;AN000;K +$$IF68: + pop si ;AN000;M + pop di ;AN000;M + mov sp,bp ;AN000;M + pop bp ;AN000;M + pop ax ;AN000;M + ret ;AN000;M +Preload_Messages ENDP ;AN000;M + + HEADER +;***************************************************************************** +; Display utility messages +;***************************************************************************** +; Input: dx contains the messsage to display +; Output: None +; Notes: The message called is displayed to stdout/stderr unless AX returns +; with error code (then setup for extended error to display) + + PUBLIC DISPLAY_MSG +Display_Msg PROC NEAR ;AN000;M + push bp ;AN000;M + mov bp,sp ;AN000;M + push di ;AN000;M + push si ;AN000;M + call SYSDISPMSG ;AN000;M Now display the message +; $if c ;AN000;K if there was a problem, then... + JNC $$IF70 + mov bx,STDERR ;AN000;M Error msg, so stderr + mov cx,0 ;AN000;M Substitution count + mov dl,NO_INPUT ;AN000;M No input characters + mov dh,EXT_ERR_CLASS ;AN000;M DOS Extended error class + call SYSDISPMSG ;AN000;M Now display the extended error + pop si ;AN000;M + pop di ;AN000;M + mov sp,bp ;AN000;M + pop bp ;AN000;M + call Error_Exit ;AN000;M Nothing we can do so leave +; $endif ;AN000;K +$$IF70: +; Done: ;AN000;M + pop si ;AN000;M + pop di ;AN000;M + mov sp,bp ;AN000;M + pop bp ;AN000;M + ret ;AN000;M Bye,bye +Display_Msg ENDP ;AN000;M + + HEADER +;***************************************************************************** +; Setup for utility messages +;***************************************************************************** +; Input: None +; Output: None + + PUBLIC SETUP_TOOMANY +Setup_TooMany PROC NEAR ;AN000;M + mov ax,4 ;AN000;M Utility's message number + mov bx,STDERR ;AN000;M Error msg, so stderr + mov cx,0 ;AN000;M Substitution count + mov dl,NO_INPUT ;AN000;M No input characters + mov dh,EXT_ERR_CLASS ;AN000;M DOS Extended error class + ret ;AN000;M Now display the message +Setup_TooMany ENDP ;AN000;M + + HEADER +;***************************************************************************** +; Setup for utility messages +;***************************************************************************** +; Input: None +; Output: None + + PUBLIC SETUP_NOROOM +Setup_NoRoom PROC NEAR ;AN000;M + mov ax,82 ;AN000;M Utility's message number + mov bx,STDERR ;AN000;M Error msg, so stderr + mov cx,0 ;AN000;M Substitution count + mov dl,NO_INPUT ;AN000;M No input characters + mov dh,EXT_ERR_CLASS ;AN000;M DOS Extended error class + ret ;AN000;M +Setup_NoRoom ENDP + + HEADER +;***************************************************************************** +; Setup for utility messages +;***************************************************************************** +; Input: None +; Output: None + + PUBLIC SETUP_INVCHAR +Setup_InvChar PROC NEAR ;AN000;M + mov ax,3 ;AN000;M Utility's message number + mov bx,STDERR ;AN000;M Error msg, so stderr + mov cx,0 ;AN000;M Substitution count + mov dl,NO_INPUT ;AN000;M No input characters + mov dh,UTILITY_MSG_CLASS ;AN000;M Utility message class + ret ;AN000;M +Setup_InvChar ENDP ;AN000;M + + HEADER +;***************************************************************************** +; Setup for utility messages +;***************************************************************************** +; Input: None +; Output: None + + PUBLIC SETUP_NEWLABEL +Setup_NewLabel PROC NEAR ;AN000;M + mov ax,6 ;AN000;M Utility's message number + mov bx,STDOUT ;AN000;M Info msg, so stdout + mov cx,0 ;AN000;M Substitution count + mov dl,NO_INPUT ;AN000;M No input characters + mov dh,UTILITY_MSG_CLASS ;AN000;M Utility message class + ret ;AN000;M +Setup_NewLabel ENDP ;AN000;M + + HEADER +;***************************************************************************** +; Setup for utility messages +;***************************************************************************** +; Input: None +; Output: None + + PUBLIC SETUP_INVDRIVE +Setup_InvDrive PROC NEAR ;AN000;M + mov s1_offset,offset FCB_Drive_Char ;AN000;M + mov s1_segment,ds ;AN000;M Setup segment + mov s1_flags,CHAR_FIELD_CHAR ;AN000;M Set up the parm formatting + mov s1_maxwidth,MAXWIDTH ;AN000;M 0 ensures no padding + mov s1_minwidth,MINWIDTH ;AN000;M At least 1 char to insert + mov s1_padchar,BLANK ;AN000;M In case, pad with blanks + mov ax,15 ;AN000;M Utility's message number + mov bx,STDERR ;AN000;M Error msg, so stderr + lea si,sublist1 ;AN000;M Display invalid drive + mov cx,0 ;AN000;M Substitution count + mov dl,NO_INPUT ;AN000;M No input characters + mov dh,EXT_ERR_CLASS ;AN000;M DOS Extended error class + ret ;AN000;M +Setup_InvDrive ENDP ;AN000;M + + HEADER +;***************************************************************************** +; Setup for utility messages +;***************************************************************************** +; Input: None +; Output: None + + PUBLIC SETUP_NETDRIVE +Setup_NetDrive PROC NEAR ;AN000;M + mov s1_offset,offset Label_Word ;AN000;M Cannot LABEL a network... + mov s1_segment,ds ;AN000;M Setup segment + mov s1_flags,STR_INPUT ;AN000;M Set up the parm formatting + mov s1_maxwidth,MAXWIDTH ;AN000;M 0 ensures no padding + mov s1_minwidth,MINWIDTH ;AN000;M At least 1 char to insert + mov s1_padchar,BLANK ;AN000;M In case, pad with blanks + mov ax,8 ;AN000;M Utility's message number + mov bx,STDERR ;AN000;M Error msg, so stderr + lea si,sublist1 ;AN000;M Display network drive msg + mov cx,1 ;AN000;M Substitution count + mov dl,NO_INPUT ;AN000;M No input characters + mov dh,UTILITY_MSG_CLASS ;AN000;M Utility message class + ret ;AN000;M +Setup_NetDrive ENDP ;AN000;M + + HEADER +;***************************************************************************** +; Setup for utility messages +;***************************************************************************** +; Input: None +; Output: None + + PUBLIC SETUP_SUBSTASGN +Setup_SubstAsgn PROC NEAR ;AN000;M + mov s1_offset,offset Label_Word ;AN000;M Cannot LABEL a SUBSTed... + mov s1_segment,ds ;AN000;M Setup segment + mov s1_flags,STR_INPUT ;AN000;M Set up the parm formatting + mov s1_maxwidth,MAXWIDTH ;AN000;M 0 ensures no padding + mov s1_minwidth,MINWIDTH ;AN000;M At least 1 char to insert + mov s1_padchar,BLANK ;AN000;M In case, pad with blanks + mov ax,2 ;AN000;M Utility's message number + mov bx,STDERR ;AN000;M Error msg, so stderr + lea si,sublist1 ;AN000;M Display SUBST/ASSIGN drive ,dh + mov cx,1 ;AN000;M Substitution count + mov dl,NO_INPUT ;AN000;M No input characters + mov dh,UTILITY_MSG_CLASS ;AN000;M Utility message class + ret ;AN000;M +Setup_SubstAsgn ENDP ;AN000;M + + HEADER +;***************************************************************************** +; Setup for utility messages +;***************************************************************************** +; Input: None +; Output: None + + PUBLIC SETUP_NOLABEL +Setup_NoLabel PROC NEAR ;AN000;M + mov s1_offset,offset FCB_Drive_Char ;AN000;M + mov s1_segment,ds ;AN000;M Setup segment + mov s1_flags,CHAR_FIELD_CHAR ;AN000;M Set up the parm formatting + mov s1_maxwidth,MAXWIDTH ;AN000;M 0 ensures no padding + mov s1_minwidth,MINWIDTH ;AN000;M At least 1 char to insert + mov s1_padchar,BLANK ;AN000;M In case, pad with blanks + mov ax,4 ;AN000;M Utility's message number + mov bx,STDOUT ;AN000;M Info msg, so stdout + lea si,sublist1 ;AN000;M Display drive + mov cx,1 ;AN000;M Substitution count + mov dl,NO_INPUT ;AN000;M No input characters + mov dh,UTILITY_MSG_CLASS ;AN000;M Utility message class + ret ;AN000;M +Setup_NoLabel ENDP ;AN000;M + + HEADER +;***************************************************************************** +; Setup for utility messages +;***************************************************************************** +; Input: None +; Output: None + + PUBLIC SETUP_SERIALNUM +Setup_SerialNum PROC NEAR ;AN000;M + mov s1_offset,offset SerNum+2 ;AN000;M + mov s1_segment,ds ;AN000;M Setup segment + mov s1_flags,BIN_HEX_WORD+RIGHT_ALIGN ;AN000;M Set up the parm formatting + mov s1_maxwidth,DWORD ;AN000;M 0 ensures no padding + mov s1_minwidth,DWORD ;AN000;M At least 1 char to insert + mov s1_padchar,CHAR_ZERO ;AN000;M In case, pad with ZERO CHAR + mov s2_offset,offset SerNum ;AN000;M + mov s2_segment,ds ;AN000;M Setup segment + mov s2_flags,BIN_HEX_WORD+RIGHT_ALIGN ;AN000;M Set up the parm formatting + mov s2_maxwidth,DWORD ;AN000;M 0 ensures no padding + mov s2_minwidth,DWORD ;AN000;M At least 1 char to insert + mov s2_padchar,CHAR_ZERO ;AN000;M In case, pad with ZERO CHAR + mov ax,7 ;AN000;M Utility's message number + mov bx,STDOUT ;AN000;M Info msg, so stdout + lea si,sublist1 ;AN000;M Display serial number + mov cx,2 ;AN000;M Substitution count + mov dl,NO_INPUT ;AN000;M No input characters + mov dh,UTILITY_MSG_CLASS ;AN000;M Utility message class + ret ;AN000;M +Setup_SerialNum ENDP ;AN000;M + + HEADER +;***************************************************************************** +; Setup for utility messages +;***************************************************************************** +; Input: None +; Output: None + + PUBLIC SETUP_HASLABEL +Setup_HasLabel PROC NEAR ;AN000;M + mov s1_offset,offset FCB_Drive_Char ;AN000;M + mov s1_segment,ds ;AN000;M Setup segment + mov s1_flags,CHAR_FIELD_CHAR ;AN000;M Set up the parm formatting + mov s1_maxwidth,MAXWIDTH ;AN000;M 0 ensures no padding + mov s1_minwidth,MINWIDTH ;AN000;M At least 1 char to insert + mov s1_padchar,BLANK ;AN000;M In case, pad with blanks + mov s2_offset,offset Label_Name ;AN000;M + mov s2_segment,ds ;AN000;M Setup segment + mov s2_flags,STR_INPUT ;AN000;M Set up the parm formatting + mov s2_maxwidth,MAXWIDTH ;AN000;M 0 ensures no padding + mov s2_minwidth,MINWIDTH ;AN000;M At least 1 char to insert + mov s2_padchar,BLANK ;AN000;M In case, pad with blanks + mov ax,5 ;AN000;M Utility's message number + mov bx,STDOUT ;AN000;M Info msg, so stdout + lea si,sublist1 ;AN000;M Display drive then label + mov cx,2 ;AN000;M Substitution count + mov dl,NO_INPUT ;AN000;M No input characters + mov dh,UTILITY_MSG_CLASS ;AN000;M Utility message class + ret ;AN000;M +Setup_HasLabel ENDP ;AN000;M + + HEADER +;***************************************************************************** +; Setup for utility messages +;***************************************************************************** +; Input: None +; Output: None + + PUBLIC SETUP_DELLABEL +Setup_DelLabel PROC NEAR ;AN001;M + mov ax,9 ;AN001;M Utility's message number + mov bx,STDOUT ;AN001;M Info msg, so stdout + mov cx,0 ;AN001;M Substitution count + mov dl,DOS_CON_INPUT ;AN001;M Input Y/N character + mov dh,UTILITY_MSG_CLASS ;AN001;M Utility message class + ret ;AN001;M +Setup_DelLabel ENDP ;AN001;M + + HEADER +;***************************************************************************** +; Setup for utility messages +;***************************************************************************** +; Input: None +; Output: None + + PUBLIC SETUP_CRLF +Setup_CRLF PROC NEAR ;AN001;M + mov ax,10 ;AN001;M Utility's message number + mov bx,STDOUT ;AN001;M Info msg, so stdout + mov cx,0 ;AN001;M Substitution count + mov dl,NO_INPUT ;AN001;M Input Y/N character + mov dh,UTILITY_MSG_CLASS ;AN001;M No input characters + ret ;AN001;M +Setup_CRLF ENDP ;AN001;M + + HEADER +;***************************************************************************** +; Error on exit +;***************************************************************************** + + PUBLIC ERROR_EXIT +Error_Exit PROC NEAR ;AC000;M + mov ax,(EXIT SHL 8)+ERRORLEVEL_1 ;AN000;K Terminate, with ret code + INT 21H +Error_Exit ENDP ;AN000;M + +End_Of_Program label byte + Public End_Of_Program + +CSEG ends + end Start + \ No newline at end of file -- cgit v1.2.3