.TITLE MCRCMD - ISSUE MCR COMMAND .SBTTL MCRCMD - TITLE PAGE .IDENT /V01.00/ .ENABL LC ; ; Issue command to MCR. ; ; Version: V01.00 ; ; Author: R.W. Stamerjohn ; ; Modification history: ; ; V01.00 RWS 14-Oct-1984 Initial version .SBTTL MCRCMD - DECLARATIONS .DSABL GBL .DSABL CRF ; ; Macro library calls: ; ; Directives. ; .MCALL DIR$ ;Issue directive .MCALL EXIT$S ;Exit command .MCALL QIOW$S ;Issue I/O and wait .MCALL ALTP$ ;Alter priority .MCALL CNCT$ ;Connect to task .MCALL SPWN$ ;Spawn task .MCALL RPOI$ ;Chain task .MCALL STSE$ ;Stop on event flag ; ; TPARS macros ; .MCALL ISTAT$ ;Define initial state .MCALL STATE$ ;Declare parsing state .MCALL TRAN$ ;Declare transaction ; ; Global declarations: ; .GLOBL MCRCMD ;Entry point ; ; Global references: ; ; CCS routines. ; .GLOBL CCSERR ;Declare CCS error ; ; System routines. ; .GLOBL $CAT5 ;Convert ASCII to RAD50 .GLOBL $SRSTD ;Search STD for task .GLOBL $TKTCB ;Current task TCB (us) .GLOBL .TPARS ;Command parser ; ; CCS data. ; .GLOBL CCSFLG ;Command processing flags .GLOBL CMDMAX ;Maximum command line .GLOBL XITSTS ;Task exit status .GLOBL OBUF ;Output command buffer .GLOBL OBUFB ;Current position in buffer ; ; .TPARS variables. ; .GLOBL .PSTCN ;Length of parsed string .GLOBL .PSTPT ;Address of parsed string ; ; CCS symbols. ; .GLOBL TLUN ;Terminal lun .GLOBL TEFN ;Terminal event flag .GLOBL SEFN ;Stop event flag .GLOBL CS.WAI ;Current command is wait task .GLOBL CS.MOR ;Current command is execute/continue .GLOBL CS.LST ;Current command is execute/last .GLOBL CS.DBG ;Current command has debug flag (%D) .GLOBL CS.PRT ;Current command has print flag (%P) .GLOBL CS.QUT ;Current command has quit flag (%Q) .GLOBL CS.NUL ;Current command has null flag (%N) .GLOBL CS.XIT ;Current command has exit flag (%$) .GLOBL CS.NON ;Required parameter not found ; ; Other symbols. ; .GLOBL EX$SUC ;Success return .GLOBL IO.WVB ;Write message .GLOBL T3.REM ;Remove task on exit .GLOBL T3.MCR ;MCR prompt control .GLOBL T.ST3 ;Task status word 3 .ENABL CRF .SBTTL MCRCMD - LOCAL DECLARATIONS ; ; Local macros: ; .MACRO SYSTEM ADDR EMT 376 .WORD ADDR .ENDM SYSTEM ; ; Local symbols: ; ; None. ; ; Local data: ; ; Define parsing variables. ; FINSB: .WORD 0 ;Start of install FINSL: .WORD 0 ;Length of install FCMDB: .WORD 0 ;Start of command FCMDL: .WORD 0 ;End of command FTSKN: .BLKW 2 ;Task name ; ; Define various directives. ; PRIH: ALTP$ ,250. ;Raise to 250 PRIL: ALTP$ ;Lower to default CNCT: CNCT$ XXXXXX,SEFN,,XITSTS ;Chain to task SPWN: SPWN$ MCR...,,,,,SEFN,,XITSTS,,,, ;Spawn MCR STSK: SPWN$ XXXXXX,,,,,SEFN,,XITSTS,,, ;Spawn task RPOI: RPOI$ MCR...,,,,,,,,RP.OEX!RP.ONX,,,, ;Chain MCR RTSK: RPOI$ XXXXXX,,,,,,,,RP.ONX,,,, ;Chain task STOP: STSE$ SEFN ; ; Error messages. ; .NLIST BEX ERSPWN: .ASCIZ /CCS - Spawn of MCR failed/ ERSTSK: .ASCIZ /CCS - Spawn of task failed/ ERRPOI: .ASCIZ /CCS - Chain of MCR failed/ ERRTSK: .ASCIZ /CCS - Chain of task failed/ ERLCMD: .ASCIZ /CCS - Resulting command line too long/ .EVEN .LIST BEX .SBTTL MCRCMD - PARSING TABLES ISTAT$ MCRTBL,MCRKTB STATE$ ST.01 ;Parse out "INS" TRAN$ "INS",,PRBEGI STATE$ ST.02 ;Parse until "/" TRAN$ <'/>,ST.03 TRAN$ $ANY,ST.02 STATE$ ST.03 ;Check for "/TASK" or "/CMD" TRAN$ "TASK",ST.04 TRAN$ "CMD" ,ST.06 TRAN$ $LAMDA,ST.02 STATE$ ST.04 ;Check for "/TASK=" TRAN$ <'=> STATE$ ST.05 ;Parse out task name TRAN$ $RAD50,ST.02,PRTASK STATE$ ST.06 ;Check for "/CMD=" TRAN$ <'=>,,PRENDI STATE$ ST.07 ;Parse lead quote TRAN$ <'">,,PRBEGC STATE$ ST.08 ;Parse trailing quote TRAN$ <'">,ST.09,PRENDC TRAN$ $ANY,ST.08 STATE$ ST.09 ;Parse EOL TRAN$ $EOS,$EXIT STATE$ .SBTTL MCRCMD * ISSUE COMMAND ; ;+ ; This routine processes the constructed command. It handles the ; print, debug, wait, and execute options. It also will handle flying ; installs that have command lines which are too long. If the command ; is the last in a sequence, a RPOI will be used to pass any OCB's. ; ; Call by: JSR PC,MCRCMD ; ; OBUF has constructed command, OBUFB points to next free ; position in buffer. ; ; Exit with: CC = More commands to process ; CS = No more commands ;- MCRCMD:: ;Ref. label ; ; Process %Q and %N. If %Q was seen and required parameter missing, do not ; spawn command. If %N was seen and all required parameters present, do not ; spawn command. ; BIT #CS.QUT,CCSFLG ;Did command have a %Q BEQ 1000$ ; If EQ - no, skip BIT #CS.NON,CCSFLG ;Is required parameter missing BNE 9000$ ; If NE - yes, do not process 1000$: BIT #CS.NUL,CCSFLG ;Did command have a %N BEQ 2000$ ; If EQ - no, skip BIT #CS.NON,CCSFLG ;Is required parameter missing BEQ 9000$ ; If EQ - no, do not process ; ; Get output buffer address in R4, next free byte in R5 and length of ; generated command in R3. ; 2000$: MOV #OBUF,R4 ;Get output buffer MOV OBUFB,R5 ;Get current command end MOV R5,R3 ;Copy current command length SUB R4,R3 ;Get length of command ; ; Check for debug and print command (%D or %P) and output to terminal. ; BIT #CS.PRT!CS.DBG,CCSFLG ;Did command have %D or %P BEQ 3000$ ; If EQ - no, continue QIOW$S #IO.WVB,#TLUN,#TEFN,,,, BR 9000$ ; ; Check for wait command (-). If found, convert first six characters in OBUF ; to RAD50 taskname and use to connect and wait on that task. ; 3000$: BIT #CS.WAI,CCSFLG ;Is this wait command (-taskname)? BEQ 4000$ ; If EQ - no, skip CALL WAITSK ;Wait for task to complete BR 9000$ ; and exit ; ; Check if execute (more) command. If so, spawn command to MCR and wait ; for task to complete. ; 4000$: BIT #CS.MOR,CCSFLG ;Is this execute (more) command BEQ 5000$ ; If EQ - no, continue BIT #CS.XIT,CCSFLG ;Is the immediate exit flag set BNE 5000$ ; If NE - yes, use chain instead CALL WAIMCR ;Spawn command and wait BR 9000$ ; and exit ; ; Must be execute (last) command. Chain command to MCR and exit. ; 5000$: CALL CHNMCR ;Chain command and exit ; ; Check if we should exit processing or not. ; 9000$: CMP #EX$SUC,XITSTS ;Did task's return some type of error BLE 9100$ ; If LE - no, skip BIS #CS.LST,CCSFLG ;Flag we should exit 9100$: BIT #CS.LST,CCSFLG ;Should we exit processing? SEC ;Preset failure BNE 9999$ ; If NE - yes, exit CLC ;Flag more commands 9999$: RETURN ;Return to caller .SBTTL WAITSK * WAIT FOR TASK ; ;+ ; This routine processes command - or wait for task completion. ; ; Call by: JSR PC,WAITSK ; ; R3 = Length of command buffer ; R4 = Starting address of buffer ; R5 = Last position in buffer ; ; Exit with: Requested task finished execution. ;- WAITSK: MOVB #<'*>,(R5)+ ;Make sure we terminate with non-RAD50. CLR CNCT+C.NCTN+0 ;Clear the task name CLR CNCT+C.NCTN+2 ; ... MOV R4,R0 ;Copy buffer address MOV #1,R1 ;Flag period conversion CALL $CAT5 ;Convert to RAD50 MOV R1,CNCT+C.NCTN+0 ;Store first part of taskname BCS 3100$ ; If CS - no more name MOV #1,R1 ;Flag period conversion CALL $CAT5 ;Convert to RAD50 MOV R1,CNCT+C.NCTN+2 ;Store second part of taskname 3100$: DIR$ #CNCT ;Connect to task BCS 9999$ ; If CS - not active DIR$ #STOP ;Stop until task exits. 9999$: RETURN ;Return to caller .SBTTL WAIMCR * SPAWN COMMAND TO MCR AND WAIT ; ;+ ; This routine processes <+command> type lines. It spawns the generated ; command to MCR and waits for task completion. ; ; Call by: JSR PC,WAIMCR ; ; R3 = Length of command buffer ; R4 = Starting address of buffer ; R5 = Last position in buffer ; ; Exit with: Requested task finished execution. ;- WAIMCR: MOV R4,SPWN+S.PWCA ;Store address of command line MOV R3,SPWN+S.PWCL ;Store length of command line CMP CMDMAX,R3 ;Is command line too long? BLT 1000$ ; If LT - yes, special processing ; ; Command line is OK, use MCR to process the command. ; DIR$ #SPWN ;Spawn the command to MCR BCC 2000$ ; and continue on wait CALL CCSERR ;Declare fatal error .WORD ERSPWN ; *** Spawn of MCR failed *** ; ; Command line is too long. If command line is flying install, try the ; following. Raise priority to 250 and spawn task install. When install ; finishes, spawn task directly and enter system state to mark for remove. ; Then wait on task to finish. ; 1000$: MOV #1,R1 ;Blanks have meaning MOV #MCRKTB,R2 ;Get keyword table MOV #MCRTBL,R5 ;Get starting table CALL .TPARS ;Can we use flying install? BCC 1100$ ; If CC - yes, attempt it CALL CCSERR ;Declare fatal error and exit .WORD ERLCMD ; *** Command line too long *** 1100$: DIR$ #PRIH ;Raise our priority so we get control MOV FINSB,R4 ;Get install command start MOV FINSL,R3 ;Get install command length CALL WAIMCR ;Call ourselves to spawn install MOV FTSKN+0,STSK+S.PWTN+0 ;Set name we should spawn MOV FTSKN+2,STSK+S.PWTN+2 ; ... MOV FCMDB,STSK+S.PWCA ;Store address of command line MOV FCMDL,STSK+S.PWCL ;Store length of command line DIR$ #STSK ;Spawn the task we really want BCC 1200$ ; If CC - continue CALL CCSERR ;Declare fatal error and exit .WORD ERSTSK ; *** Spawn of task failed *** 1200$: SYSTEM 1300$ ;;Enter system state MOV #FTSKN,R3 ;;Get taskname we have installed CALL $SRSTD ;;Find the task BCS 1210$ ;; If CS - not found BIS #T3.REM,T.ST3(R0) ;;Flag for remove on exit 1210$: RETURN ;;Exit system state 1300$: DIR$ #PRIL ;Lower priority back down ; ; Wait for spawned task to exit. ; 2000$: DIR$ #STOP ;Wait until we get done RETURN ;Return to caller .SBTTL CHNMCR * CHAIN COMMAND TO MCR AND EXIT ; ;+ ; This routine processes <*command> type lines. It chains the generated ; command to MCR, passing the OCB's, and exits. This processing uses the ; RPOI directive. ; ; Call by: JSR PC,CHNMCR ; ; R3 = Length of command buffer ; R4 = Starting address of buffer ; R5 = Last position in buffer ; ; Exit with: Command chained. Does not return control. ;- CHNMCR: MOV R4,RPOI+R.POBF ;Store address of command line MOV R3,RPOI+R.POBL ;Store length of command line CMP CMDMAX,R3 ;Is command line too long? BLT 1000$ ; If LT - yes, special processing ; ; Command line is OK, use MCR to process the command. ; DIR$ #RPOI ;Spawn the command to MCR and exit CALL CCSERR ;Declare fatal error .WORD ERRPOI ; *** Chain to MCR failed *** ; ; Command line is too long. If command line is flying install, try the ; following. Raise priority to 250 and spawn task install. When install ; finishes, spawn task directly and enter system state to mark for remove. ; Then wait on task to finish. ; 1000$: MOV #1,R1 ;Blanks have meaning MOV #MCRKTB,R2 ;Get keyword table MOV #MCRTBL,R5 ;Get starting table CALL .TPARS ;Can we use flying install? BCC 1100$ ; If CC - yes, attempt it CALL CCSERR ;Declare fatal error and exit .WORD ERLCMD ; *** Command line too long *** 1100$: DIR$ #PRIH ;Raise our priority so we get control MOV FINSB,R4 ;Get install command start MOV FINSL,R3 ;Get install command length CALL WAIMCR ;Call ourselves to spawn install MOV FTSKN+0,RTSK+R.POTK+0 ;Set name we should spawn MOV FTSKN+2,RTSK+R.POTK+2 ; ... MOV FCMDB,RTSK+R.POBF ;Store address of command line MOV FCMDL,RTSK+R.POBL ;Store length of command line DIR$ #RTSK ;Chain the task we really want BCC 1200$ ; If CC - continue CALL CCSERR ;Declare fatal error and exit .WORD ERRTSK ; *** Chain of task failed *** 1200$: SYSTEM 1300$ ;;Enter system state MOV #FTSKN,R3 ;;Get taskname we have installed CALL $SRSTD ;;Find the task BCS 1210$ ;; If CS - not found BIS #T3.REM,T.ST3(R0) ;;Flag for remove on exit MOV $TKTCB,R1 ;;Get our TCB address BIC #T3.MCR,T.ST3(R0) ;;Flag no prompt in spawned task BIT #T3.MCR,T.ST3(R1) ;;Will we prompt? BEQ 1210$ ;; If NE - no, skip BIS #T3.MCR,T.ST3(R0) ;;Flag spawned task to prompt BIC #T3.MCR,T.ST3(R1) ;; and make ourselves not 1210$: RETURN ;;Exit system state 1300$: EXIT$S ;Exit the task .SBTTL PR???? * ACTION ROUTINES ;+ ; These are the action routines for the install search. They assume the ; following .TPARS variables are setup. ; ; .PSTCN Count of characters matched ; .PSTPT Address of characters matched ;- ; ; *** PRBEGI *** Parse beginning of INSTALL command. ; PRBEGI: MOV .PSTCN,FINSL ;Set length of keyword ADD R3,FINSL ; and add rest of command MOV .PSTPT,FINSB ;Set address of keyword RETURN ;Return to parser ; ; *** PRENDI *** Parse end of INSTALL command. ; PRENDI: SUB R3,FINSL ;Subtract out remaining length SUB #5,FINSL ;Subtract out /CMD= string. RETURN ;Return to parser ; ; *** PRBEGC *** Parse beginning of command. ; PRBEGC: MOV R3,FCMDL ;Set length of command MOV R4,FCMDB ;Set address of keyword RETURN ;Return to parser ; ; *** PRENDC *** Parse end of command. ; PRENDC: SUB R3,FCMDL ;Subtract out remaining length SUB #1,FCMDL ;Subtract out quote string. CMP CMDMAX,FCMDL ;Is string within limits BLT REJECT ; If LT - no, reject RETURN ;Return to parser ; ; *** PRTASK *** Parse out task name. ; PRTASK: CMP #6,.PSTCN ;Is string longer than 6 characters BLT REJECT ; If LT - yes, reject MOV .PSTPT,R0 ;Get address of string MOV #1,R1 ;Accept periods. CALL $CAT5 ;Convert to RAD-50 MOV R1,FTSKN+0 ;Store as task name BCS 1000$ ; If CS - all done MOV #1,R1 ;Accept periods. CALL $CAT5 ;Convert to RAD-50 MOV R1,FTSKN+2 ;Store as task name 1000$: RETURN ;Return to caller REJECT: ADD #2,(SP) ;Take skip return RETURN ; all done .END