⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init.asm

📁 DOS 源代码 系列之 command 源码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
setcomsr:
	push	cx

	push	cs				; Get local segment
	pop	ds				;
	assume	ds:ResGroup			;

	push	ds
	mov	si,offset ResGroup:ComSpect
	mov	cx,14

	mov	al,es:[di-1]

	ifdef	DBCS
	or	ah,ah
	jnz	iNotRoot			; Last char was KANJI second byte, might be '\'
	endif

	cmp	al,RDirChar
	jnz	iNotRoot
	inc	si				; Don't make a double /
	dec	cx

iNotRoot:
	rep	movsb

        mov     dx,ComspOffset                  ; Now lets make sure its good!
	push	es
	pop	ds

	mov	ax,OPEN shl 8
	int	21h				; Open COMMAND.COM
	pop	ds
	jc	SetComsrBad			; No COMMAND.COM here
	mov	bx,ax				; Handle
	mov	ah,CLOSE
	int	21h				; Close COMMAND.COM

SetComsrRet:
	pop	cx
	pop	si
	pop	ds				;
	assume	ds:ResGroup			;

	push	cs				; Make sure local ES is
	pop	es				;  restored
	jmp	Parse_command_line			; continue parsing command line

SetComsrBad:
	mov	dx,offset ResGroup:BadComlkMsg	; dx = ptr to msg

;	Note:  we're about to make a near call to TriageError, which
;	lives in a different segment and group.  Some linkers will
;	generate a warning like "Possible fix-up overflow".  We're
;	ok, though, because we all fit in 64 KB and, at init time,
;	we're still all together.

	call	triageError
	cmp	ax, 65
	jnz	doprt
	mov	dx,offset ResGroup:BadComaccMsg	; dx = ptr to msg
DoPrt:
	call	RPrint
	mov	si,offset ResGroup:ComSpect
        mov     di,ComspOffset
	mov	cx,14
	rep	movsb				; get my default back

	jmp	short SetComsrRet

;*********************************
; Parsing Ends Here
;*********************************

ArgsDone:

	mov	es,EnvirSeg			; get environment back
	assume	es:nothing			;

	cmp	PermCom,0
	jz	ComReturns

	push	es				; Save environment pointer
	mov	ah,SET_CURRENT_PDB
	mov	bx,ds
	mov	es,bx
	int	21h				; current process is me
	mov	di,PDB_EXIT			; Diddle the addresses in my header
	mov	ax,offset DATARES:LodCom_Trap
	stosw
	mov	ax,ds
	stosw
	mov	ax,offset DATARES:Ctrlc_Trap
	stosw
	mov	ax,ds
	stosw
	mov	ax,offset DATARES:CritErr_Trap
	stosw
	mov	ax,ds
	stosw
	mov	word ptr ds:PDB_Parent_Pid,ds 	; Parent is me forever

	mov	dx,offset DATARES:Int2e_Trap
	mov	ax,(SET_INTERRUPT_VECTOR shl 8) or 02eh
	int	21h				;set magic interrupt
	pop	es				;Remember environment

ComReturns:
	mov	ax,word ptr ds:PDB_Parent_Pid
	mov	Parent,ax			; Save parent
	mov	word ptr ds:PDB_Parent_Pid,ds 	; Parent is me
	mov	ax,word ptr ds:PDB_Jfn_Table
	mov	Io_save,ax			; Get the default stdin and out
	mov	word ptr Com_ptr+2,ds		 	; set all these to resident
	mov	word ptr Com_fcb1+2,ds
	mov	word ptr Com_fcb2+2,ds
	mov	di,offset ResGroup:ComSpec

        mov     si,ComspOffset
        cmp     AllocedEnv,0

	mov	ax,ds				; Xchg es,ds
	push	es
	pop	ds
	mov	es,ax

        jne     CopyComsp                       ; All set up for copy

	push	cs
	pop	ds

	mov	si,offset ResGroup:ComspString
	push	es
	push	di
	call	IfindE
	mov	si,di
	push	es
	pop	ds
	pop	di
	pop	es
	jnc	CopyComsp

ComSpecNofnd:
        mov     si,offset ResGroup:ComspString
        add     si,ComspStrLen
	push	cs
	pop	ds

	assume	es:ResGroup

CopyComsp:
	mov	es:PutBackComSpec.SubstPtr,di	; Save ptr to beginning of comspec path
	cmp	byte ptr [si+1],':'             ; Is there a drive specifier in comspec
	jnz	CopyComspLoop			; If not, do not skip over first 2 bytes
	add	es:PutBackComSpec.SubstPtr,2

CopyComspLoop:
	lodsb
	stosb
	or	al,al
	jnz	CopyComspLoop
	mov	es:Comspec_end,di			; Save ptr to end of comspec path
	dec	es:Comspec_end
	mov	ah,es:comdrv
	add	ah,'A'-1
	mov	es:PutBackDrv,ah			; save drive letter


	call	setup_for_messages			; set up parse and extended error messages
