Comment | Common included routines for BootSave, BootRest and BootCheck | ; end of comment ;=============================================================== CommandLine proc near ; gets command line into ES:bx with length in cx. ; This version works for a COM file only. xor ch,ch mov cl,ES:80H mov bx,81H ret CommandLine endp ;====================================== GetBoot proc near ; Read first sector, the boot block of hard disk C: mov ah,02 ; function 2 read mov dl,080h ; C:= 080h mov dh,0 ; head 0 mov ch,0 ; cyl 0 mov cl,1 ; sector 1 is first mov al,1 ; just 1 sector lea bx,Buffer ; ES:BX is buffer int 13h jc BootTrouble ret GetBoot endp ;=============================================================== NthParm proc near ; Parses string for Nth Parameter delimited by blanks ; e.g. " A: /Q " with bx=1 would give string "/Q" ; on entry: ; ES:bx - string, usually the command line ; cx - length of string ; dx - which parm wanted 1=parm1 2=parm2 etc. ; NthParm only finds one parm per call. ; On exit ES:bx points to string and cx is its length. ; If there is no parm, the length will be 0. ; It also handles multiple leading/trailing blanks on parms. mov al,20h ; al = blank -- the search char mov di,bx Parmloop: ; Remove leading blanks on parm jcxz NullParm ; jump if null string repe scasb ; scan ES:di forwards till hit non blank ; di points just after it ; cx is one too small, or 0 if none found je NullParm ; jump if entire string was blank inc cx ; cx is length of remainder of string dec di ; di points to non-blank mov si,di ; remember start of string ; Search for terminating blank on parm jcxz NullParm ; jump if null string repne scasb ; scan ES:di forwards till hit blank ; di points just after it ; cx is one too small, or 0 if none found jne NoBlank ; jump if entire string was non blank inc cx ; cx is length of remainder of string dec di ; backup di to point to blank at string end NoBlank: ; di=addr tail end of command string, ; cx=len tail end of command string ; si=addr parm just parsed ; Major loop for each parm dec dx jnz Parmloop ; loop once for each parm mov cx,di sub cx,si ; cx is length of parameter. mov bx,si ret NullParm: ; was no nth parameter mov cx,0 mov bx,si ret NthParm endp ;=============================================================== Parse proc near ; Parse the command line and process each parameter. ; sample inputs ; BootSAVE A:\Boot.SAV /Q ; BootREST C:\SAFE\Boot.SAV ; counted string at HEX 80 PSP ; contains command line. ; Preceeded by unwanted spaces. ; possibly followed by unwanted spaces. ; currently missing a trailing null. ; Both ES and DS cover the command line ; since this is a COM file. ; However to make code compatible with EXE ; files we use ES: to cover the command line. call CommandLine ; string addr ES:bx, length cx. jcxz NullParms mov ParmIndex,1 ; start parsing with the 1st parm ; note start with 1 not 0! ; We don't want the the program name. jmp Short Parseloop NullParms: NoMoreParms: test fileName,-1 ; ensure some sort of filename provided jz BadCmd ; by the time all done mov ax,DS mov ES,ax ; restore ES to match DS, for COM file ret ; we are done Parseloop: call CommandLine ; commmandline=ES:bx, length=cx mov dx,ParmIndex call NthParm ; work left to right jcxz NoMoreParms ; null param means no more ; e.g. ES:bx points to A: or /Q ; cx is length of that piece mov ax,ES:[bx] ; al=A ah=: or al=/ ah=Q call ToUc ; Convert both chars to upper case xchg ah,al call ToUc cmp ah,'/' ; drive or Switch? jne ProcessDrive ; it was a switch with slash ; was it /Q? cmp al,'Q' je ProcessQ ; something else, give up. BadCmd: jmp SyntaxTrouble ProcessDrive: ; don't insist on drive letter. ; should have C:\SAFE\Boot.SAV ; copy string to FileName ; followed by a null mov si,bx lea di,FileName ; ES:si -> DS:di ( segs are backwards ) push ES ; swap ES DS push DS pop ES pop DS rep movsb ; copy filename DS:si -> ES:di mov ES:[di],byte ptr 0 ; append a null push ES ; swap ES DS back to normal push DS pop ES pop DS jmp short Next ProcessQ: ; handle /Quiet mov SlashQuiet,-1 Next: inc ParmIndex ; bump loop counter jmp Parseloop ; loop till hit null param Parse endp ;======================================== Say proc ; on entry DX points to a string to display mov AH,9 int 21h ret Say endp ;=============================================================== SayQ proc ; on entry DX points to a string to display ; Only displays string if /Q not on test SlashQuiet,-1 jnz Quietly call Say Quietly: ret SayQ endp ;============================================================== ToUC proc NEAR ; converts char in AL to upper case cmp al,'a' jb FineAsIs cmp al,'z' ja FineAsIs sub al,20H ; convert a to A FineAsIs: ret ToUc endp ;======================================