.TITLE CATCH - Catch and file data .IDENT /1.2/ .ENABL LC .NLIST BEX ;--------------------------------------------------------------------------- ; ; CATCH is a program that allows the user to communicate with ; RSX, catching all input from TI: and filing it. ; ; Version 1.0 h gregg august 1982 ; Initial hack. ; ; Version 1.1 h gregg december 1983 ; Made a seperate QIO for each of the reads, so status ; would be properly returned. ; ; Version 1.2 h gregg march 1984 ; Try multi-buffering on output file. To do this, the ; program must be linked to the FCSMBF files (see the ; IO operations guide manual, in an appendix). ; Also, remove leading 's from a record. ; ; ;--------------------------------------------------------------------------- ; ; ; Program internals: ; ; Logical unit assignments: ; ; 1 user's terminal, command terminal ; 2 receive file LUN ; ; Event flag structure: ; ; 1-n flag that buffer n is full ; 21 user's terminal output (CATCH's messages) ; 22 flag for file I/O ; ; The receive file name is user specified. The receive file ; is set as a 'normal' text file with variable length records and ; no funky FORTRAN characters. ; ;-------------------------------------------------------------------------- ; ; ; The number and size of the buffers used must be specified below. ; Due to the way I am using the WTLO$ directive and a macro to make ; the event flag mask, a maxumum of 15 buffers can be specified. ; NUMBUF = 8. ; must be less than 16. BUFSIZ = 136. ; ; MACRO definitions ; .MCALL QIOW$S,CLEF$S,EXIT$S,WTLO$S .MCALL FCSMC$,CSI$,CSI$1,CSI$2,DIR$,QIO$,QIOW$ ; .MACRO PRINT,STRING,?TEMP1,?TEMP2 .NCHR LENGTH, ; get how long it is MOV #TEMP1,PRNT+Q.IOPL ; put buffer in place MOV #LENGTH+4,PRNT+Q.IOPL+2 ; stuff len + extra in place DIR$ #KILL ; first, kill any outstanding I/O DIR$ #PRNT ; do it BR TEMP2 ; branch about the ascii TEMP1: .ASCII @STRING@ .EVEN TEMP2: .ENDM ; .MACRO REPEAT MACRO ARG .NARG NARG ; see how many arguments we have I = 1 ; start with buffer number 1 .REPT NUMBUF ; go thru all buffers .IF EQ NARG - 1 ; if we have one argument ... MACRO \I ; .IFF ; if we have two arguments ... MACRO \I,ARG ; .ENDC ; now for both cases again I = I + 1 ; move on to the next buffer .ENDR .ENDM ; .MACRO REQUEST N ; make the read req, and buffers READ'N: QIO$ IO.RVB,1,'N,,IOSB'N,, ; the read request IOSB'N: .BLKW 2 ; the status block for the read BUFR'N: .BLKB BUFSIZ ; the input buffer .ENDM ; .MACRO POINTR N NAME ; create one entry in a pointer table .WORD NAME'N ; this is the entry .ENDM ; .MACRO MASK ; create the event flag mask EFMASK = 2 ; start here .REPT NUMBUF - 1 ; and count one less EFMASK = EFMASK * 2 ; 2^n - 1 .ENDR ; EFMASK = EFMASK - 1 ; .ENDM .PSECT DATA ; ; Directives, buffers and pointers ; KILL: QIOW$ IO.KIL,1,21 ; kill outstanding I/O PRNT: QIOW$ IO.WVB,1,21,,,,<,,0> ; print a message to the user NEXTRD: .WORD 1 ; this should be the next one in IOSB: .BLKW 2 ; status block for prompt REPEAT REQUEST ; make all the QIO's, IOSB's and buffers PREAD: REPEAT POINTR READ ; pointers to the read requests PIOSB: REPEAT POINTR IOSB ; pointers to the IO status blocks PBUFR: REPEAT POINTR BUFR ; pointers to the buffers ; FCSMC$ ; define FCS macros FSRSZ$ 2 ; initialize FCS record buffer CSI$ ; define CSI control block .PSECT DATA ; get back to our own PSECT ; RCVFDB: FDBDF$ ; for file to receive FDBF$A 22,,2 ; use event flag 22 for the file,buffer FDAT$A R.VAR,FD.CR,,-5,-5 ; set carraige control atributes FDOP$A 2,RCVCSI+C.DSDS,,FO.WRT,FA.DLK ; loon 2,CSI + default RCVNAM: .BLKB 30. ; buffer for filename input RCVCSI: .BLKB C.SIZE ; CSI's buffer ; LF = 12 CR = 15 .PSECT CATCH CATCH:: QIOW$S #IO.ATA!TF.XCC,#1,#21,,,,<#AST> ; attach the terminal ; ; get file name, parse it, open output file ; QIOW$S #IO.RPR,#1,#21,,#IOSB,,<#RCVNAM,#30.,#6,#20$,#30$-20$,#0> CSI$1 #RCVCSI,#RCVNAM,IOSB+2 ; compress the line BCS 10$ ; error - go tell us CSI$2 #RCVCSI,OUTPUT ; set up for the open BCS 10$ ; error - go tell us OPEN$W #RCVFDB ; and open the file BCC 40$ ; no problem, continue ; error opening file -- say so and leave 10$: PRINT JMP EXIT ; file name query message 20$: .ASCII /File to catch: / 30$: .EVEN ; ; tell us we're ready, then get ready ; 40$: PRINT CLR R1 ; get clean for the start ; 50$: INC R1 ; get a buffer number CMP #NUMBUF,R1 ; done? BLT WAIT ; yup - go wait for input CALL QUEUE ; and queue up the request BR 50$ ; and do all the buffers ; ; Subroutine QUEUE. R0 = scratch, R1=buffer number to queue ; QUEUE: MOV R1,R0 ; make a working copy of the variable DEC R0 ; start at zero ASL R0 ; make it a word offset MOV PREAD(R0),R0 ; get the base of the request DIR$ R0,10$ ; and issue the read RETURN 10$: PRINT JMP EXIT ; ; now we wait for a complete line ; MASK ; make the event flag mask WAIT: WTLO$S 0,#EFMASK ; wait for flags MOV NEXTRD,R1 ; get the number of the input buffer MOV R1,R2 ; and get a temp version of it DEC R2 ; start numbering at zero ASL R2 ; and make it a word offset MOV PIOSB(R2),R3 ; R3 ==> I/O status block and buffer MOV (R3),R4 ; R4 = 1st word of I/O status block CMPB #IS.SUC,R4 ; all perfect? BEQ 30$ ; yup - go write it out CMPB #IE.EOF,R4 ; end of the file? BEQ 10$ ; yup - tell us PRINT ; tell us of problems BR 20$ ; and leave 10$: PRINT ; we must be all done 20$: BR EXIT ; and leave this place ; ; this is where we write the record out ; 30$: MOV 2(R3),R4 ; R4 = length MOV PBUFR(R2),R3 ; R3 ==> buffer 40$: CMPB #12,(R3) ; is the first character a line feed? BNE 50$ ; nope - write it out INC R3 ; increment past it DEC R4 ; and lower the counter BEQ 60$ ; if zero - don't write anything out BR 40$ ; go check again 50$: PUT$ #RCVFDB,R3,R4,80$ ; put the record 60$: CALL QUEUE ; and queue up thie record again INC R1 ; move on to the next record CMP #NUMBUF,R1 ; past the end? BGE 70$ ; not this time MOV #1,R1 ; past the end, wrap around 70$: MOV R1,NEXTRD ; set the next buffer to read flag BR WAIT ; time now to circle around 80$: PRINT ; ; Asked to leave - bag outstanding I/O, release things ; EXIT: CLOSE$ #RCVFDB ; close the file DIR$ #KILL ; kill any I/O QIOW$S #IO.DET,#1,#21 ; and free us EXIT$S ; and get out of here ; ; If we get here, we've had an AST and thats trouble ; AST: PRINT BR EXIT ; kludge way to exit an AST, but it works .END CATCH