title COMSPEC - Patch comspec parameter for hard/electronic disk.
page 64,132
comment |
	/////////////////////////////////////////////////////////////////////
	/  A Patch to DOS 2.0 to allow resetting of the COMSPEC parameter.  /
	/COMSPEC4.ASM							     /
	/  Page 10-23 of the DOS 2.0 manual clearly states the the COMSPEC  /
	/  parameter is used to locate the command processor (COMMAND.COM)  /
	/  when it needs to be reloaded.  Although the SET command may be   /
	/  used to respecify the path, DOS does not seem to recognize it.   /
	/								    /
	/  This program if included in the AUTOEXEC.BAT file at boot time   /
	/  along with a SET command will cause DOS to reload COMMAND.COM    /
	/  from wherever you wish.  My AUTOEXEC.BAT file looks like this:   /
	/								    /
	/	    ECHO ** AUTOEXEC.BAT **				    /
	/	    COMSPEC C:\DOS20\COMMAND.COM			DMO /
	/	    IF ERRORLEVEL 1 GOTO CSBAD				DMO /
	/	    SET COMSPEC=C:\DOS20\COMMAND.COM			    /
	/	    GOTO CSCONT 					DMO /
	/	 :CSBAD 						    /
	/	    ECHO COMSPEC ERROR					    /
	/	 :CSCONT						DMO /
	/								    /
	/  I have a TallGrass hard disk which is configured as drives C-F.  /
	/  There is a sub-directory called \DOS20 with most of the DOS 2.0  /
	/  commands and most importantly a copy of COMMAND.COM.  This idea  /
	/  will also work from an electronic disk.  Just remember to copy   /
	/  COMMAND.COM to the electronic disk in your AUTOEXEC.BAT file.    /
	/								    /
	/	       Ted Reuss    Houston, Tx    August 1983		    /
	/////////////////////////////////////////////////////////////////////

	/ Fixed by Daniel M. O'Brien (21 August 1983). Problem was this
	/ program only searched the first 64k segment to find the COMSPEC
	/ string. With systems running DOS 2.0 VDISK (ramdisk) the COMSPEC
	/ string is located higher in memory. Fix was to loop thru all segments
	/ from 0 up to the segment containing this program.
	/ In addition, the new COMSPEC string was changed to reflect the
	/ use of VDISK as disk C:
	/ Finally, I want to thank Ted Reuss who developed the concepts
	/ and the original program as I have been battling this problem for
	/ about two months and it is now solved.
	/
	/ Daniel M. O'Brien (29 August 1983). Specify where COMMAND.COM
	/ is to come from via command line parameter. Avoids having to
	/ patch or assemble correct values into place.
	|
cseg	segment public 'code'
	assume	cs:cseg,ds:cseg
	org	100h			;use EXE2BIN to make .com
start	proc	far
	jmp	initial

oprm	db	'a:\COMMAND.COM',0      ;original comspec parameter
;note that the lower case 'a' is required so we don't match this
; string since it will be in a low memory disk buffer.
oprm_l	equ	$-offset oprm

nprm	db	'C:\COMMAND.COM',0 ;user supplied parameter                  DMO
nprm_l	equ	$-offset nprm
	db	14 dup(0)	;reserve space for patches
nprm_len	dw	0	;length of user suppled parameter	     DMO

initial:
	mov	ax,nprm_l	;get default length			     DMO
	mov	nprm_len,ax	;initialize default length field	     DMO

	cld			;clear direction flag			     DMO
	xor	ax,ax		;clear ah,al				     DMO
	mov	si,80h		;point to input parm area		     DMO
	lods	byte [si]	;get byte count 			     DMO
	or	al,al		;any input?				     DMO
	jz	no$input	;no-use default 			     DMO

	mov	cx,ax		;get user input length			     DMO
trim_blank:			;					     DMO
	mov	al,[si] 	;get next byte				     DMO
	cmp	al,' '          ;leading blank?                              DMO
	jne	blank_done	;no-then done				     DMO
	inc	si		;skip leading blank			     DMO
	loop	trim_blank	;loop					     DMO

blank_done:			;					     DMO

	mov	ax,cx		;save length for update 		     DMO
	mov	di,offset nprm	;point to path variable 		     DMO
	rep	movs [di],[si]	;fill in our copy of value		     DMO
	mov	byte ptr [di],0 ;don't forget to include trailing zero       DMO
	inc	ax		;bump length by one for trailing zero	     DMO
	mov	nprm_len,ax	;fill in length of user supplied path	     DMO

no$input:			;					     DMO

	xor	ax,ax
	mov	es,ax		;Scan for original comspec string
	mov	di,ax		; begins at 0000:0000.
bigloop:			;					     DMO
	mov	cx,0ffffh	;search entire segment			     DMO
	cld			;set auto-increment
again:	mov	si,offset oprm+1  ;point to target string
	mov	al,byte ptr[si-1] ;and fetch first character.
	and	al,11011111B	;force to upper case
	repnz	scasb		;loop while not equal
	jnz	err
	mov	dx,cx		;save counter
	mov	cx,oprm_l-1	;get string length-1
	repz	cmpsb		;loop while equal
	je	match		;strings match?
	mov	cx,dx		;nope,
	jmp	short again	; go look again...

match:	mov	cx,nprm_len	;get length of new comspec
	mov	si,offset nprm	;point to new comspec
	sub	di,oprm_l	;back-up to begin of old one
	rep	movsb		;store new comspec
	mov	al,0		;set ERRORLEVEL = 0
	jmp	short exit

err:
	mov	ax,es		;get current search segment		     DMO
	add	ax,1000h	;increment to next segment		     DMO
	mov	cx,ax		;save for update			     DMO
	mov	ax,cs		;get our code segment			     DMO
	cmp	cx,ax		;did we reach our code segment yet?	     DMO
	mov	es,cx		;..in case we did			     DMO
	mov	di,0		;..beginning of segment 		     DMO
	jb	bigloop 	;no-continue looking			     DMO

	mov	al,1		;set ERRORLEVEL = 1
exit:	mov	ah,4CH		;DOS exit function
	int	21H		;return to DOS

start	endp
cseg	ends
	end	start
