📄 init.asm
字号:
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 + -