.enabl lc .title unx .nlist bex ; ; ; this program, when installed as ...unx, is used to ; unload the LBL communication drivers which have the ; perpetual timer to perform the self-cleansing ; action required for their use. ; ; usage: ; ; unx xx: ; ; where xx: is the device mnemonic. A syntax error occurs if the ; colon(:) is not found. ; ; after retrieving the device mnemonic from the command line, ; a lun is assigned to the device. A qiow is made to the driver ; with the function code IO.STP. If the qiow is successful (the ; requesting terminal must be priveleged), the timer will have been ; stopped. This task then spawns the following three MCR commands ; ; device xx: ; unload xx: ; device xx: ; .mcall gmcr$,dir$,alun$s,glun$s,spwn$s,stse$s,exit$s,qiow$s ; ; local constants ; ttylun=1 ; lun for terminal io devlun=2 ; lun for device 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 ; ; local macros ; .macro concat a,b,c mov #'c,r0 mov #'a,r1 call scopy mov #'b,r1 call scopy .endm concat ; ; ; local impure storage ; ; xx: .blkb 2 ; location for device mnemonic gmcrpb: gmcr$ ; DPB for GMCR$ iosb: .blkb 4 ; io status block for qiow numbuf: .blkb 10. ; buffer for formatted numbers tbuf: .blkb 80. ; temporary buffer for formatted error msgs outbuf: .byte cr,lf ; formatting buffer for error processor obuf: .blkb 132. ; remainder of buffer devstr: .ascii "device " ; device command to spawn devxx: .blkb 2 .ascii ":" devlen=.-devstr .even unlstr: .ascii "unload " ; unload command to spawn unlxx: .blkb 2 .ascii ":" unllen=.-unlstr .even ; ; ; local pure storage ; ; usemsg: .asciz "Usage: unx xx:" lunmsg: .asciz "unx - error assigning lun to device; $dsw = " qiomsg: .asciz "unx - error stopping timer; iosb(1) = " spnmsg: .asciz "unx - error spawning process; $dsw = " .even ; ; task name for spawn invocation ; mcr: .rad50 "MCR..." ; ; ; start of unx code ; ; first assign lun to TI: and get MCR command line ; start: alun$s #ttylun,#"TI,#0 ; assign lun to TI: dir$ #gmcrpb ; get MCR command line mov @#$dsw,r0 ; place number of chars in r0 ble useerr ; if <= 0, error clrb gmcrpb+g.mcrb(r0) ; terminate with 0 byte mov #gmcrpb+g.mcrb,r0 ; starting buffer address 10$: movb (r0)+,r1 ; get next character beq useerr ; if == 0, syntax error cmpb r1,#' ; see if blank bne 10$ ; if != BLANK, try next character movb (r0)+,xx ; copy first character beq useerr ; if == 0, syntax error movb (r0)+,xx+1 ; copy second character beq useerr ; copy second character cmpb (r0)+,#': ; check for colon(:) bne useerr ; if !=, syntax error tstb (r0) ; must be 0 byte beq synok ; if == 0, OK go on useerr: mov #usemsg,r0 ; error to report jmp errmsg ; report it and exit synok: alun$s #devlun,xx,#0 ; assign lun to device mov $dsw,r1 ; get status word bgt devok ; if > 0, ok call numfmt ; format error number concat lunmsg,numbuf,tbuf ; generate error string mov #tbuf,r0 ; message to report jmp errmsg ; display it devok: qiow$s #io.stp,#devlun,#qioefn,,#iosb ; stop timer mov $dsw,r1 ; get directive status ble qioerr ; if <= 0, error movb iosb,r1 ; get io status bgt qiook ; if > 0, continue bis #177400,r1 ; sign extend byte qioerr: call numfmt ; format error number concat qiomsg,numbuf,tbuf ; generate full error message mov #tbuf,r0 ; message to report jmp errmsg ; report it and die qiook: movb xx,devxx ; copy device mnemonic to spawn string movb xx+1,devxx+1 ; movb xx,unlxx ; copy device mnemonic to spawn string movb xx+1,unlxx+1 ; spwn$s #mcr,,,,,#spnefn,,,#devstr,#devlen,#0 ; spawn device xx: mov $dsw,r1 ; get status ble spnerr ; if <= 0, error stse$s #spnefn ; wait for it to complete spwn$s #mcr,,,,,#spnefn,,,#unlstr,#unllen,#0 ; spawn unload xx: mov $dsw,r1 ; get status ble spnerr ; if <= 0, error stse$s #spnefn ; wait for it to complete spwn$s #mcr,,,,,#spnefn,,,#devstr,#devlen,#0 ; spawn device xx: mov $dsw,r1 ; get status ble spnerr ; if <= 0, error stse$s #spnefn ; wait for it to complete br done spnerr: call numfmt ; format error number concat spnmsg,numbuf,tbuf ; generate full error message mov #tbuf,r0 ; message to report jmp errmsg ; report it and die done: exit$s ; ; ; routine to format error code into buffer numbuf ; ; inputs: r1 number to format ; ; outputs: number formatted in number with 0-byte teminator ; r0-r3 are modified ; numfmt: mov #numbuf,r0 ; buffer for error number clr r2 ; no leading zeroes call $cbdsg ; convert to signed decimal clrb (r0) ; terminate with zero byte return ; ; ; routine to calculate the length of the zero byte terminated ; string pointed to by r1. length returned in r0, r1 is left ; unmodified ; ; .enabl lsb 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