#-h- shl.tkb 47 asc 20-jun-80 11:43:08 shl.tsk;1/cp/-fp,shl.map;1/ma=shl / units=2 // #-h- shl.mac 6398 asc 20-aug-80 14:55:27 .title shl ; ; ; this program, when installed as ...shl, is used to ; get into the software tools shell. shl takes the ; arguements given to it and forwards them to the shell, ; which has been invoked with the task name of .SHTnn, ; thus allowing the kill feature to work correctly. ; This program has been rewritten in assembler due to ; large memory requirements of its predecessor. ; ; .mcall fdbdf$,fdat$a,fdop$a,fsrsz$,nmblk$,finit$,ofnb$,close$ .mcall put$ .mcall gmcr$,dir$,alun$s,glun$s,spwn$s,stse$s,exit$s,qiow$s ; ; local constants ; fillun=1 ; lun for file manipulation ttylun=2 ; lun for terminal io qioefn=1 ; event flag for qios spnefn=2 ; event flag for spawn blank=40 ; ASCII code for blank cr=15 ; ASCII code for carriage return lf=12 ; ASCII code for line feed esc=33 ; ASCII code for escape star=52 ; ASCII code for * ; ; ; local impure storage ; ; putsba: .blkw 1 ; address of buffer for puts putsbc: .blkw 1 ; number of characters to put lunbuf: .blkw 6 ; buffer for GLUN$ octnum: .blkb 4 ; 6 byte buffer for $cbomg unit: .blkb 2 ; these 2 bytes will have the unit # shtska: .blkw 1 ; address of sh.tsk file name gmcrdp: gmcr$ ; DPB for GMCR$ outbuf: .byte cr,lf ; formatting buffer for error processor obuf: .blkb 132. ; remainder of buffer fdb: fdbdf$ ; FDB for file activity fdat$a r.var,fd.cr ; variable length records, list cctrl fdop$a fillun tnam: nmblk$ ,ARG,,ST,0 ; default name block for arg file fsrsz$ 1 ; generate FCS buffer area for 1 file ; ; ; local pure storage ; ; locerr: .asciz "Error locating shell image file." argerr: .asciz "Cannot create argument file for sh." puterr: .asciz "Cannot write arguments to file." spnerr: .asciz "Error spawning sh.tsk." insst: .asciz "INS " ; these 3 stings will be concatenated tasst: .asciz "/TASK=." ; to form the command line for MCR to runst: .asciz "/RUN=REM" ; spawn the shell ; ; file specs follow ; usr: udev: .ascii "ST0:" udevl=.-udev udir: .ascii "[105,2]" udirl=.-udir ufil: .ascii "SH.TSK" ufill=.-ufil .byte 0 bin: bdev: .ascii "ST0:" bdevl=.-bdev bdir: .ascii "[105,1]" bdirl=.-bdir bfil: .ascii "SH.TSK" bfill=.-bfil .byte 0 tmp: tdir: .ascii "[105,3]" tdirl=.-tdir tfil: .ascii "SH" devc: .blkb 1 ; will have the device character (T) tnum: .blkb 2 tfill=.-tfil .byte 0 .even ; ; task name for spawn invocation ; mcr: .rad50 "MCR..." ; ; the following are data-set descriptors ; udsc: .word udevl .word udev .word udirl .word udir .word ufill .word ufil bdsc: .word bdevl .word bdev .word bdirl .word bdir .word bfill .word bfil tdsc: .word 0,0 .word tdirl .word tdir .word tfill .word tfil ; ; ; start of shl code ; ; first initialize FCS and get MCR command line ; start: finit$ ; initialize FCS dir$ #gmcrdp ; get MCR command line mov $dsw,r0 ; place number of chars in r0 bgt 5$ ; successfully got cmd line movb #star,gmcrdp+g.mcrb ; copy dummy task name into buffer mov #1,r0 ; new count in r0 5$: mov #gmcrdp+g.mcrb,r1 ; buffer address in r1 mov r1,putsba ; save address for put$ mov r0,putsbc ; save count for put$ ; ; ; now we must generate the task name for the shell - .SHTnn ; ; alun$s #ttylun,#"TI,#0 ; assign lun to terminal glun$s #ttylun,#lunbuf ; get lun info mov #octnum,r0 ; string to format into movb lunbuf+g.lunu,r1 ; value to format mov #1,r2 ; desire leading zeroes call $cbomg ; convert to octal magnitude movb lunbuf+g.luna,devc ; overwrite devc with ch movb unit,tnum ; copy first number of unit movb unit+1,tnum+1 ; copy second number of unit ; ; the following lines of code attempt to locate sh.tsk in ; first the usr directory, then the bin directory ; tryusr: mov #fdb,r0 ; FDB address in r0 mov #fdb+f.fnb,r1 ; FNB address in r1 mov #udsc,r2 ; usr file desc in r2 clr r3 ; no default FNB call .parse ; parse into FNB in r1 bcs trybin ; c set => directory doesn't exist call .find ; find file in directory bcs trybin ; c set => not found mov #usr,r0 ; file spec addr in r0 jmp gotshl trybin: mov #bdsc,r2 ; bin data-set descriptor in r2 clr r3 ; no default FNB call .parse ; parse for directory info bcs notfnd ; c set => no directory call .find ; find file in directory bcs notfnd ; c set => file does not exist mov #bin,r0 ; file spec addr in r0 jmp gotshl notfnd: mov #locerr,r0 jmp errmsg ; ; we found the shell, now try to open the argument file and place ; the arguments in it ; gotshl: mov r0,shtska ; save sh.tsk addr for later mov #fdb,r0 ; parse file spec mov #fdb+f.fnb,r1 mov #tdsc,r2 mov #tnam,r3 call .parse bcs erropn ofnb$ r0,#fo.wrt ; open the file bcs erropn put$ r0,putsba,putsbc ; write the record bcs errput close$ r0 ; close the file jmp spwnit errput: close$ r0 mov #puterr,r0 jmp errmsg erropn: mov #argerr,r0 jmp errmsg ; ; having been successful to this point, we will now generate the ; mcr command line to spawn the shell, and spawn it ; spwnit: mov #gmcrdp+g.mcrb,r0 ; need to concatenate the parts mov #insst,r1 ; of the command line together call scopy mov shtska,r1 call scopy mov #tasst,r1 call scopy mov #tfil,r1 call scopy mov #runst,r1 call scopy movb #esc,(r0)+ ; place ESCAPE at end of command line clrb (r0) mov #gmcrdp+g.mcrb,r1 call length spwn$s #mcr,,,,,#spnefn,,,r1,r0,#0 ; spawn sh tst $dsw bgt wait mov #spnerr,r0 jmp errmsg wait: stse$s #spnefn ; wait for completion done: exit$s ; ; ; routine to calculate the length of the zero byte terminated ; string pointed to by r1. length returned in r0, r1 is left ; unmodified ; ; length: clr r0 ; initialize count mov r1,-(sp) ; save r1 1$: tstb (r1)+ ; see if 0 byte beq 2$ ; yes, done inc r0 br 1$ 2$: mov (sp)+,r1 ; restore r1 return ; ; ; routine to copy 0-byte terminated string pointed to by r1 ; to string pointed to by r0. r1 is left pointing to character ; after z byte, and r0 points to next available location ; scopy: movb (r1)+,(r0)+ ; copy byte bne scopy ; try again tstb -(r0) ; backup one byte return ; ; ; routine to display error message on terminal. address of ; zero byte terminated message is passed in r0 ; ; errmsg: mov r0,r1 ; going to scopy into buffer mov #obuf,r0 ; destination call scopy ; copy string mov #outbuf,r1 ; calculate length call length ; length in r0 qiow$s #io.wlb,#ttylun,#qioefn,,,, br done ; exit .end start