Files
Digital-Research-Source-Code/MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/02/COMMAND.SUP
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

599 lines
13 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;*****************************************************
;*
;* Command Line Interpreter, Program Chain
;*
;*****************************************************
;===========
chain_entry:
;===========
sub dx,dx
;============
clicmd_entry:
;============
; Create a process based on an Ascii Command Line.
; The command Line is first parsed and an FCB is
; initialized as a result.
; An attempt is made to open a queue with the filename
; of the FCB. If this succeeds, The default console
; is assigned to a process by the same name.
; The commandtail is then written to the queue and
; the we exit (even if assign fails).
; If there is a failure, We make the type name in the
; FCB to be 'CMD' and open the file. If this fails,
; so do we.
; We then obtain a Process Descriptor from the
; PD table. Again we fail if it does.
; On a successful open, we call the BDOS load function.
; If the load fails, so do we. The PD is
; initialized, the default console is assigned to the
; PD and a create process call is made.
;
; input: DX -> command buffer in u_wrkseg
; It is assumed that the calling process
; is attached to its default console
; and is willing to lose it since it
; will be handed to the newly created
; process.
; if DX = 0, assume chain w/command in DMA
;
; output: BX = 0 if successful
; = 0ffffh if failure has occured
; CX = error code
push dx ! call mxread ! pop dx
mov bx,rlr ! mov ax,p_flag[bx]
mov cli_pflag,ax
and ax,not pf_keep ! or ax,pf_tempkeep
mov p_flag[bx],ax
; we have MXcli queue.
; Check for Chain
mov cli_chain,false
cmp dx,0 ! jne cli_cli
mov cli_chain,true
mov cli_term,false
cli_cli:
; initialize defaults from parent PD
mov cli_dfil,false
cmp dayfile,0ffh ! jne nodf
push dx ! mov cx,f_cconattch
call mpmif ! pop dx
cmp cx,0 ! jne nodf
mov cli_dfil,true
push dx
call prtime
pop dx
nodf: mov bx,rlr
mov cli_ppd,bx
mov cl,p_dsk[bx]
mov cli_dsk,cl
mov cl,p_user[bx]
mov cli_user,cl
mov cl,p_cns[bx]
mov cli_cns,cl
mov cl,u_error_mode
mov cli_err_mode,cl
mov cx,u_dma_ofst
mov cli_dma_ofst,cx
mov cx,u_dma_seg
mov cli_dma_seg,cx
mov clierr,0
; copy command into local area
cmp cli_chain,true ! jne cli_copy
push es ! push ds
mov es,sysdat
mov si,cli_dma_ofst
mov di,offset cli_cmdtail
mov ds,cli_dma_seg
mov cx,040H
rep movsw
pop ds ! pop es
jmp cli_parse
cli_copy:
push es ! push ds
mov ds,u_wrkseg ! pop es
; DS=Wrkseg, ES=Sysdat, SP->UDA
; copy clicb_net
mov si,dx ! mov di,offset cli_net
movsb
; copy command
mov si,dx ! add si,clicb_cmd
mov di,offset cli_cmdtail
mov cx,clicblen-clicb_cmd
rep movsb
push es ! pop ds ! pop es
;parse the command
cli_parse:
call pfn ! jcxz cli_goodparse
mov clierr,cx
jmp cli_exit
cli_goodparse:
call shifttail
;fcb has parsed filename
;if not explicit disk then
; if not RSP try CMD
;else try CMD
cmp cli_fcb,0 ! jne cli_ffload
mov bx,(offset cli_fcb)
cmp fcb_plen[bx],0 ! jne cli_ffload
call cli_checkque ! jnz cli_ffload
;successful RSP access
cli_qful:
cmp cli_chain,true ! jne cli_exit2
mov cli_term,true
cli_exit2: jmp cli_exit
cli_ffload:
cmp cx,e_q_full ! jne cli_fload
mov clierr,cx ! jmps cli_qful
cli_checkque:
;------------
; output: z flag on if successful
;copy fcb.name to qpb.name
mov si,(offset cli_fcb)+fcb_name
mov di,(offset cli_cuspqpb)+qpb_name
mov cx,qnamsiz/2 ! push es ! push ds ! pop es
push si ! rep movsw
;copy fcb.name to acb.name
pop si ! mov cx,qnamsiz/2
mov di,(offset cli_acb)+acb_name
rep movsw ! pop es
;open queue
mov cx,f_qopen ! mov dx,(offset cli_cuspqpb)
call mpmif ! jcxz cli_goodq
retcli1: cmp cx,0 ! ret
;we successfully opened the queue
;check for process by assign console
cli_goodq:
mov bx,offset cli_cuspqpb
mov bx,qpb_qaddr[bx]
test q_flags[bx],qf_rsp ! jnz cli_gq
mov cx,e_no_queue ! jmps retcli1
;write command tail to queue
cli_gq: mov cx,f_cqwrite ! mov dx,offset cli_cuspqpb
call mpmif ! jcxz cli_qw
mov cx,e_q_full ! jmps retcli1
;successful queue write, assign console
cli_qw: cmp cli_dfil,true ! jne noqm
call prcusp
noqm: mov bx,offset cli_acb
mov al,cli_cns ! mov acb_cns[bx],al
mov acb_match[bx],false
mov acb_pd[bx],0
call conasn ! sub cx,cx ! ret
cli_fload:
;---------
; Try to Load a file for execution
; The Command Line Parsed correctly and we have an FCB
; set up. We already know there isn't a queue and a
; process by the same name as the command.
; Obtain a Process Descriptor
pushf ! cli ! mov bx,pul
cmp bx,0 ! jne cli_gpd
popf ! mov clierr,e_no_pd
jmp cli_exit
cli_gpd:
mov si,p_link[bx] ! mov pul,si
popf ! mov cli_pd,bx
; zero PD
push es ! push ds ! pop es
mov di,bx ! mov cx,pdlen/2
sub ax,ax ! rep stosw
pop es
; Initialize the PD for Load
mov al,cli_fcb
mov cli_lddsk,al
mov bx,cli_pd
mov p_flag[bx],pf_table
mov di,bx ! add di,p_name
mov si,offset cli_fcb ! add si,fcb_name
push es ! mov ax,ds ! mov es,ax
mov cx,pnamsiz/2 ! rep movsw
pop es
mov si,rlr
mov al,cli_dsk ! mov p_dsk[bx],al
mov al,cli_user ! mov p_user[bx],al
mov al,cli_cns ! mov p_cns[bx],al
mov al,p_lst[si] ! sub al,ncondev
mov p_lst[bx],al
; 3. Open the file
mov si,(offset cli_fcb)+fcb_dskmap
mov di,offset cli_dma
push es ! mov es,sysdat
mov cx,4 ! rep movsw
pop es
mov u_dma_ofst,offset cli_dma
mov u_dma_seg,ds
mov si,offset cli_fcb
mov byte ptr fcb_type[si],'C'
mov byte ptr fcb_type+1[si],'M'
mov byte ptr fcb_type+2[si],'D'
; Open the CMD file
mov u_error_mode,0feh
call fileopen
cmp bl,0ffh ! jne cli_gopen
; on failure,
; if default is not system disk
; and not an explicit disk then
; try CMD file on System disk
cmp bh,0 ! jne cli_bopen ;extended error
mov cl,srchdisk
cmp cl,cli_dsk ! je cli_bopen
cmp cli_fcb,0 ! jne cli_bopen
; try system disk
mov bx,rlr
mov p_dsk[bx],cl
call fileopen
cmp bl,0ffh ! je cli_bopen
;make sure SYS attribute is on...
mov bx,offset cli_fcb
test byte ptr fcb_type+1[bx],080h ! jnz cli_gopen
;We opened a NON-SYS file. Do explicit open
;on user zero if not already
call fileclose
mov bx,rlr
cmp p_user[bx],0 ! je cli_bopene
mov p_user[bx],0
call fileopen
cmp bl,0ffh ! je cli_bopen
mov bx,offset cli_fcb
test byte ptr fcb_type+1[bx],080h
jnz cli_gopen
call fileclose
jmps cli_bopene
;could not find CMD file
cli_bopen: cmp bh,0 ! jne cli_rmpd2
cli_bopene: mov clierr,e_bad_open
cli_rmpd2: jmp cli_rmpd
cli_gopen:
; 8. Call the load function
mov bx,rlr
test p_flag[bx],pf_ctlc ! jz cli_ld1
mov bx,0ffffh ! mov cx,e_abort
jmp cli_cl
cli_ld1:
cmp cli_chain,true ! jne cli_kuda
mov bx,cli_pd
mov p_uda[bx],es
mov ax,offset inituda
mov cl,4 ! shr ax,cl
add ax,sysdat
mov bx,es ! mov es,ax ! mov di,0
mov ds,bx ! mov si,di
mov cx,ulen/2
rep movsw
pushf ! cli ! pop dx
mov ax,es
mov ds,sysdat
mov ss,ax
mov bx,rlr
mov p_uda[bx],ax
push dx ! popf
cli_kuda:
cmp cli_dfil,true ! jne noprfil
call prfilnam
noprfil:mov bx,cli_pd
mov dx,offset cli_fcb
mov cx,f_load
cmp cli_chain,true ! jne cli_ld
mov cli_term,true
mov cx,f_cload
cli_ld: call mpmif
cli_cl: push bx ! push cx
mov u_error_mode,0
call fileclose
pop cx ! pop bx
jcxz cli_gload
cmp cx,e_abort ! jne cli_lnab
jmp cli_rmpd
cli_lnab: mov clierr,cx
jmp cli_rmpd
cli_gload:
mov cli_bpage,bx
; 9a. Parse Command Tail
; copy cmdtail to user DMA buffer
push es ! mov es,cli_bpage
mov di,offset bpg_dma+1
mov si,offset cli_cmdtail
mov cx,127
rep movsb ! pop es
; count cmd length and convert
; to upper case
push ds ! mov ds,cli_bpage
mov cl,0 ! mov di,offset bpg_dma+1
ncmdchar:
cmp byte ptr [di],0 ! je endtail
cmp byte ptr [di],'a' ! jb nlow
cmp byte ptr [di],'z' ! ja nlow
and byte ptr [di],05fh
nlow: inc di ! inc cl ! jmps ncmdchar
endtail:
mov bpg_dma,cl ! pop ds
; init default fcb
push es ! mov es,cli_bpage
mov al,cli_lddsk
mov es:bpg_lddsk,al
mov di,offset bpg_fcb0
sub ax,ax ! stosb ;default disk
mov al,' '
mov cx,11 ! rep stosb ;name,type
sub ax,ax
mov cx,2 ! rep stosw ;other
push ds ! push es ! pop ds
mov si,offset bpg_fcb0
mov cx,8 ! rep movsw
pop ds ! pop es
; init load disk
; if cmdtail, parse
cmp cli_cmdtail,0 ! je cmdtaildone
call pfn
cmp bx,0ffffh ! je cmdtaildone
; copy fcb to user fcb front
push es ! mov es,cli_bpage
mov di,offset bpg_fcb0
mov si,offset cli_fcb
mov ax,fcb_pptr[si]
mov es:bpg_pw1ptr,ax
mov al,fcb_plen[si]
mov es:bpg_pw1len,al
mov cx,8 ! rep movsw ! pop es
; if more cmdtail, parse
cmp bx,0 ! je cmdtaildone
push cli_pcb ! inc bx
mov cli_pcb,bx
call pfn
pop cli_pcb
cmp bx,0ffffh ! je cmdtaildone
; copy 2nd fcb front
push es ! mov es,cli_bpage
mov di,offset bpg_fcb1
mov si,offset cli_fcb
mov ax,fcb_pptr[si]
mov es:bpg_pw2ptr,ax
mov al,fcb_plen[si]
mov es:bpg_pw2len,al
mov cx,8
rep movsw
pop es
cmdtaildone:
; 10. Create the process
cmp cli_chain,true ! jne noprior
mov cx,f_setprior
mov dx,1 ! call mpmif
noprior:
mov dx,cli_pd ! mov cx,f_createproc
call mpmif
; 11. Assign Console to new process
cmp cli_dfil,true ! jne nocrlf
call crlf
nocrlf: mov bx,offset cli_acb
mov al,cli_cns ! mov acb_cns[bx],al
mov ax,cli_pd ! mov acb_pd[bx],ax
mov acb_match[bx],true
call conasn
mov clierr,cx ! jmps cli_exit
; 12. All Done
cli_rmpd: ; release PD
pushf ! cli
mov bx,pul ! mov si,cli_pd
mov p_link[si],bx ! mov pul,si
popf
; Normal EXIT
cli_exit: ; close file and release MXCli queue
mov bx,rlr
mov cl,cli_dsk ! mov p_dsk[bx],cl
mov cl,cli_user ! mov p_user[bx],cl
mov cl,cli_err_mode ! mov u_error_mode,cl
mov cx,cli_dma_ofst ! mov u_dma_ofst,cx
mov cx,cli_dma_seg ! mov u_dma_seg,cx
cmp cli_chain,true ! jne clirls
cmp cli_term,true ! jne clirls
mov bx,rlr
and p_flag[bx],not (pf_keep+pf_sys+pf_tempkeep+pf_ctlc)
mov cx,f_terminate
jmp mpmif
clirls:
push cli_pflag
call mxwrite
pop ax ! and ax,pf_tempkeep+pf_keep
mov bx,rlr ! mov cx,p_flag[bx]
and cx,not pf_tempkeep+pf_keep
or cx,ax ! mov p_flag[bx],cx
test p_flag[bx],pf_ctlc ! jz cli_nctl
mov cx,f_terminate ! sub dx,dx
call mpmif
mov cli_err,e_abort
; setup error return if needed
cli_nctl:
mov cx,clierr ! sub bx,bx
jcxz cli_gexit
mov bx,0ffffh
cli_gexit:
ret
shifttail:
;---------
; setup command tail to be parsed
; input: AX = output of previous parsefilename
cmp ax,0 ! je cli_notail
;shift command tail to beginning
;of command buffer
push ax ! sub ax,offset cli_cmdtail
mov cx,128 ! sub cx,ax ! shr cx,1
pop si ! mov di,offset cli_cmdtail
push es ! push ds ! pop es
rep movsw ! pop es
ret
cli_notail:
mov cli_cmdtail,0
ret
crlf: mov dl,13 ! call prchar
mov dl,10
;jmps prchar
prchar: mov cx,f_conout ! jmp mpmif
prtime: mov dl,tod_hr ! call prnum
mov dl,':' ! call prchar
mov dl,tod_min ! call prnum
mov dl,':' ! call prchar
mov dl,tod_sec ! call prnum
mov dl,' ' ! jmps prchar
prnum: push dx ! mov cl,4
shr dl,cl ! add dl,'0'
call prchar
pop dx ! and dl,0fh
add dl,'0' ! jmps prchar
prfilnam:
call prdisk
mov dx,(offset cli_fcb)+fcb_name
call prnam
mov dl,'.' ! call prchar
mov dx,(offset cli_fcb) + fcb_type
call prtyp
mov dl,' ' ! call prchar
mov bx,offset cli_fcb
test byte ptr fcb_name+7[bx],080h ! jnz pruser
cmp cli_user,0 ! je pret
mov bx,rlr
cmp p_user[bx],0 ! je pruser
pret: ret
pruser: mov dx,offset userstr
jmps prcsm
prdisk: mov dl,cli_fcb
cmp dl,0 ! je prpddsk
dec dl ! jmps prdsk1
prpddsk:
mov bx,rlr
mov dl,p_dsk[bx]
prdsk1: add dl,'A' ! call prchar
mov dl,':' ! jmp prchar
prcusp: mov dx,(offset cli_cuspqpb) + qpb_name
call prnam ! mov dx,offset questr
call prcsm ! jmp crlf
prcsm: sub bx,bx ! push ds
mov ax,cs ! mov ds,ax
call cprnt ! pop ds ! ret
prtyp: mov bh,3 ! jmps prn1
prnam: mov bh,8
prn1: mov bl,' '
cprnt: mov cx,f_conprint ! jmps jmpm
fileclose:
mov cx,f_fclose ! mov dx,offset cli_fcb
jmps fo1
fileopen:
mov cx,f_fopen
mov si,offset cli_fcb
or byte ptr fcb_name+5[si],080h ;f6`=open read-only
mov dx,si
fo1: push es ! call mpmif ! pop es ! ret
mxwrite:mov cx,f_qwrite
jmps mxw1
mxread: mov cx,f_qread
mxw1: mov dx,offset mxcliqpb
jmpm: jmp mpmif
pfn: mov dx,offset cli_pcb ! mov cx,f_parsefilename
jmps jmpm
conasn: mov cx,f_conassign ! mov dx,offset cli_acb
jmps jmpm
questr db ' Msg Qued',0
userstr db '(User 0)',0
;=========
user_retf:
;=========
; If a user does a RETF expecting to go to CCP,
; The process ends here
mov bx,rlr
and p_flag[bx],not pf_keep+pf_tempkeep+pf_ctlc+pf_sys
mov cx,f_terminate ! sub dx,dx ! int mpmint