.TITLE PIN -- PROCEDURE INTERPRETER .IDENT /01.4/ ;+ ; WRITTEN BY: ; JAMES G. DOWNWARD ; KMS FUSION, INC. ; 3941 RESEARCH PARK DR ; ANN ARBOR, MICH. 48104 ; (313)-769-8500 ; 07-JUN-79 ; ; PIN is a procedure interpreter for RSX11M V4.0 with SPAWNing and ; STOP BIT directive support. Normally the indirect file processor is ; used to control assembly and task builds. The sizes of Indirect and PIN are ; ; ICP (standard ...AT.) ~12.K ; ICR (FCSRES ...AT.) ~ 8.K ; PIN (FCSRES) ~ 2.K ; ; that SPAWNing exists, a simple smaller task could read a command file, ; SPAWN the MCR commands, check exit status, etc. This is the function ; of PIN. With PIN it is possible to control an assembly/compile/taskbuild ; using only about 1/4 to 1/6 the core used by the 12K version of ...AT. ; (assuming PIN is built with FCSRES). ; ; Modified: ; 16-Oct-81 J. Downward Lower Case Error messages ; $COW,$EOW commands ;- .MCALL QIOW$,EXIT$S,DIR$,EXST$S,STSE$,SPWN$,GLUN$ .MCALL GCMLB$,GCML$,CSI$,CSI$1,CSI$2 .MCALL FINIT$,FSRSZ$,FDBDF$,FDOP$A,CLOSE$,OFID$R,GET$ .MCALL FDBF$R,FDRC$R,NMBLK$ .MCALL FHDOF$,FDOF$L,NBOFF$ ; .MACRO PRINT STRING MOV #STRING,R0 CALL PNTLIN .ENDM PRINT FHDOF$ DEF$L ; DEFNE FILE HEADER OFFSETS NBOFF$ DEF$L ; DEFINE NAME BLOCK OFFSETS LOCALLY ; COMMAND LINE MACROS AND DATA BLOCKS GCLBLK: GCMLB$ 0,PIN,HEADER,2 CSI$ .EVEN CSIBLK: .BLKB C.SIZE ; CSI BLOCK .EVEN ; HEADER: .BLKB 82. ; I/O MACROS AND DATA BLOCKS FDOF$L FSRSZ$ 1 ; SET UP FOR 1 LUN FDB: FDBDF$ ; START OF FDB FDOP$A 1,CSIBLK+C.DSDS,DFNB ; LUN 1 FOR FILE DFNB: NMBLK$ ,PRC,,SY,0 ; DEFALTS TO .PRC FILES ON SY0: ; LUN VALUES ARE SET UP AT TASK BUILD ; FOR PROGRAM TO WORK ; LUN=1 =>SY: THE .PRC FILE ; LUN=2 =>TI: THE TERMINAL(OR VT:) I/O BUFFER: .BLKB 80. BUFLEN = .-BUFFER BUFEND: .WORD 0 CMDLEN: .WORD 0 EOWFLG: .WORD 1 ; EXIT ON WARNING FLAG ; 0 = EXIT ON WARNING ; 1 = CONTINUE ON WARNING TRAFLG: .WORD 1 ; TRACE FLAG (=1 PRINT EACH COMMAND) DELFLG: .WORD 0 ; DELETE FLAG (=1 DELETE COMMAND ; FILE AT CLOSE) ; DPB'S QIODPB: QIOW$ IO.WVB,2,2,,,,<0,0,40> ; WRITE TO TERMINAL GETLUN: GLUN$ 2,GLNBUF ; GET TERMINAL INFORMATION SPAWN2: SPWN$ MCR...,,,,,1,,IEXBLK ; SPAWN TO TI: VIA MCR...(FINAL V3.2) STOP: STSE$ 1 ; STOP FOR EVENT FLAG IEXBLK: .BLKW 8. ; EXIT STATUS BLOCK GLNBUF: .BLKW 6 ; BUFFER FOR GETLUN DIRECTIVE ; ERROR MESSAGES ; .ENABL LC ERM1: .ASCIZ /PIN -- Syntax error/<7> ERM2: .ASCIZ /PIN -- Illegal file name/<7> ERM3: .ASCIZ /PIN -- File open error/<7> ERM4: .ASCIZ /PIN -- No such file/<7> ERM5: .ASCIZ /PIN -- SPAWN failure/<7> ERM6: .ASCIZ /PIN -- STOP for Event Flag failed/<7> ERM7: .ASCIZ /PIN -- WARNING, Exit with non-fatal error/<7> ERM8: .ASCIZ /PIN -- FATAL, Exit with severe error/<7> ERM9: .ASCIZ /PIN -- Procedure file read error/<7> ERM10: .ASCIZ /PIN -- Procedure file close error/<7> ERM11: .ASCIZ /PIN -- EOF/<7> ERM13: .ASCIZ <15>/PIN -- Only single line, valid MCR commands allowed/<7> ERM14: .ASCIZ <15>/PIN -- WARNING, Unknown internal command/<7> .EVEN ; ; READ AND DECODE THE COMMAND LINE ; PIN:: FINIT$ ; INITIALIZE FSR GCML$ #GCLBLK ; GET COMMAND LINE BCC CONTIN ; NO ERROR SERR: PRINT ERM1 ; SYNTAX ERROR JMP ERRXIT ; CONTIN: ; REF LABLE ; TST ; IS ANYTHING TYPED TSTB ; ANY ERRORS ON INPUT BEQ 1$ ; IF EQ, NO JMP ERRXIT ; 1$: ; REF LABLE CSI$1 #CSIBLK,GCLBLK+G.CMLD+2,GCLBLK+G.CMLD ; CHECK SYNTAX BCS SERR ; ERROR IN SYNTAX FOUND TST ; JUST IN CASE A BUNCH OF SPACES FOLLOWED ; BY A ^Z WERE TYPED, CHECK TO BE SURE >0 ; PARSED CHARACTER IS IN THE CSIBLK BNE 2$ ; ALL IS OK JMP ERRXIT ; ONLY ONE CHARACTER EXIT WITH ERROR ; CHECK TO SEE IF SOME ONE TRIED USING THE FILSPEC=FILESPEC TYPE ; COMMAND LINE. IF SO, THIS IS A SYNTAX ERROR ; 2$: MOV #CSIBLK+C.STAT,R0 ; GET ADDRESS OF STATUS WORD BITB #CS.EQU,(R0) ; WAS AN EQUAL SIGN SEEN? BNE SERR ; IF NE, EQUAL SIGN SEEN CSI$2 #CSIBLK,OUTPUT ; DECODE THE FILE NAME BCS SERR ; SYNTAX ERROR IF NOT OKAY ; NOW CHECK TO SEE IF WILD CARDS ARE SPECIFIED ; MOV #CSIBLK+C.STAT,R0 ; GET ADDRESS OF STATUS WORD BITB #CS.WLD,(R0) ; ANY WILD CARDS BEQ 15$ ; IF EQ, NO WILD CARDS JMP SERR ; SYNTAX ERROR 15$: MOV #FDB,R0 ; FDB ADRESS IN R0 MOV #FDB+F.FNB,R1 ; FNB ADDRESS IN R1 MOV #CSIBLK+C.DSDS,R2 ; DATASET POINTER IN R2 MOV #DFNB,R3 ; SETUP THE DEFAULT FILE NAME BLOCK CALL .PARSE ; PARSE THE FDB BCC 20$ ; ALL OK SO SKIP ERROR MESSAGE PRINT ERM2 ; ILLEGAL FILE NAME JMP ERRXIT ; AND EXIT WITH SEVERE ERROR 20$: ; REF LABLE CALL .FIND ; FIND THE FILE BCC OPEN ; IF CC, NO ERROR, SO OPEN FILE OPNERR: CMPB #IE.NSF,FDB+F.ERR ; IS IT NO SUCH FILE? BEQ 5$ ; YES 3$: PRINT ERM3 ; FILE OPEN ERROR JMP ERRXIT ; AND RE-START. 5$: PRINT ERM4 ; NO SUCH FILE JMP ERRXIT ; SO ERRXIT ; ; OPEN THE FILE AND LOOK AT IT. ; OPEN: ; REF LABLE FDRC$R #FDB ; 20$: OFID$R #FDB ; OPEN THE FILE BY ID BCC LOOK ; FILE OPENED WITHOUT ERRORS JMP OPNERR ; WARN USER OF ERROR LOOK: GET$ #FDB,#BUFFER,#BUFLEN,FILERR MOV FDB+F.NRBD+2,R2 ; GET THE START OF THE BUFFER IN R2. CMPB (R2),#'@ ; IS FIRST CHARACTER BGE 10$ ; OK IF >= AN 'A' CMPB (R2),#'; ; OR MAYBE A COMMENT BEQ 10$ ; OK IF A ';' CMPB (R2),#'$ ; IS IT AN INTERNAL COMMAND BNE 5$ ; IF NE, NO CALL CHKCMD ; SEE IF ITS A COMMAND JMP LOOK ; GO BACK AND LOOK FOR MORE TO DO 5$: PRINT ERM13 ; ELSE WARN USER OF ILLEGAL RECORD FORMAT CALL WRTCMD ; SHOW USER OFFENDING LINE JMP ERRXIT ; AND EXIT 10$: CMPB (R2),#'Z ; IS IT <='Z' BLE 12$ ; IF LE,YES IT IS PRINT ERM13 ; WARN USER CALL WRTCMD ; SHOW USER OFFENDING LINE JMP ERRXIT ; AND EXIT 12$: ; REF LABLE TST TRAFLG ; IS TRACE SET BEQ 15$ ; IF EQ 0, NO CALL WRTCMD ; GO DISPLAY COMMAND 15$: ; REF LABLE MOV FDB+F.NRBD,R3 ; AND LENGTH OF BUFFER. MOV R3,CMDLEN MOV CMDLEN,R3 ; RESTORE IT MOV CMDLEN,SPAWN2+S.PWCL ; SET LENGTH HERE ALSO MOV R2,SPAWN2+S.PWCA ; SET ADDRESS HERE TOO DIR$ #SPAWN2 ; FIRST TRY SPAWNING TO MCR... BCC 18$ ; IF CC, WE GOT IT PRINT ERM5 ; SPAWN FAILURE CALL WRTCMD ; WRITE OUT COMMAND THAT SPAWN FAILED ON JMP ERRXIT 18$: DIR$ #STOP ; STOP FOR EFN 1 BCC 20$ ; IF CC ALL OK PRINT ERM6 ; STOP FOR EVENT FLAG FAILURE CALL WRTCMD ; WRITE OUT COMMAND STOP FAILED ON JMP ERRXIT ; ERRXIT 20$: CMP #4,IEXBLK ; IS IT FATEL BEQ 22$ ; YES CMP #1,IEXBLK ; IS IT SUCCESS BEQ 21$ ; IF EQ, YES, OTHERWISE IS A WARNING ERROR PRINT ERM7 ; WARNING, EXIT WITH NON-FATAL STATUS CALL WRTCMD ; WRITE OUT OFFENDING COMMAND TST EOWFLG ; SHOULD WE EXIT ON WARNING BNE 21$ ; IF NE, NO JMP ERRXIT ; EXIT AND SET ERROR STATUS 21$: JMP LOOK ; CONTINUE 22$: CMP #4,IEXBLK ; IS IT A SEVERE ERROR BNE 24$ ; IF NE , NO CALL WRTCMD ; WRITE OUT OFFENDING COMMAND PRINT ERM8 ; EXIT WITH SEVERE ERROR JMP ERRXIT ; ERRXIT 24$: JMP LOOK ; AGAIN ;+ ; WRTCMD -- ISSUE QIO TO WRITE OUT OFFENDING COMMAND ; ;- WRTCMD: ; MOV FDB+F.NRBD+2,QIODPB+Q.IOPL; GET ADDRESS OF COMMAND MOV FDB+F.NRBD,QIODPB+Q.IOPL+2; SET COMMAND LENGTH DIR$ #QIODPB ; ISSUE QIO RETURN ; ; ;+ ; CHKCMD ; A COMMAND BEGINNING WITH '$' IS AN INTERNAL PIN COMMAND ; SO SEE IF THE ENTERED LINE IS SUCH A COMMAND ; IF IT IS, DO WHAT IS NEEDED AND RETURN ; IF IT ISN'T PRINT A NASTY MESSAGE, AND RETURN ; ; INPUT: R2 POINT TO COMMAND BUFFER ; DON'T FIDDLE WITH ANYTHING ELSE ; ALLOWED COMMANDS ; $DELETE - DELETE THIS COMMAND FILE ON EXIT ; $TRACT - PROVIDE A TRACING OF THE COMMANDS SPAWNED ; $NODEL - DON'T DELETE THE FILE(IS INITIAL DEFAULT) ; $NOTR - NO TRACE(SET BY DEFAULT) ; $EOW - EXIT ON WARNING ERROR ; $COW - CONTINUE ON WARNING ERROR(DEFAULT CHKCMD: MOV R2,R4 ; SAVE R4 INC R2 ; POINT TO NEXT CHARACTER CMPB (R2),#'D ; IS IT DELETE? BNE 20$ ; NO, SO CHECK SOME MORE INC R2 ; NEXT LETTER PLEASE CMPB (R2),#'E ; IS IT AN 'E' BNE 200$ ; IF NE, ERROR RETURN INC DELFLG ; SET DELETE FLAG RETURN ; AND RETURN 20$: CMPB (R2),#'N ; MAYBE A 'NO' BNE 40$ ; IF NE, NO INC R2 ; MAYBE EITHER A NOTR OR NODE CMPB (R2),#'O ; IS IT NO BNE 200$ ; IF NE, ERROR RETURN WITH NASTY MESSAGE INC R2 ; BUMP TO NEXT CHARACTER CMPB (R2),#'D ; IS IT DELETE BNE 25$ ; IF NE, CHECK 'NOTR' INC R2 ; SEE IF 'E' CMPB (R2),#'E ; AN 'E' PERHAPS BNE 200$ ; NO, ERROR RETURN CLR DELFLG ; RESET DELETE FLAG RETURN ; AND RETURN 25$: CMPB (R2),#'T ; IS IT 'NOTR' BNE 200$ ; IF NE, NO, ERROR INC R2 ; BUMP COUNTER CMPB (R2),#'R ; IS IT 'TR' BNE 200$ ; IF NE, NO , ERROR CLR TRAFLG ; YES, RESET TO NO TRACE RETURN 40$: CMPB (R2),#'T ; IS IT 'TRACE' BNE 60$ ; CHECK NEXT FOR $EOW INC R2 ; CMPB (R2),#'R ; IS IT 'R' BNE 200$ ; NO ERROR INC TRAFLG ; SET TRACE FLAG RETURN 60$: CMPB (R2),#'E ; IS IN $EOW? BNE 80$ ; IF NO CHECK FOR $COW INC R2 ; CMPB (R2),#'O ; IS IT 'O' BNE 200$ ; IF NE, FATAL ERROR CLR EOWFLG ; CLEAR FLAG RETURN 80$: CMPB (R2),#'C ; IS IT $COW BNE 200$ ; NO, THEN IS UNKNOWN COMMAND INC R2 ; CMPB (R2),#'O ; AN 'O'? BNE 200$ ; UNKNOWN COMMAND INC EOWFLG ; IT IS, WE SHOULD CONTINUE ON WARNING ERRORS RETURN 200$: MOV R4,R2 ; RESTORE POINTER CALL WRTCMD ; WRITE IT OUT PRINT ERM14 ; PRINT OUT WARNING THAT IT IS AN UNKNOWN COMMAND RETURN ; EXIT AND ERROR ROUTINES ; ; ERRXIT: ; REF LABLE TST TRAFLG ; SHOULD WE PRINT EXIT MESSAGE BEQ 25$ ; IF EQ 0, NO PRINT ERM11 ; PRINT EXIT LINE 25$: EXST$S #4 ; EXIT WITH SEVERE ERROR FILERR: TST (SP)+ ; POP OFF RETURN ADDR CMPB F.ERR(R0),#IE.EOF ; IS IT EOF? BEQ 10$ ; NO -- ERROR PRINT ERM9 ; CMD FILE READ ERROR JMP ERRXIT ; EXIT WITH SEVERE ERROR 10$: ; REF LABLE TST DELFLG ; SHOULD WE DELETE THIS FILE WHEN WE CLOSE BEQ 15$ ; IF EQ 0 NO MOV #FDB,R0 ; YES WE SHOULD CALL .DLFNB ; DELET BY FILE NAME BLOCK BR 16$ ; LOOP THROUGH COMMON CODE 15$: CLOSE$ #FDB ; CLOSE THE FILE. 16$: BCS 20$ ; FILE CLOSE ERROR JMP SUCXIT ; EXIT WITH SUCCESS 20$: PRINT ERM10 ; FILE CLOSE ERROR JMP ERRXIT ; EXIT WITH SEVERE STATUS SUCXIT: ; REF LABLE 10$: TST TRAFLG ; SHOULD WE PRINT MESSAGE BEQ 20$ ; IF EQ 0 NO PRINT ERM11 ; NORMAL EXIT MESSAGE 20$: EXST$S #1 ; EXIT WITH SUCCESS ;+ ; PNTLIN ; ; THIS ROUTINE WILL PRINT AN ASCIZ LINE ;- PNTLIN: MOV #-1,R1 ; GET COUNT INITIALIZED MOV R0,QIODPB+Q.IOPL ; STORE BUFFER ADDRESS 170$: INC R1 ; INCREMENT COUNTER TSTB (R0)+ ; IS THIS THE LAST BYTE? BNE 170$ ; NO. KEEP GOING MOV R1,QIODPB+Q.IOPL+2 ; STORE BYTE COUNT DIR$ #QIODPB RETURN .END PIN