;
; The routine below sets up the exact resident size of COMMAND. If this is not
; the first COMMAND, then the resident code is not duplicated and the resident
; size is just the data. If we are the first COMMAND, it checks if we are to
; be loaded into HIMEM. If not, then the resident size includes the code and
; the data otherwise it is just the data.
; 
	call	Setup_res_end			;put resident size in ResSize

	push	cs
	pop	ds
	assume	ds:RESGROUP


Public EnvMaximum
EnvMaximum:

;
; Compute checksum right now before we can get corrupted and save it
;

	mov	si,offset RESGROUP:TranStart
	add	si,100h
	mov	cx,offset TRANGROUP:TranDataEnd - 100H

	cld
	shr	cx,1
	xor	dx,dx
Ichksum:
	lodsw
	add	dx,ax
	adc	dx,0
	loop	Ichksum

        mov     Sum,dx                          ; store checksum

        cmp     byte ptr PrdAttm,0              ;
        jnz     NoBatchSeg                      ; don't do autoexec or date time
;
; Allocate batch segment for d:/autoexec.bat + no arguments
;
	mov	bx,((SIZE BatchSegment) + 15 + 1 + 0fh)/16 ;eg
        mov     ah,ALLOC                        ;
        int     21h                             ;
        jc      NoBatchSeg                      ; didn't allocate - pretend no batch
        mov     Batch,ax                        ; save batch segment

nobatchseg:
        mov     bx,EnvirSeg                     ; get old environment segment
        mov     OldEnv,bx                       ; save it

        mov     UsedEnv,0                       ; initialize env size counter
	mov	ds,bx
	assume	ds:nothing

	xor	si,si
	mov	di,si
;
; This is the maximum allowed size for the environment
;
	mov	bx,4096 - 1 			; max. allowed env. size
	mov	EnvMax,bx
				 
	shl	bx,1
	shl	bx,1
	shl	bx,1
	shl	bx,1
	mov	EnvMax, bx			; convert envmax to bytes
	dec	bx				; dec by one to leave room for double 0
	xor	dx,dx				; use dx to indicate that there was
						; no environment size error.
public NxtStr
NxtStr:
	call	GetStrLen			; get the size of the current env string

;Bugbug: Can use ss here to address UsedEnv

        push    ds                              ; get addressability to environment
        push    cs                              ;                       counter
        pop     ds                              ;
        assume  ds:ResGroup
        add     UsedEnv,cx                      ; add the string length to env size
        pop     ds                              ;
	assume	ds:nothing
	cmp	cx,1				; end of environment was encountered.
	jz	EnvExit
	sub	bx,cx
	jae	OkCpyStr			; can't fit in all of enviroment.
	inc	dx				; out of env space msg must be displayed
	jmp	short EnvExit
OkCpyStr:
	jmp	NxtStr
EnvExit:

	push	cs
	pop	ds
	assume	ds:ResGroup
	or	dx,dx				; dx will be non-zero if error
	jz	EnvNoErr
	mov	dx,offset ResGroup:OutEnvMsg	; dx = ptr to msg
	call 	RPrint

EnvNoErr:
	mov	ax,EnvSiz			;env size previously set
	mov	cl,4
	shl	ax,cl				;get size in bytes
	cmp	ax,UsedEnv			;is it a new env?
	ja	st_envsize			;yes, store the size

	mov	ax,UsedEnv
	add	ax,15				;round up
st_envsize:	
	shr	ax,cl
	mov	EnvSiz,ax			;store env size needed(paras)

if MSVER
	cmp	SingleCom,0
	jnz	nophead 			; don't print header if singlecom
	mov	dx,offset ResGroup:CopyrightMsg	; dx = ptr to msg
	call	RPrint
nophead:
endif

	cmp	Batch,0			;eg did we set up a batch segment?
	jnz	DoDate				;eg yes - go initialize it
	jmp	NoDttm				; don't do autoexec or date time
;
; allocate batch segment for d:/autoexec.bat + no arguments
;
DoDate:
	mov	ax,Batch			;eg get batch segment
	mov	EchoFlag,3			; set batch echo
	mov	Nest,1				; g set nest flag to 1 batch
	mov	es,ax
;
; initialize the segment
;
	xor	di,di
	mov	al,BATCHTYPE
	stosb
	mov	al,1				; g initialize echo for batch exit
	stosb					; g
;
; Hosebag! This guy does not use the struct fields to init the BatchSegment
;
	xor	ax,ax				; initialize to zero
	stosb					; clear out BatchEOF

	stosw					; g batch segment of last job - batlast
	stosw					; g segment for for
	stosb					; g for flag
	stosw					; position in file - batseek
	stosw
;
; clean out the parameters
;
	mov	ax,-1				; initialize to no parameters
	mov	cx,10
	rep	stosw
;
; decide whether we should grab the default drive
;
	cmp	byte ptr AutoBat,0
	jnz	NoAutSet
	mov	ah,GET_DEFAULT_DRIVE
	int	21h
	add	al,Ucasea

	mov	AutoBat,al
	mov	KautoBat,al			; 3/3/kk

