.TITLE TYPE A FILE ON TERMINAL .IDENT /01/ ;07-JAN-80 ; ; WRITTEN BY NORM PERRON FOR RSX-11M ; ; FEATURES: ; ; 1. IF NO FILE EXTENSION IS ENTERED, A TABLE WILL BE SEARCHED ; TO TRY SEVERAL DEFAULTS. ; ; 2. CONTROL C OR CONTROL Z WILL STOP TASK. ; ; 3. OUTPUT WILL BE TRUNCATED AT END OF MCR>SET /BUF SIZE. ; OR OPTIONALLY SET TO OTHER SIZE THORUGH A SWITCH ; ; 4. FORM FEEDS AND BLANK LINES ARE STRIPPED OFF. ; OR OPTIONALLY RETAINED THROUGH A SWITCH ; ; 5. HOLD SCREEN MODE ; OPTIONALLY THROUGH A SWITCH ; ; 6. CHECK FOR BINARY FILES AND AVOID PRINTING ; OR OPTIONALLY OVERRIDE THROUGH A SWITCH ; ; 7. TYPE HELP ON HOW TO USE SWITCHES ; OPTIONALLY THROUGH A SWITCH ; ; 8. TECO MACRO FILES ARE TYPED CORRECTLY. FILES WITH EXTENSIONS ; OF TEC ARE TREATED AS TECO MACRO FILES ; OR OPTIONALLY OVERRIDDEN THROUGH SWITCHES ; ; 9. WILD CARD PROCESSING ; ; 10. INDIRECT COMMAND FILES ; ; 11. PRINTS FILE NAME ALONG WITH FILE ; ; TO ASSEMBLE, BUILD, INSTALL AND RUN, ; ; MCR>MAC TYP=TYP ; MCR>TKB @TYPBLD ; MCR>INS TYP ; MCR>TYP FILE[/SW] ; OR ; MCR>TYP FILE.EXT[/SW] ; OR ; MCR>TYP ; ENTER FILE NAME OR /HE FOR HELP: FILE[.EXT][/SW] ; ; FILE TYPBLD.CMD ;TYP/CP=TYP ;/ ;STACK=100 ;TASK=...TYP ;UNITS=3 ;ASG=TI:2:3 ;// ; .NLIST SYM .MCALL EXIT$S,QIOW$,DIR$,ASTX$S,GLUN$,WSIG$S .MCALL FSRSZ$,FDBDF$,FDRC$A,FDOP$A .MCALL OPEN$R,GET$,CLOSE$,FINIT$,NMBLK$ .MCALL CSI$,CSI$1,CSI$2,GCMLB$,GCML$ .MCALL CSI$SW,CSI$ND,CSI$SV ; SYLUN=1 ;LUN FOR DISK GCMLUN=2 ;GET COMMAND LINE LUN TTLUN=3 ;LUN FOR TERMINAL EFN=1 ;EVENT FLAG NUM RECSIZ=132. ;MAX RECORD SIZE FUSW=1 ;FULL SWITCH FFSW=2 ;FORM FEED RETAINED SWITCH HOSW=4 ;HOLD SCREEN SWITCH NCSW=10 ;NO CHECK FILE EXTENSIONS SWITCH HESW=20 ;HELP SWITCH TESW=40 ;TEC FILE NTSW=100 ;NT TECO FILE SWITCH WISW=200 ;WILD CARD SPECIFIED ; .ENABL LSB START: FINIT$ ;INIT FILE STORAGE REGION MOV #RECBUF,R5 ;WILL BE USING A LOT AGAIN: CALL INIT ;INIT TASK CLR SWMASK ;CLEAR ALL FLAGS TST EXIFLG ;EXIT WANTED? BNE 100$ ;BR IF YES GCML$ #CMDBLK,#PROMSG,#PROLEN ;GET COMMAND LINE + PROMPT BCC 110$ ;BR IF OK CMPB #GE.EOF,G.ERR(R0) ;EOF? BNE 99$ ;BR IF NO, ERROR 100$: EXIT$S ;EXIT ; ; 110$: CSI$1 #CSIBLK,CMDBLK+G.CMLD+2,CMDBLK+G.CMLD ;CHECK SYNTAX BCS 99$ ;ERROR CSI$2 ,OUTPUT,#SWTABL ;PARSE FILE NAME BCS 99$ ;ERROR MOV SWMASK,R4 ;WILL BE USING FLAGS A LOT CALL ATTATC ;ATTATCH TO TERMINAL CALL HELP ;SEE IF NEEDS HELP BITB #CS.WLD,C.STAT(R0) ;WILD CARD SPECIFIED? BEQ 140$ ;BR IF NO BIS #WISW,R4 ;SAVE WILD CARD STATUS MOV #INPFDB,R0 ;SET UP FOR .PARSE MOV #INPFDB+F.FNB,R1 ;FILE NAME BLOCK MOV #CSIBLK+C.DSDS,R2 ;DATA SET DESCRIPTOR MOV F.DFNB(R0),R3 ;DEFAULT FILE NAME BLOCK CALL .PARSE ;PARSE WILD CARD FILE NAME BCS 99$ ;BR IF ERROR 130$: CALL .FIND ;FIND DIRECTORY ENTRY BCS 190$ ;BR IF DONE CMP INPFDB+F.FNB+N.NEXT,INDEX ;NEW ONE? BEQ 130$ ;BR IF NOT (SAME FILE) CALL INIT ;RE-INIT TASK CALL ATTATC ;ATTATCH TO TERMINAL MOV INPFDB+F.FNB+N.NEXT,INDEX ;UPDATE INDEX 140$: MOV #EXTLST,R1 ;POINTER TO FILE EXTENSIONS TO TRY BIT #FUSW,R4 ;FULL SPECIFIED? BEQ 150$ ;BR IF NO MOV FUSIZ,TRMSIZ ;USE WHAT HE GAVE BNE 150$ ;BR IF HE DIDN'T GIVE ANYTHING MOV #RECSIZ,TRMSIZ ;USE DEFAULT 150$: OPEN$R #INPFDB ;OPEN SPECIFIED FILE BCC 160$ ;BR IF OK BIT #WISW,R4 ;WORKING ON WILD CARDS? BNE NSF ;BR IF YES, CAN'T FIND FILE MOV (R1)+,DEFNAM+N.FTYP ;SET UP NEXT FILE EXTENSION BNE 150$ ;BR IF VALID BR NSF ;NO SUCH FILE ERROR ; 160$: CALL PRINAM ;PRINT FILE NAME CMP INPFDB+F.FNB+N.FTYP,(PC)+ ;TEC EXTENSION? .RAD50 /TEC/ BNE 170$ ;BR IF NO BIT #NTSW,R4 ;NOT TECO FILE SWITCH GIVEN? BNE 170$ ;BR IF YES (NOT A TECO FILE) BIS #TESW,R4 ;SET FLAG 170$: MOV #40,OUTDPB+Q.IOPL+4 ;ASSUME NEED CARRIAGE CONTROL BITB #FD.CR,INPFDB+F.RATT ;NEED IT? BNE 180$ ;BR IF NO CLR OUTDPB+Q.IOPL+4 ;SAY NO NEED, IT'S IN RECORD 180$: GET$ ;READ A RECORD BCC 200$ ;BR IF OK CMPB #IE.EOF,F.ERR(R0) ;EOF? BEQ CLOSE ;BR IF YES BR 200$ ;TSTBIN SHOULD FIND IT 99$: BR CMDERR ;COMMAND ERROR ; 190$: BIC #WISW,R4 ;ALL DONE WITH WILD CARDS BR FINI ; 200$: CALL TSTBIN ;TEST FOR BINARY EXT BITB #FD.FTN,INPFDB+F.RATT ;FORTRAN OUTPUT? BEQ 210$ ;BR IF NO MOVB (R5),OUTDPB+Q.IOPL+4 ;PICK UP FORTRAN'S CARRIAGE CONT. CLRB (R5) ;PUT IN A NULL 210$: BIT #FFSW,R4 ;FORM FEEDS WANTED? BNE 220$ ;BR IF YES CMPB #14,(R5) ;FORM FEED? BNE 220$ ;BR IF NOT CLRB (R5) ;GET RID OF IT (PUT IN A NULL) MOV #FFMSG,R1 ;PICK UP MESSAGE MOV #FFLEN,R2 ;PICK UP SIZE MOV OUTDPB+Q.IOPL+4,R3 ;SAVE CARRIAGE CONTROL MOV #40,OUTDPB+Q.IOPL+4 ;SET UP CORRECTLY CALL OUTLIN ;TELL HIM ABOUT FORM FEED MOV R3,OUTDPB+Q.IOPL+4 ;RESTORE TO PREVIOUS 220$: CALL TSTTEC ;TEST FOR TECO FILE CALL TRUNCA ;TRUNCATE WRAP-AROUND TST EXIFLG ;EXIT? BNE 230$ ;BR IF YES MOV #OUTBUF,R1 ;PICK UP BUFF ADDR ;R2=LENGTH CALL OUTLIN ;TYPE LINE BR 180$ ;GET NEXT RECORD ; 230$: BIC #WISW,R4 ;INDICATE DONE CLOSE: CLOSE$ ;CLOSE FILE FINI: MOV #IO.DET,ATTDPB+Q.IOFN ;SET UP TO DETATCH DIR$ #ATTDPB ;JUST IN CASE HE CONTROLLED O'ED BIT #WISW,R4 ;WORKING ON WILD CARDS? BNE 250$ ;BR IF YES 240$: JMP AGAIN ;DO IT ALL AGAIN 250$: MOV #INPFDB+F.FNB,R1 ;FILE NAME BLOCK MOV INDEX,INPFDB+F.FNB+N.NEXT ;UPDATE INDEX JMP 130$ ;FIND NEXT ONE .DSABL LSB ; ; ERROR PROCESSING ; CMDERR: MOV #CMDMSG,R1 ;SET UP MESSAGE BUFFER MOV #CMDLEN,R2 ;SET UP LENGTH BR OUTERR ;OUTPUT ERROR ; NSF: MOV #NSFMSG,R1 ;SET UP MESSAGE BUFFER MOV #NSFLEN,R2 ;SET UP LENGTH OUTERR: CLR NUMLIN ;BE SURE NO INPUT NEEDED CALL OUTLIN ;TYPE ERROR MESSAGE BR CLOSE ;CLOSE FILE + EXIT ; ; OUTPUT A LINE ; OUTLIN: MOV R1,OUTDPB+Q.IOPL ;SET UP BUFFER ADDRESS MOV R2,OUTDPB+Q.IOPL+2 ;SET UP BUFFER COUNT BR 10$ 5$: WSIG$S ;WAIT FOR SIGNIFICANT EVENT 10$: DIR$ #OUTDPB ;TYPE LINE BCC 15$ ;BR IF NO ERROR CMP #IE.UPN,$DSW ;POOL EMPTY? BEQ 5$ ;BR IF YES, TRY LATER IOT ;FATAL ERROR, CRASH TASK 15$: BIT #HOSW,R4 ;HOLD SCREEN? BEQ 40$ ;BR IF NO INC NUMLIN ;NOW 1 EXTRA LINE CMP #23.,NUMLIN ;FULL SCREEN? BGT 40$ ;BR IF NO CLR NUMLIN ;START WITH CLEAN SLATE DIR$ #INPDPB ;WAIT FOR RESPONSE BICB #40,(R5) ;CONVERT TO UPPER CASE CMPB #'G,(R5) ;G=GO WITHOUT /HO MODE BNE 20$ ;BR IF NOT BIC #HOSW,R4 ;CLEAR /HO SWITCH BR 40$ 20$: CMPB #32,(R5) ; Z? BEQ 30$ ;BR IF YES CMPB #3,(R5) ; C? BNE 40$ ;BR IF NO 30$: INC EXIFLG ;INDICATE EXIT WHEN CHANCE 40$: RETURN ; ; PRINT FILE NAME ; PRINAM: MOV #INPFDB+F.FNB+N.FNAM,R3 ;START OF RAD50 FILE NAME MOV R0,-(SP) ;SAVE FDB ADDR MOV R1,-(SP) MOV (R3)+,R1 ;WHERE TO GET RAD50 DATA MOV #FILNA1,R0 ;WHERE TO PUT ASCII CALL $C5TA ;CONVERT 1ST 3 CHARS OF FILE NAME TO ASCII MOV (R3)+,R1 ;GET NEXT 3 CHARS CALL $C5TA ;CONVERT TO ASCII MOV (R3)+,R1 ;GET LAST 3 CHARS CALL $C5TA ;CONVERT TSTB (R0)+ ;SKIP PERIOD MOV (R3)+,R1 ;GET 3 CHAR EXTENSION CALL $C5TA TSTB (R0)+ ;SKIP ; MOV (R3),R1 ;GET BINARY VERSION # .REPT 0 ;THE FOLLOWING SOULD, BUT DOESN'T WORK CMP #NB.VER,INPFDB+F.FNB+N.STAT ;EXPLICIT VERSION # SPECIFIED? BEQ 10$ ;BR IF YES (DON'T LOOK FOR LATEST NEXT TIME) .ENDR CLR (R3) ;GET VERSION # READY FOR NEXT .FIND 10$: CLR R2 ;INDICATE ZERO SUPPRESS CALL $CBOMG ;CONVERT BINARY TO ASCII MOV #FILNAM,R1 ;START OF MESSAGE MOVB #15,(R0)+ ;STUFF A CARRIAGE RETURN SUB R1,R0 ;CONVERT LENGTH MOV R0,R2 ;NEEDED IN R2 CALL OUTLIN ;OUTPUT LINE MOV (SP)+,R1 MOV (SP)+,R0 ;RESTORE FDB ADDR RETURN ; ; TEST FOR BINARY EXTENSION ; TSTBIN: MOV F.NRBD(R0),R1 ;# OF CHARS BEQ 20$ ;BR IF NONE MOV R5,R2 ;START OF BUFFER 10$: BITB #200,(R2)+ ;HIGH ORDER BIT SET (IF CLEAR MIGHT BE ASCII) BNE 30$ ;BR IF NOT ASCII DEC R1 ;COUNT CHARS BNE 10$ ;BR IF NOT DONE RECORD 20$: RETURN 30$: BIT #NCSW,R4 ;BYPASS CHECKING? BNE RET ;BR IF YES CLOSE$ ;CLOSE FILE MOV #BADMSG,R1 ;SET UP MESSAGE BUF MOV #BADLEN,R2 ;SET UP LENGTH OUTEXI: CALL OUTLIN ;TELL USER BAD EXTENSION TST (SP)+ ;CLEAN STACK JMP FINI ;DONE ; ; HELP PROCESSING ; HELP: BIT #HESW,R4 ;NEED HELP? BEQ RET ;BR IF NO MOV #HELMSG,R1 ;SET UP MESSAGES MOV #HELLEN,R2 CALL OUTLIN ;TYPE IT MOV #HE1MSG,R1 MOV #HE1LEN,R2 CALL OUTLIN MOV #HE2MSG,R1 MOV #HE2LEN,R2 CALL OUTLIN MOV #HE3MSG,R1 MOV #HE3LEN,R2 CALL OUTLIN MOV #HE4MSG,R1 MOV #HE4LEN,R2 BR OUTEXI ;OUTPUT LINE + EXIT ; ; TRUNCATE WRAP-AROUND (CALCULATE ACTUAL # OF CHARS LOOKING FOR TAB'S ; TRUNCA: MOV #OUTBUF,R2 ;START OF BUFFER MOV F.NRBD(R0),R1 ;PICK UP LENGTH BEQ 20$ ;BR IF EMPTY ADD R2,R1 ;CALCULATE END OF BUFFER CLR R3 ;# OF CHARS TO OUTPUT 5$: CMPB #11,(R2)+ ;TAB CHAR? BNE 10$ ;BR IF NO MOV R0,-(SP) ;SAVE R0 MOV R3,R0 ;SAVE SO WE DON'T DESTROY BIC #177770,R0 ;MODULO 8 MOVB TABTAB(R0),R0 ;PICK UP TAB VALUE ADD R0,R3 ;CALCULATE WHAT THIS TAB'S WORTH MOV (SP)+,R0 ;RESTORE R0 BR 15$ 10$: INC R3 ;ADD IN THIS CHAR 15$: CMP TRMSIZ,R3 ;MAX TERM SIZE? BLE 20$ ;R IF YES CMP R1,R2 ;END OF BUFFER BNE 5$ ;BR IF NO 20$: SUB #OUTBUF,R2 ;CALCULATE LENGTH RET: RETURN ; ; INIT TASK ; INIT: CLR FUSIZ ;CLEAR LISTING SIZE CLR NUMLIN ;CLEAR NUMER OF LINES TYPED DIR$ #GLUDPB ;GET LUN INFO MOV RECBUF+12,TRMSIZ;SET UP TERMINAL SIZE CLR DEFNAM+N.FTYP ;ACTUALLY STORE 3 .RAD50 BLANKS RETURN ; ; UNSOLICITED TERMINAL INPUT AST HANDELING ; ATAAST: CMPB #32,(SP) ; Z? BEQ 20$ ;BR IF YES CMPB #3,(SP) ; C? BNE 30$ ;BR IF NOT 20$: INC EXIFLG ;INDICATE EXIT WHEN CHANCE BR 40$ 30$: DIR$ #ATADPB ;RE-ATTATCH 40$: TST (SP)+ ;GET RID OF CHAR ASTX$S ;EXIT AST ; ; TEST FOR TECO LINE + RE FORMAT ; TSTTEC: MOV #OUTBUF,R1 ;OUTPUT BUFFER MOV R5,R2 ;WHERE TO GET DATA MOV F.NRBD(R0),R3 ;# OF CHARS BEQ 50$ ;BR IF ZERO BIT #TESW,R4 ;TEC FILE? BEQ 40$ ;BR IF NO 10$: CMPB #11,(R2) ;TAB? BEQ 30$ ;BR IF YES, DON'T CONVERT TSTB (R2) ;NULL? BEQ 30$ ;BR IF YES CMPB #33,(R2) ;ESCAPE? BEQ 20$ ;BR IF YES, CONVERT TO $ BLT 30$ ;BR IF CONTROL CHAR MOVB #'^,(R1)+ ;STUFF A ^ TO SAY CONTROL CHAR MOVB (R2),-(SP) ;PUT CHAR IN WORD ADD #'@,(SP) ;FORM ASCII MOVB (SP)+,(R2) ;PUT IT BACK INC F.NRBD(R0) ;INDICATE AN EXTRA CHAR BR 30$ 20$: MOVB #'$,(R2) ;CONVERT ESCAPE TO $ 30$: MOVB (R2)+,(R1)+ ;COPY CHAR TO OUTPUT BUFFER DEC R3 ;DONE? BNE 10$ ;BR IF NO RETURN ; 40$: MOVB (R2)+,(R1)+ ;COPY RECBUF TO OUTBUF DEC R3 ;DONE? BNE 40$ ;BR IF NO 50$: RETURN ; ; ATTATCH TO TERMINAL ; ATTATC: DIR$ #ATADPB ;ATTATCH TO UNSOLICITED INPUT MOV #IO.ATT,ATTDPB+Q.IOFN ;SET UP TO ATTATCH DIR$ #ATTDPB ;ATTATCH TO TERMINAL (FOR O ) RETURN .NLIST BEX ; ; TABLE OF TABS ; TABTAB: .BYTE 8.,7,6,5,4,3,2,1 ; ; TABLE OF FILE EXTENSION DEFAULTS TO TRY BEFORE SAYING NO SUCH FILE ; EXTLST: .RAD50 /LST/ ;FILE EXTENSIONS TO TRY .RAD50 /MAC/ .RAD50 /FTN/ .RAD50 /CMD/ .RAD50 /DAT/ .RAD50 /MAP/ .RAD50 /DOC/ .RAD50 /TEC/ .WORD 0 ;END OF TABLE ; ; FILE CONTROL SERVICES DEFINITIONS ; INPFDB: FDBDF$ ;SET UP FILE DESCIPTOR BLOCK FDRC$A ,RECBUF,RECSIZ FDOP$A SYLUN,CSIBLK+C.DSDS,DEFNAM DEFNAM: NMBLK$ ,< >,,SY ;DEFAULT FILE NAME BLOCK FSRSZ$ 1 ;1 FILE TO BE OPENED ; ; COMMAND STRING INTERPRETOR DEFINITIONS ; CSI$ ;DEFNE CSI CONTROL BLOCK CSIBLK: .BLKB C.SIZE ;ALLOCATE STORAGE CMDBLK: GCMLB$ 1,,RECBUF,GCMLUN ;ALLOC + INIT GCML BLOCK ; ; SWITCHES ; SWTABL: CSI$SW FU,FUSW,SWMASK,SET,NEG,FUVAL CSI$SW FF,FFSW,SWMASK,SET,NEG CSI$SW HO,HOSW,SWMASK,SET,NEG CSI$SW NC,NCSW,SWMASK,SET,NEG CSI$SW HE,HESW,SWMASK,SET,NEG CSI$SW TE,TESW,SWMASK,SET,NEG CSI$SW NT,NTSW,SWMASK,SET,NEG CSI$ND ;END OF TABLE CSI$SV DECIMAL,FUSIZ,4,FUVAL CSI$ND ;END OF TABLE ; RECBUF: .BLKB RECSIZ ;WHERE TO STORE RECORD OUTBUF: .BLKB RECSIZ*2 ;OUTPUT BUFFER EXIFLG: .BLKW 1 ;EXIT FLAG TRMSIZ: .BLKW 1 ;SET /BUF SIZE SWMASK: .BLKW 1 ;SWITCH MASK FUSIZ: .BLKW 1 ;/FU: VALUE NUMLIN: .BLKW 1 ;NUMBER OF LINES TYPED SO FAR INDEX: .BLKW 1 ;INDEX FOR FCS OUTDPB: QIOW$ IO.WLB,TTLUN,EFN,,,,;FOR TERMINAL ATADPB: QIOW$ IO.ATA,TTLUN,EFN,,,, ATTDPB: QIOW$ IO.ATT,TTLUN INPDPB: QIOW$ IO.RNE!IO.RAL,TTLUN,EFN,,,, ;READ NO ECHO+READ PASS ALL GLUDPB: GLUN$ TTLUN,RECBUF PROMSG: .ASCII <12><15>@ENTER FILE NAME OR /HE FOR HELP: @ PROLEN=.-PROMSG ;LENGTH OF MESSAGE CMDMSG: .ASCII @TYP -- COMMAND ERROR@ CMDLEN=.-CMDMSG NSFMSG: .ASCII @TYP -- NO SUCH FILE@ NSFLEN=.-NSFMSG FFMSG: .ASCII <11><11>@*** FORM FEED ***@ FFLEN=.-FFMSG BADMSG: .ASCII <12><15>@TYP -- BINARY FILE@ BADLEN=.-BADMSG FILNAM: .ASCII <12><15>@******************************************* FILE: @ FILNA1: .ASCII @AAAAAAAAA.AAA;NNNNNN@ HELMSG: .ASCII @THIS PROGRAM TYPES A FILE ON YOUR TERMINAL.@<12><15> .ASCII @YOU MUST SPECIFY A FILE NAME, OPTIONALLY AN EXTENSION@ .ASCII @ AND OPTIONALLY SWITCHES.@ HELLEN=.-HELMSG HE1MSG: .ASCII @IF NO EXTENSION IS ENTERED, A TABLE OF DEFAULT@ .ASCII @ EXTENSIONS IS SEARCHED.@<12><15> .ASCII @INDIRECT COMMAND FILES AND WILD CARDS ARE SUPPORTED.@<12><15> .ASCII @THE CONTROL C KEY WILL STOP THE PROGRAM.@ HE1LEN=.-HE1MSG HE2MSG: .ASCII @THE POSSIBLE SWITCHES ARE:@<12><15> .ASCII @/HE FOR THIS HELP TEXT@<12><15> .ASCII @/FU TO TYPE A FULL LINE@<12><15> .ASCII @/FF OUTPUT FORM FEEDS TO TERMINAL@ HE2LEN=.-HE2MSG HE3MSG: .ASCII @/HO HOLD SCREEN WHEN FULL. HIT TO CONTINUE@<12><15> .ASCII @ HIT G TO CONTINUE WITHOUT /HO@<12><15> .ASCII @/NC NO CHECKING FOR BINARY EXTENSIONS@ HE3LEN=.-HE3MSG HE4MSG: .ASCII @/TE ACTUALLY A TECO MACRO FILE@<12><15> .ASCII @/NT NOT A TECO MACRO FILE@ HE4LEN=.-HE4MSG .EVEN ; .END START