NoAutSet:
;
; copy in the batch file name (including nul)
;
	mov	si,offset ResGroup:AutoBat
	mov	cx,8
	rep	movsw
	movsb					; move in carriage return to terminate string

ifdef ROMDOS

; Check to see if the Boot Options indicate that startup processing
; should be omitted.  If so, skip the open, and pretend that there is
; no autoexec.bat.

	push	es			; save current ES
	mov	ax,BDATA
	mov	es,ax
	assume	es:BDATA
	mov	ax,es:BootFlags		; get boot options from BIOS
	pop	es			; restore previous ES
	assume	es:RESGROUP
	test	al,BF_NoConfig		; flag set to supress processing?
	jnz	NOABAT			; if so, skip autoexec processing

endif ; ROMDOS

	mov	dx,offset ResGroup:AutoBat
	mov	ax,OPEN shl 8
	int	21h				; see if autoexec.bat exists
	jc	NoAbat
	mov	bx,ax
	mov	ah,CLOSE
	int	21h
	jmp	Drv0				; go process autoexec

noabat:
	push	ax
	call	Setup_Seg
	mov	word ptr Triage_Add+2,ax
	pop	ax
	call	Triage_Add
	cmp	ax, 65
	jz	AccDenErr			; was network access denied


; If AUTOEXEC.BAT is not found, then check for KAUTOEXE.BAT.  Changed
; by Ellen to check only when in Korea.  The country information
; returned will overlay the old parse data area, but we don't care
; since we won't need the parse information or country information.
; We only care about the country code returned in BX.

	mov	dx,offset ResGroup:Internat_Info ; set up internat vars
	mov	ax,INTERNATIONAL shl 8		; get country dependent info
	int	21h				;
	jc	NoKabat 			; error - don't bother with it
	cmp	bx,KOREA_COUNTRY_CODE			; are we speaking korean?
	jnz	OpenErr 			; no, don't check for kautoexe

	mov	di,BatFile			; 3/3/kk
	mov	si,offset ResGroup:KautoBat	; another trial to do	3/3/kk
	mov	cx,8				; auto execution for the 3/3/kk
	rep	movsw				; non-english country	3/3/kk
	movsb					; move in carraige return to terminate string
	mov	dx,offset ResGroup:KautoBat	; 3/3/kk
	mov	ax,OPEN shl 8			; 3/3/kk
	int	21h				; see if kautoexe.bat exists    3/3/kk
	jc	NoKabat 			; 3/3/kk
	mov	bx,ax				; 3/3/kk
	mov	ah,CLOSE			; 3/3/kk
	int	21h				; 3/3/kk
	jmp	short Drv0			; 3/3/kk

NoKabat:						; 3/3/kk
	call	Triage_Add			; get extended error
	cmp	ax, 65				; network access denied?
	jnz	OpenErr 			; no - go deallocate batch

AccDenErr:					; yes - put out message
	mov	dx,offset ResGroup:AccDen		; dx = ptr to msg
	call	RPrint

OpenErr:
	mov	es,Batch			; not found--turn off batch job
	mov	ah,DEALLOC
	int	21h
	mov	Batch,0			; after dealloc in case of ^c
	mov	EchoFlag,1
	mov	Nest,0				;g indicate no batch in progress

DoDttm:
	mov	ax,offset TranGroup:Datinit
	mov	word ptr InitAdd,ax
;;;M004	mov	ax,TrnSeg	
;
; M004; We cant use TrnSeg now because it is not initialized. We now that
; M004; the transient starts on a para boundary at the label TranStart.
; M004; We use TranStart to get the start of the transient segment.
;
	mov	ax,offset RESGROUP:TranStart	; M004
	mov	cl,4				; M004
	shr	ax,cl				; get relative seg ; M004
	mov	cx,cs
	add	ax,cx				; ax = transient seg ; M004

	mov	word ptr InitAdd+2,ax
	call	dword ptr InitAdd

NoDttm:

Copyright:
	public	Copyright
;	Bugbug:	remove Copyright label.

if IBMVER
	cmp	SingleCom,0
	jnz	Drv0				; don't print header if singlecom
	mov	dx,offset ResGroup:CopyrightMsg	; dx = ptr to msg
	call	RPrint
endif

Drv0:						; Reset APPEND state
	push	ds				; save data segment
	push	cs				; Get local segment into DS
	pop	ds				;
	mov	ax,APPENDSETSTATE			; Set the state of Append
	mov	bx,Append_State 			;  back to the original state
	int	2fh				;
	pop	ds				; get data segment back
;
;Check FirstCom set previously to see if this is the first instance of
;command.com. If not, we do not move command.com. Instead, we copy over the
;jump table from the previous stub to the current stub.
;
	cmp	FirstCom,1			;first command.com?
	jz	move_code			;yes, move it

	push	es
	push	ds

	push	ds
	pop	es

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -