.TITLE KERFIL - KERMIT - FILE PROCESSING .SBTTL David Stevens, Stuart Hecht, Robert McQueen ; ; Kerfil is the file processing routine for Pro/Kermit ; ; Created on July 14,1983 ; ; Written by Stuart Hecht and David Stevens ; ; Version 1 ; .IDENT /1.0.09/ ; Directives .LIBRARY /KERMLB/ .LIBRARY /LB:[1,5]RMSMAC/ .ENABLE LC .NLIST BEX .SBTTL Revision History ;++ ; 1.0.00 By: Many On: Long time ; Create this module. ; ; 1.0.01 By: Nick Bush On: 15-Feb-1984 ; Fix FILE.OPEN to make sure it always returns an ; error when NEXT.FILE fails. KERMSG is not expecting ; a "no more files" return from FILE.OPEN. ; ; 1.0.02 By: Robert C. McQueen On: 16-Feb-1984 ; Add checks for exceeding the size of the output buffer ; for ASCII mode files. ; ; 1.0.03 By: David Stevens On: 21-Feb-1984 ; Make FILE.OPEN (send) usable in server mode,and have ; file.name contain the first file name before entering ; KERMSG. ; ; 1.0.04 By: Stuart Hecht On: 06-Mar-1984 ; Change default device from 'LB:' to 'SY:' so that ; PRO/Kermit can use a device other than the Library ; default. 'SY:' uses the device from the default directory. ; ; 1.0.05 By: Robert C. McQueen On: 6-March-1984 ; Restructure the sending of multiple files and use PJMPs when ; possible. ; ; 1.0.06 By: Robert C. McQueen On: 6-March-1984 ; Sending LSA files to the -10 do not work correctly. The ; problem is MOVBs extend the sign. Rework some code to ; not set the sign bit. ; ; 1.0.07 By: Robert C. McQueen On: 14-March-1984 ; Redo the inter task communication between KERMIT and KERFIL. ; ; 1.0.08 By: Robert C. McQueen On: 20-March-1984 ; Make M$RES global, so that we can use it from KERXFR. ; ; 1.0.09 By: Nick Bush On: 21-May-1984 ; Initialize FILSTA when file is opened for reading. ;-- .SBTTL Kermit symbol definitions ; ; THe following will cause the Pro/Kermit symbol definitions to be include ; in this module. ; .MCALL KERDEF ; Get the macro KERDEF ; Cause the symbols to be defined .MCALL CHRDEF ; Character definition macro CHRDEF ; Define the special characters .MCALL BITS ; Bit definitions BITS ; Define bit definitions .MCALL BLSRTN ; Allow use of BLISS macros from .MCALL BLSCAL ; library .MCALL PJMP ; Jump to subroutine that returns .SBTTL RMS-11 Directives and macros ;++ ; RMS-11 directives and macros ;++ ;+ ; RMS data strcutures ;- .MCALL FAB$B ; File attributes block .MCALL ORG$ ; Allowed organizations .MCALL NAM$B ; Name block .MCALL RAB$B ; Record attributes block ;+ ; RMS routines ;- .MCALL $CLOSE ; RMS routine to close a file .MCALL $CONNECT ; RMS routine to connect RAB/FAB .MCALL $CREATE ; Create a file .MCALL $DISCONNECT ; RMS routine to disconnect RAB/FAB .MCALL $ERASE ; RMS routine to delete a file .MCALL $GET ; RMS routine to get a record .MCALL $OPEN ; RMS routine to open a file .MCALL $PARSE ; RMS routine to parse wildcards .MCALL $PUT ; RMS routine to put a record .MCALL $READ ; RMS routine to read a block .MCALL $SEARCH ; RMS routine to search for a wild file .MCALL $WRITE ; RMS routine to write a block ;+ ; RMS data structure access macros ;- .MCALL $COMPARE .MCALL $FETCH .MCALL $OFF .MCALL $SET .MCALL $STORE .MCALL $TESTBITS ; ; RMS 11 data structure ; ORG$ SEQ ; $Open a sequential file .SBTTL Symbol definitions -- File types ;++ ; The following are the various file types that are supported by ; Pro/Kermit. These formats are used as offsets into tables to jump ; directly to the input routines associated with the various types. ;-- $TYCR =0*2 ; Carriage return RAT $TYFTN =1*2 ; Fortran RAT $TYPRN =2*2 ; Printer file RAT $TYNONE =3*2 ; No attribute file RAT .SBTTL Symbol definitions -- File reader states ;++ ; The file reader is a finite state machine. It will dispatch to various ; states depending on the type of record attributes (RAT) are dealing with ; and what the position is in the record we are dealing with. ;-- $REPR1 =0*2 ; Record pre processing state 1 $REPR2 =1*2 ; Record pre precessing state 2 $RERD =2*2 ; Record reading $REPS1 =3*2 ; Record post processing state 1 $REPS2 =4*2 ; Record post prrocessing state 2 ; NOTE: *2 so that we can use directly into a dispatch table. .SBTTL Data .PSECT $OWN$, D ; ; Data for Fab, Nam, & Rab blocks ; RESSTR: .BLKB 50. ; Block for the resultant string. STRBUF: .BLKB 128. ; Expanded string buffer for search. DEFALT: .ASCIZ 'SY:' ;[04] System default. DEFALN =.-DEFALT ; Size of the default device. .EVEN ;++ ; The following are used for reading character from the input file. ; These locations may be used by the print file, FORTRAN, or CRLF ; file record attribute routines. ;-- BYTCNT: .BLKW 1 ; Holds the byte counter for send. BYTOFS: .BLKW 1 ; Byte offset we are reading PRNCNT: .BLKW 1 ; Count of the number of LFs to output PSTPRN: .BLKW 1 ; Post print file byte CRFLG: .BLKW 1 ; Must put CR on at end of record FILSTA: .BLKW 1 ; Current state file reader is in ; ; Locations needed for sending of the next file ; SIZPOI: .blkw 1 ; Pointer to size of next filename. FILPOI: .blkw 1 ; Pointer to next filename. ; ; Flag for Send/Receive ; LSTFG: .BLKW 1 ; Last file flag. FORMAT: .BLKW 1 ; Format type for opened file. CRLF.FLG: .BLKW 1 ; Carriage return line feed flag. M$POS: .ASCIZ <.CHCSI>/23;1H/<.CHLF><.CHLF><.CHCSI>/23;1H/ M$RES:: .BYTE .CHLF,.CHCR .ASCII 'Please press RESUME to continue' .BYTE .CHCR,.CHNUL .EVEN .SBTTL FAB, NAM, and RAB blocks for send .PSECT $PLIT$, RO, D ; Pure copies of RMS blocks to be copied to impure data when needed PURFAB: FAB$B ; Beginning of FAB block. F$DNA DEFALT ; Address of default device. F$DNS DEFALN ; Default length field. F$NAM NAMBLK ; Chain to the NAM block F$LCH 1 ; Use the logical channel 1. FAB$E ; End of FAB block. FABLEN=.-PURFAB .EVEN PURNAM: NAM$B ; Beginning of NAM block. N$ESA STRBUF ; Address of the expanded string N$ESS 128. ; buffer and its length. N$RSA RESSTR ; Address of the resultant string N$RSS 50. ; buffer and its length. NAM$E ; End of NAM block. NAMLEN=.-PURNAM .EVEN PURRAB: RAB$B ; Beginning of RAB block. R$FAB FILFAB ; Chain to FAB block. R$MBC 2 ; Size of the multiblock count. R$RAC RB$SEQ ; Set the sequential access flag. RAB$E ; End RAB block. RABLEN=.-PURRAB .PSECT $OWN$, RW, D FILFAB:: FAB$B ; Beginning of FAB block. F$DNA DEFALT ; Address of default device. F$DNS DEFALN ; Default length field. F$NAM NAMBLK ; Chain to the NAM block F$LCH 1 ; Use the logical channel 1. FAB$E ; End of FAB block. .EVEN NAMBLK:: NAM$B ; Beginning of NAM block. N$ESA STRBUF ; Address of the expanded string N$ESS 128. ; buffer and its length. N$RSA RESSTR ; Address of the resultant string N$RSS 50. ; buffer and its length. NAM$E ; End of NAM block. .EVEN RABBLK:: RAB$B ; Beginning of RAB block. R$FAB FILFAB ; Chain to FAB block. R$MBC 2 ; Size of the multiblock count. R$RAC RB$SEQ ; Set the sequential access flag. RAB$E ; End RAB block. .SBTTL Send Routine ; ; The send routine takes a file from your directory and sends ; a copy of it to the host computer. ; ; SUBROUTINES: ; Open: Routine to open up a file. ; ; Send also updates the status board, by moving in information ; relative to the transfer. ; .PSECT $CODE$, RO X$SEND::CLR LSTFG ; Initialize the pointer CLR SIZPOI ; Reset size pointer. CLR FILPOI ; Reset filename pointer. JSR PC,SETNUL ; Call setnul subroutine. JSR PC,STARTRANS ; Set initial parameters. . . ; ; Put first file name into file.name. ; 4$: JSR PC,INFLNM ; Copy the first file name ; ; Enter KERMSG. ; JSR PC,SEND.SWITCH ; Go into Kermsg. PJMP DONETRANS ; Finished with transaction and return .SBTTL Receive ; ; This routine receives a file from the host kermit. ; ; .PSECT $CODE$, RO X$RECV::JSR PC,SWAPNM ; Put input file into File.name. JSR PC,STARTRANS ; Set initial parameters. . . BLSCAL REC.SWITCH ; Call the message processing JSR PC,DONETRANS ; Jump to trannsfer complete routine. RTS PC .sbttl File Open Routine: Send ; This routine Opens up a file for sending. ; The register R1 is used as a general purpose register for the ; system calls. A status check is made after opening to confirm a ; successful file opening. ; ; INPUT: The file name and the length of the filename. ; ; OUTPUT: The buffer containing the record. ; ; REGISTERS: ; R0 => Takes back a true or false value to Kermsg ; R1 => Pointer to the currently used control block. ; R2 => Register to carry value to clear buffer routine. ; .PSECT $CODE$, RO BLSRTN FILE.OPEN,2,SNRCFG ; Open a file routine. ;[03] ;[03] Initialize the RAV/FAB/NAM blocks for RMS from the prototypes ;[03] BLSCAL BL$MOV,<#FABLEN,#PURFAB,#FILFAB>,+ ;[03] Initialize the FAB BLSCAL BL$MOV,<#NAMLEN,#PURNAM,#NAMBLK>,+ ;[03] And the name block BLSCAL BL$MOV,<#RABLEN,#PURRAB,#RABBLK>,- ;[03] And the RAB CLR BYTCNT ; Clear the count of bytes read/writen TST SNRCFG(SP) ; Are we sending? BNE RCVOPN ; No, open for receiving ; ; Go to next.file routine and put parsed file name into file.name. ; JSR PC,PARSE ; Parse the file specification CMP #KNORMAL,R0 ; Get a good return? BNE 99$ ; Branch if not and return ; ; Now attempt to search for the first of the files ; MOV #FILFAB,R0 ; Get the FAB address $SET #FB$FID,FOP,R0 ; Set the wildcard flag $SEARCH #FILFAB ; Search for this file JSR PC,SENCHK ; Check for errors CMP #KNORMAL,R0 ; Get a good return? BNE 99$ ; Branch if an error and return CMP #NOMORFILES,R0 ; No more files? BNE OP1 ; No, skip this MOV #ER$FNF,R0 ; Get the error code back JSR PC,RMSERR ; Issue an RMS error MOV #RMS11,R0 ;[01] No, some type of error 99$: RTS PC ; Return to caller, with error. ; ; Here if we can really open the file for processing ; OP1: MOV #$REPR1,FILSTA ;[09] Start out in first prefix state MOV #FILFAB,R1 ; Put address of FAB into R1. CMP FILFLG,#MODBLK ; Are we in block transfer mode. BNE 5$ ; No, skip ; ; Set up for block reads ; $SET #FB$REA,FAC,R1 ; Otherwise set the block read in FAB. ; ; Now prepare to open the file. ; 5$: $SET #FB$FID,FOP,R1 ; Set up for wild card transfer. $STORE FILE.SIZE,FNS,R1 ; Store filename size in the FAB. $STORE #FILE.NAME,FNA,R1 ; Store filename in the FAB. $OPEN #FILFAB ; Open up file specified in the FAB. JSR PC,SENCHK ; Jump to status check routine. CMP #KNORMAL,R0 ; Did we get a good returned value ? BEQ 6$ ; Yes, branch to continue. RTS PC ; Return with error. ; ; If here we wish to have the file name cut up as determined by the ; fil.narmal.form field. ; 6$: JSR PC,FIXNAM ; Fix name to desired fashion. CMP #KNORMAL,R0 ; Did we get a good returned value ? BEQ 7$ ; Yes, branch to continue. RTS PC ; Return to caller with error. ; ; If here then we didn't get any screwy error in fixnam. ; 7$: CMP FILFLG,#MODBLK ; Are we in block mode ? BEQ 30$ ; Yes, branch. CMP FILFLG,#MODFIX ; Are we in fixed mode ? BEQ 30$ ; Yes, branch. ; ; Here if we have an ASCII or BINARY file. Determine which of the file ; processing routines are to be used. Store the converted RAT into FORMAT ; MOV #$TYNONE,FORMAT ; Assume NO ATTRIBUTE file MOV #FILFAB,R1 ; Store address of FAB in R1. $FETCH R0,RAT,R1 ; Get the record attributes BIC R0,#FB$BLK ; Clear the block bit ; ; Assume we have a NO ATTRIBUTE file, and check to see if right ; CMP R0,#FB$PRN ; Print file? BNE 10$ ; No, skip this MOV #$TYPRN,FORMAT ; Yes, set the print file format BR 30$ ; And skip other code ; ; Wasn't a PRINT file, so check FORTRAN ; 10$: CMP R0,#FB$FTN ; Fortran file? BNE 20$ ; No, skip this MOV #$TYFTN,FORMAT ; Yes, store the new format BR 30$ ; Branch. ; ; Wasn't a fortran file, so check CRLF ; 20$: CMP R0,#FB$CR ; Carriage return line feed file ? BNE 30$ ; No, branch. MOV #$TYCR,FORMAT ; Yes, set offset into FORMAT. ; ; We now have the format type, display the file name, and connect to the ; file. ; 30$: PJMP CONOPN ; Connect to the file and return .SBTTL File Open Routine: Receive ; ; Receive open creates the file that the remote Kermit is sending. ; If it can not create the file or connect to it it returns a false ; value to Kermsg. Before creating the file though it makes sure ; that the file name and type is compatible with the P/OS system ; by fixing the name to nine characters at most, and the type being ; three characters long. .PSECT $CODE$, RO RCVOPN: MOV #FILFAB,R1 ; Put address of Filfab into R1. $STORE #FILE.NAME,FNA,R1 ; Store the file name in the Fab. $STORE FILE.SIZE,FNS,R1 ; Store the name length in the Fab. $STORE #FB$VAR,RFM,R1 ; Variable length records ; ; Check to see if we are receiving an ascii file ; CMP FILFLG,#MODASC ; Are we receiving an ascii file. BNE 21$ ; No, then skip. $SET #FB$CR,RAT,R1 ; Set the record handling mask. ; ; Check to see if we are receiving a block file ; 21$: CMP FILFLG,#MODBLK ; Are we recieving a block file. BNE 22$ ; No, skip. $SET #FB$WRT,FAC,R1 ; Otherwise set the block write in FAB. $STORE #FB$VAR,RFM,R1 ; Fixed size records $STORE #8192.,MRS,R1 ; 8192 bytes per record ; ; See if we are doing a fixed length file. ; 22$: CMP FILFLG,#MODFIX ; Are we receiving in fixed mode ? BNE 25$ ; No, branch. $STORE #FB$FIX,RFM,R1 ; Set for fixed length records. $STORE #512.,MRS,R1 ; 512 bytes per record ; ; Create the file by the specifications given in the FAB ; 25$: $CREATE #FILFAB ; Create the new file. JSR PC,SENCHK ; Check the status return. CMP #KNORMAL,R0 ; Did we get a true return ? BEQ 30$ ; Yes, branch to connect to the file. RTS PC ; Return with error. ; ; If here then we must connect to the file ; 30$: PJMP CONOPN ; Connect to the file and return .SBTTL File Open Routine: Connect ; ; Conect connects to the open file, it does not care whether it was ; opened by send open or receive open. Conect will return a false ; value if it was unable to open the file. .PSECT $CODE$, RO CONOPN: MOV #RABBLK,R1 ; Put address of RAB into R1. $STORE #DSKBUF,UBF,R1 ; Put address of user buffer in RAB. $STORE #1400.,USZ,R1 ; Put size of user buffer into RAB. $SET #RB$SEQ,RAC,R1 ; Load RAC field of RAB. $CONNECT #RABBLK ; Connect to record. PJMP SENCHK ; Check status and return .SBTTL Next file routine ; ; This routine sets you up for the next file to be sent. ; ; INPUT: The block containing the file names, or a ; string to search for. ; ; OUTPUT: The next file to transfer or a return ; indicating no more files. ; ; REGISTERS: { The old values in the registers are saved } ; R0 => Takes back a true or false value to Kermsg ; R1 => Holds the address of the Rab. ; .PSECT $CODE$, RO BLSRTN NEXT.FILE,2, MOV #KNORMAL,R0 ; Assume this will work ; Search for parsed string 10$: MOV #FILFAB,R1 ; Put address of FAB into R1. $SET #FB$FID,FOP,R1 ; Set wildcard flag in FAB. $SEARCH #FILFAB ; Search for the file specified. JSR PC,SENCHK ; Check for an error in the parsing. CMP #KNORMAL,R0 ; Did we get a true return ? BEQ 20$ ; Yes, then branch. CMP #NOMORFILES,R0 ; No more files for this wild card? BNE 99$ ; Return if another type of error ; ; See if there is another file on the list of files to process. ; CMP LSTFG,NOCHOS ; See if it matches the number BNE 15$ ; chosen, if so then branch. MOV #NOMORFILES,R0 ; Put error message into R0. RTS PC ; Return to calling routine. ; ; Move the file specification to FILE.NAME and set up to process it ; 15$: JSR PC,INFLNM ; Go to increment file, & size routine. ; ; When we get here we may have an unparsed string. If we do then ; parse it. Then search for the file until we have no more then ; return the error NOMORFILES to kermsg. ; JSR PC,PARSE ; Parse for the search. CMP #KNORMAL,R0 ; Did we get a successful return. BNE 99$ ; No, return to caller with error. BR 10$ ; Loop for all files ; ; If here then we still have files. ; 20$: MOV #NAMBLK,R1 ; Put address of block into R1 $FETCH FILE.SIZE,RSL,R1 ; Get the length of the name. ; ; Open the file for reading now and then return to the caller ; JSR PC,OP1 ; Open the file. 99$: RTS PC ; Return to caller. .SBTTL Get File Routine ; ; This routine gets a record out of the open file, and then gets ; characters out of the record. ; ; INPUT: The currently open file, ; flag indicating an empty record, ; and where to put the character. ; ; OUTPUT: A character stored in the location ; specified by Kermsg. ; ; REGISTERS: { The old values are saved } ; R0 => Takes back a true or false value to Kermsg ; R1 => Holds the address of the Rab ; .PSECT $CODE$, RO BLSRTN GET.FILE,3, CMP FILFLG,#MODBLK ; Are we transfering a block file ? BEQ 5$ ; Yes we are, branch. CMP FILFLG,#MODFIX ; Are we transfering in fixed mode ? BNE 20$ ; No, branch ; If we get here then we are transfering in block or fixed mode. 5$: TST BYTCNT ; Do we need to get a buffer ? BNE 10$ ; No we do not, branch. JSR PC,GETBUF ; Jump to the get-buffer routine. CMP #KNORMAL,R0 ; Did we successfully get the buffer ? BNE 99$ ; No, return with the error ; We successfully got a buffer of data. 10$: JSR PC,GETCHR ; Get a character from the buffer. MOVB R1,@CHRADR(SP) ; Put that char. into the address MOV #KNORMAL,R0 ; specified, set up for a normal RTS PC ; return, and return to caller. ; ; If we get here then we are transfering in either ascii or binary mode. ; 20$: MOV FORMAT,R0 ; Put offset into R0. JSR PC,@RATDSP(R0) ; Jump to the specified routine. CMP #KNORMAL,R0 ; Did we get a successfull return ? BNE 99$ ; No, branch. MOVB R1,@CHRADR(SP) ; Put that char. into the address 99$: RTS PC ; return, and return to caller. ; ; Record attributes dispatch table. ; .PSECT $PLIT$, RO, D RATDSP: .WORD CRLF ; Dispatch to the input .WORD FORTRAN ; Dispatch to the FORTRAN input .WORD PRINT ; Dispatch to the print file input .WORD NONE ; Dispatch to no attribute routine. .sbttl Suport routines - GET.FILE - GETBUF - Get a buffer ;++ ; This routine will read the next buffer from the input file. It will ; return with the status in R0 to determine if it failed or succeeded. ; ; Usage: ; JSR PC,GETBUF ; (Return) ; ; On return: ; R0/ Kermit error code ; ;-- .PSECT $CODE$, RO GETBUF: MOV #RABBLK,R1 ; Put address of RAB into R1. CMP FILFLG,#MODBLK ; Are we transfering in block ? BEQ 10$ ; Yes we are, branch. ; If we are here then we want to do a $get. $GET #RABBLK ; Get the buffer of data. BR 20$ ; Branch to common code. ; If we are here then we want to do a $read. 10$: $STORE #512.,USZ,R1 ; Put size of user buffer into RAB. $READ #RABBLK ; Read in the buffer of data. ; The following code is used for both types of files. 20$: JSR PC,SENCHK ; Check for RMS-11 error. $FETCH BYTCNT,RSZ,R1 ; Get the byte-count from the RSZ field CLR BYTOFS ; Reset the byte-offset RTS PC ; Return to caller. .sbttl Support routine - GET.FILE - Getchr ;++ ; Getchr will return a value in R1. If there are no more words in ; the buffer it will return a -1, if there are still bytes to be ; transfered then it will put the next byte into R1. The bytcnt ; is a counter that is zero when all the bytes of the current record ; have been transfered. The bytofs points to the byte to be ; transfered and is incramented before returning to the caller. ;-- .PSECT $CODE$, RO GETCHR: TST BYTCNT ; Is the byte-count zero ? BNE 10$ ; No, we still have characters, branch. MOV #-1,R1 ; Put a -1 into R1. RTS PC ; Return to caller. ; ; If here then we still have characters to get. ; 10$: MOV BYTOFS,R0 ; Put byte-pointer into R0. CLR R1 ; Clear the register BISB DSKBUF(R0),R1 ; Mov the character into R1. DEC BYTCNT ; Decrament the byte-count. INC BYTOFS ; Move forward the byte-pointer. RTS PC ; Return to caller. ;++ ; This routine is called whenever one of the routines called by get.file ; return an error that is not RMS related. ; It returns to the message processor an internal error code that will ; shut down the file transfer. ;-- INTERR: MOV #INTERNALERR,R0 ; Put code for an internal error into RTS PC ; R0, and return to caller. .SBTTL Support routine - GET.FILE - CRLF file ;++ ; This routine is called to read a character from a normal file. ; This will return the character to be sent in R1 and the status of ; the fetch in R0. ; ; Usage: ; JSR PC,CRLF ; (Return) ; ; On return: ; R0/ Status (Kermit error status) ; R1/ Character ; ;-- .PSECT $CODE$, RO CRLF: MOV FILSTA,R0 ; Get the file reader state JMP @CRDSP(R0) ; Dispatch to the correct routine ;++ ; Pre processing state one ;-- CRPR1: JSR PC,GETBUF ; Get a record. CMP #KNORMAL,R0 ; Get it ok? BEQ 10$ ; Yes, branch. RTS PC ; Return to caller. ; ; Now just change state to record reading. ; 10$: MOV #$RERD,FILSTA ; Change file state to read. BR CRLF ; Branch back. ;++ ; Pre processing state two -- Internal error ;-- CRPR2= INTERR ; Internal error ;++ ; Record processing state - Return the record character to the caller ;-- CRREC: JSR PC,GETCHR ; Get a character TST R1 ; Fail? BGE 310$ ; No, got a character - branch MOV #$REPS1,FILSTA ; Change to post processing state->1. BR CRLF ; Try again from the top 310$: MOV #KNORMAL,R0 ; Return a good error code RTS PC ; Return to the caller ;++ ; First post processing state - Just append the CR to the information sent ;-- CRPS1: MOVB #.CHCR,R1 ; Store the carriage return MOV #$REPS2,FILSTA ; Change to the preprocessing routine MOV #KNORMAL,R0 ; Return normal RTS PC ; And return ;++ ; Post processing state 2 return a line-feed. ;-- CRPS2: MOVB #.CHLF,R1 ; Store a line feed in R1. MOV #$REPR1,FILSTA ; Change state to pre pros 1. MOV #KNORMAL,R0 ; Set up normal return. RTS PC ; Return to caller. ;++ ; The following is the dispatch table for the various states that we can be ; in reading the records. ;-- .PSECT $PLIT$, RO, D CRDSP: .WORD CRPR1 ; Preprocessing state one .WORD CRPR2 ; Preprocessing state two .WORD CRREC ; Record processing .WORD CRPS1 ; Postprocessing state one .WORD CRPS2 ; Postprocessing satte two .SBTTL Support routine - GET.FILE - PRINT file ;++ ; This routine will read character for a file with the PRN record attributes. ; It will return the characters to the caller in R1 and the status in R0. ; ; Usage: ; JSR PC,PRINT ; (Return) ; ; On return: ; R0/ Kermit status ; R1/ Character ; ;-- .PSECT $CODE$, RO PRINT: MOV FILSTA,R0 ; Get the file state JMP @PRNDSP(R0) ; Dispatch to the correct routine ;++ ; Preprocessing state one. This will read the print file carriage control ; information and change to state two to return the characters ;-- PRNPR1: JSR PC,GETBUF ; Get the next record CMP #KNORMAL,R0 ; Did we get it ok? BEQ 110$ ; Branch if we did RTS PC ; No, just pass back the error ; ; If here then we got no rms error. ; 110$: JSR PC,GETCHR ; Get the first character of the record TST R1 ; Did we get anything? BLT PRINT ; Try again if not MOV R1,R2 ; Move to a safer place JSR PC,GETCHR ; Get the second byte TST R1 ; Is this one really here? BLT PRINT ; No, try again, broken file MOV R1,PSTPRN ; Store for later BIC #B7,R2 ; Is this clear BEQ 120$ ; No, must be a character to output MOV R2,PRNCNT ; Store as the count MOV #$REPR2,FILSTA ; Set the new state BR PRINT ; Try again ; ; Here if we have a character that must be output. ; First try for a control character to be output ; 120$: MOV #$RERD,FILSTA ; Change state BIC #B6,R2 ; Is bit six on? BNE 130$ ; Branch if it was off BIC #B5,R2 ; Was bit 5 on? BEQ PRINT ; Yes, reserved code try again ADD #128.,R2 ; Offset to the correct place 130$: MOV R2,R1 ; Copy to the right place MOV #KNORMAL,R0 ; Give a good return RTS PC ; Return to the caller ;++ ; Preprocessing state two. This will return the lead in characters for the ; record. After this state is finished it will change to the record processing ; state. ;-- PRNPR2: TST PRNCNT ; Finished with the LFs? BEQ 210$ ; Branch if so MOVB #.CHLF,R1 ; Return a LF MOV #KNORMAL,R0 ; And a good return RTS PC ; Return to the caller ; ; Here if finished with the LFs. Just return a CR now and change the state ; reading the record ; 210$: MOV #$RERD,FILSTA ; Now reading the record MOVB #.CHCR,R1 ; Return the CR MOV #KNORMAL,R0 ; Return the code RTS PC ; Return to the caller ;++ ; Record processing state - This will return characters to the calling routine. ; from the record. When the characters are finished it will change to first ; post processing state. ;-- PRNREC: JSR PC,GETCHR ; Get a byte from the record TST R1 ; End of record? BGE 310$ ; Branch if not MOV #$REPS1,FILSTA ; Yes, set the post processing state BR PRINT ; And try from the top ; ; If here then we want to return the character. ; 310$: MOV #KNORMAL,R0 ; Give a normal return RTS PC ; And return to the caller ;++ ; Postprocessing state one. This will determine what type of carriage control ; must be placed on the end of the record. After it has determined the ; type it will dispatch to either the preprocessing or the other postprocessing ; routine. ;-- PRNPS1: MOV PSTPRN,R2 ; Get the postfix character BIC #B7,R2 ; Is this clear BEQ 410$ ; No, must be a character to output MOV R2,PRNCNT ; Store as the count MOV #$REPR2,FILSTA ; Set the new state BR PRINT ; Try again ; ; Here if we have a character that must be output. ; First try for a control character to be output ; 410$: MOV #$RERD,FILSTA ; Change state BIC #B6,R2 ; Is bit six on? BNE 420$ ; Branch if it was off BIC #B5,R2 ; Was bit 5 on? BEQ PRINT ; Yes, reserved code try again ADD #128.,R2 ; Offset to the correct place 420$: MOV R2,R1 ; Copy to the right place MOV #KNORMAL,R0 ; Give a good return RTS PC ; Return to the caller ;++ ; Postprocessing state two. This routine will return the characters that are ; to be output after the record. It will change to the first preprocessing ; routine after it has finished the returning of the characters. ;-- PRNPS2: TST PRNCNT ; Finished with the LFs? BEQ 510$ ; Branch if so MOVB #.CHLF,R1 ; Return a LF MOV #KNORMAL,R0 ; And a good return RTS PC ; Return to the caller ; ; Here if finished with the LFs. Just return a CR now and change the state ; reading the record ; 510$: MOV #$REPR1,FILSTA ; Now reading the record MOVB #.CHCR,R1 ; Return the CR MOV #KNORMAL,R0 ; Return the code RTS PC ; Return to the caller ;++ ; Print file dispatch table. ;-- .PSECT $PLIT$, RO, D PRNDSP: .WORD PRNPR1 ; First preprocessing routine .WORD PRNPR2 ; Second preprocessing routine .WORD PRNREC ; Record processing routine .WORD PRNPS1 ; First postprocessing routine .WORD PRNPS2 ; Second postprocessing rouine .sbttl Support routine - GET.FILE - FORTRAN file ;++ ; This routine is called to read a character from a FORTRAN file. The ; file contains the leading character followed by the record. The leading ; character must be converted to a normal ASCII character for processing. ; ; Usage: ; JSR PC,FORTRAN ; (Return) ; ; On return: ; R0/ Status ; R1/ Character if any ;-- .PSECT $CODE$, RO FORTRAN:MOV FILSTA,R0 ; Get the current state JMP @FTNDSP(R0) ; Dispatch to the correct routine ;++ ; Pre processing routine 1. ;-- FTNPR1: MOV #TRUE,CRFLG ; Set the flag JSR PC,GETBUF ; Get the next record CMP #KNORMAL,R0 ; Did we get it ok? BEQ 110$ ; Branch if we did RTS PC ; No, just pass back the error ; ; If here then we got no rms error. ; 110$: JSR PC,GETCHR ; Get the first character of the record TST R1 ; Is this the end of line already? BGE 120$ ; No, Check the first character BR FORTRAN ; Try again from the top ; ; If we get here then we want to check the first byte. ; ; ; Check for "null" format type. ; 120$: TST R1 ; Is this a null byte? BNE 130$ ; No, check for other characters CLR CRFLG ; Yes, clear output a CR flag. 125$: MOV #$RERD,FILSTA ; Set new state to read the record BR FORTRAN ; And try again from the top ; ; Check for "0" format type. ; 130$: CMPB DSKBUF,#'0 ; Is this a "0"? BNE 140$ ; Branch if not MOV #$REPR2,FILSTA ; Set to preprocessing state-> 2. BR 170$ ; Join common code to return LF ; ; Check for "1" format type. ; 140$: CMPB DSKBUF,#'1 ; Is this a "1"? BNE 150$ ; Branch if not MOVB #.CHFF,R1 ; It is, so return FF CR MOV #$RERD,FILSTA ; Set state to read the record next RTS PC ; Return to the caller ; ; Check for "+" format type. ; 150$: CMPB DSKBUF,#'+ ; Is this a "+"? BNE 160$ ; Branch if not BR 125$ ; Join the common code ; ; Check for "$" format type. ; 160$: CMPB DSKBUF,#'$ ; Is this a "$"? BNE 170$ ; Branch if not CLR CRFLG ; Clear flag noting CR needed ; ; All other characters default to this. ; 170$: MOVB #.CHLF,R1 ; Return a LF MOV #$RERD,FILSTA ; Set the new state RTS PC ; Return to the caller ;++ ; Pre-processing routine 2. ;__ FTNPR2= 170$ ; Same, just return LF and change ; states ;++ ; Record reading routine. ;-- FTNREC: JSR PC,GETCHR ; Get a byte from the record TST R1 ; End of record? BGE 310$ ; Branch if not MOV #$REPS1,FILSTA ; Yes, set the post processing state BR FORTRAN ; And try from the top ; ; If here then we want to return the character. ; 310$: MOV #KNORMAL,R0 ; Give a normal return RTS PC ; And return to the caller ;++ ; Post processing routine 1. ;-- FTNPS1: MOV #$REPR1,FILSTA ; Set the to preprocessing routine TST CRFLG ; Need to output the CR? BEQ FORTRAN ; Branch if not MOVB #.CHCR,R1 ; Return the CR MOV #KNORMAL,R0 ; Give a normal return RTS PC ; Return to the caller ;++ ; Post processing routine 2. INTERNAL ERROR if we get here ;-- FTNPS2= INTERR ;++ ; The following is the FORTRAN dispatch table. This table is used to ; dispatch to the correct routine depending on the state of the character ; reader. ;-- .PSECT $PLIT$, RO, D FTNDSP: .WORD FTNPR1 ; Pre processing state 1 .WORD FTNPR2 ; Pre processing state 2 .WORD FTNREC ; Record processing state .WORD FTNPS1 ; Post processing state 1 .WORD FTNPS2 ; Post processing state 2 .SBTTL Support routine - GET.FILE - No attribute file ;++ ; This file processing mode is used when the file to be sent has no ; record attributes. It will get a buffer when the bytecount is zero ; and transfer over every byte in the record. ; ; ; Usage: ; JSR PC,@RATDSP(R0) ; (return) ; (R0 must have the offset value) ; ;-- .PSECT $CODE$, RO NONE: TST BYTCNT ; Is the byte-count zero ? BNE 10$ ; No, go get characters. JSR PC,GETBUF ; Yes, go get a buffer. CMP #KNORMAL,R0 ; Did we get a normal return ? BNE 99$ ; No, return with error. ; ; If here then we want to get characters. ; 10$: JSR PC,GETCHR ; Go get a character. MOV #KNORMAL,R0 ; Set up normal return. 99$: RTS PC ; Return to caller. .SBTTL Bliss interface -- PUT.FILE - Write a character ;++ ; This routine will write a character into the output file. It will then ; return to the calling routine. ; ; Usage: ; BLISS: ; Status = PUT.FILE(.CHARACTER); ; ;-- .PSECT $CODE$, RO BLSRTN PUT.FILE,2, MOV CHARACTER(SP),R1 ; Get the character ; ; First determine the type of output we are doing. ; CMP FILFLG,#MODBLK ; Are we doing block mode? BNE 10$ ; No, skip this JSR PC,PUTCHR ; Output the character CMP #512.,BYTCNT ; Buffer full now? BNE 30$ ; No, just give a good return BR 40$ ; Yes, dump the buffer and get out ; ; Here if we are not processing a Block file. ; 10$: CMP FILFLG,#MODASC ; Doing an ASCII file? BNE 35$ ; No, just output the byte ; ; Here if we are doing an ASCII file, must check for end of record ; characters ; CMPB #.CHCRT,R1 ; Is this a carriage return. BNE 15$ ; No, branch. MOV #TRUE,CRLF.FLG ; Set on the flag. BR 30$ ; Branch. ; ; Here if it wasn't a . ; 15$: TST CRLF.FLG ; Is the carraige return flag set ? BEQ 20$ ; No, branch. ; ; Here if a carriage return was the previous character. ; CMPB #.CHLFD,R1 ; Is this a line feed? BEQ 40$ ; Yes, branch. ; ; Here if we got a carriage return and no line feed. ; CMP #512.,BYTCNT ;[02] Buffer full now? BEQ 98$ ;[02] Return record too big error MOV R1,-(SP) ; Save the current byte. MOVB #.CHCRT,R1 ; Put a in R1. JSR PC,PUTCHR ; Put it into the buffer. MOV (SP)+,R1 ; Restore the current byte CLR CRLF.FLG ; Reset the flag. ; ; Here to just store the byte and return to the caller ; 20$: CMP #512.,BYTCNT ;[02] Buffer full now? BEQ 98$ ;[02] Return record too bit JSR PC,PUTCHR ; Output the character 30$: MOV #KNORMAL,R0 ; Give a normal return RTS PC ; Return to the caller ; ; Here if you are playing with a BINARY or FIXED file. Put in the character ; if your buffer has 512. bytes in it dump it else return. ; 35$: JSR PC,PUTCHR ; Output the character. CMP #512.,BYTCNT ; Do we have 510 characters ? BEQ 40$ ; Yes, branch to dump the file. MOV #KNORMAL,R0 ; Give a normal return. RTS PC ; Return to caller. ; ; Here to dump the buffer and return to the caller ; 40$: JSR PC,BUFDMP ; Output the buffer CLR CRLF.FLG ; Reset the flag. RTS PC ; Return to the caller ;[02] ;[02] Here when the record is filled and we must dump the buffer. ;[02] 98$: MOV #REC.TOO.BIG,R0 ;[02] Store the error code RTS PC ;[02] Return to the caller .SBTTL Support -- BUFDMP - Dump the current buffers ;++ ; This routine will dump what is in the current buffers. It will then return ; to the caller. First checks will be done to determine if there is anything ; to dump in the first place. ; ; Usage: ; ; JSR PC,BUFDMP ; Output the buffer ; (Return) ; ; Returns with: ; R0/ Error code if any ;-- .PSECT $CODE$, RO BUFDMP: MOV #RABBLK,R1 ; Put address of RAB into R1. $STORE #DSKBUF,RBF,R1 ; Store address of record buffer. CMP FILFLG,#MODBLK ; Block mode? BEQ 10$ ; Yes, output the full block ; ; Here to write a record for an ASCII file or a block mode file ; MOV BYTCNT,R0 ; Get byte count CMP FILFLG,#MODFIX ; Fixed length records? BNE 5$ ; No, go store length MOV #512.,R0 ; Yes, get length 5$: $STORE R0,RSZ,R1 ; Put its size into the RAB. $PUT #RABBLK ; Output the record BR 20$ ; Finish up ; ; Here to write a dump mode block to the disk ; 10$: $STORE #512.,RSZ,R1 ; Store the block size $WRITE #RABBLK ; Write out the buffer into the file. ; ; Determine if we got any errors. If so pass them back to the calling routine ; Also inform the remote if it is something bad. ; 20$: JSR PC,SENCHK ; Check for any errors. CLR BYTCNT ; Clear the byte count RTS PC ; Return to caller. .SBTTL Support -- PUTCHR - Put a character into the output buffer ;++ ; This routine will store a byte into the output buffer that is being built. ; It will then return to the caller after the byte count and the character ; has been stored. ; ; Usage: ; MOV #Character,R1 ; JSR PC,PUTCHR ; (Return) ; ; On return: ; Character stored. ; ;-- .PSECT $CODE$, RO PUTCHR: MOV BYTCNT,R0 ; Put byte count into R2. MOVB R1,DSKBUF(R0) ; Move the character into the byte at INC BYTCNT ; R2, and increment the byte pointer RTS PC .SBTTL File closing routine ;++ ; This routine will close the file for KERMSG. It assumes that the file has ; been opened (KERMSG will insure this). The routine may or may not delete ; the file depending on the value of the argument. ; ; Usage BLISS: ; ; Status = FILE_CLOSE (Flag); ; ;-- .PSECT $CODE$, RO BLSRTN FILE.CLOSE,2, ; Close file routine. TST BYTCNT ; Get the byte count BEQ 10$ ; Skip if nothing in the buffer JSR PC,BUFDMP ; Dump anything in the buffers ; ; Disconnect the file from processing ; 10$: MOV #RABBLK,R1 ; Put address of RAB into R1. $DISCONNECT #RABBLK ; Disconnect from file. ; ; Close the open file ; MOV #FILFAB,R1 ; Put address of FAB into R1 $OFF #FB$REA,FAC,R1 ; Turn off fac field in FAB. $OFF #FB$WRT,FAC,R1 ; Turn off fac field in FAB. $CLOSE #FILFAB ; Close the file specified in the FAB. ; ; See if we wish to close with delete ; BIT DELFLG(SP),#TRUE ; Do we want to close with delete ? BEQ 90$ ; No, we do not so branch. MOV #FILFAB,R1 ; Put address of FAB into R1. $TESTBITS #FB$FID,FOP,R1 ; Open by file-id? BNE 90$ ; Yes, we don't really want to delete it $ERASE R1 ; Delete the file 90$: MOV #KNORMAL,R0 ; Set up success code in R0. RTS PC ; Return to Kermsg. .sbttl Parser for File.open ; ; Parse the filename for wildcard searches ; ; INPUT: The name string located in file.n ; and its length in file.s. ; ; OUTPUT: The fields required by $Search are initialized ; and a match string is build. ; ; REGISTERS: ; R1 => Pointer to the FAB block. ; .PSECT $CODE$, RO PARSE: BLSCAL BL$MOV,<#FABLEN,#PURFAB,#FILFAB> ; Initialize the FAB BLSCAL BL$MOV,<#NAMLEN,#PURNAM,#NAMBLK> ; And the name block BLSCAL BL$MOV,<#RABLEN,#PURRAB,#RABBLK> ; And the RAB MOV #FILFAB,R1 ; Put address of FAB into R1. $STORE FILE.SIZE,FNS,R1 ; Store filename size in the FAB. $STORE #FILE.NAME,FNA,R1 ; Store filename in the FAB. $SET #FB$FID,FOP,R1 ; Set flag in Fop field of FILFAB. $PARSE #FILFAB ; Parse the file string. PJMP SENCHK ; Check for errors and return to caller .SBTTL Startup routine for file transfers .PSECT $CODE$, RO STARTRANS:: JSR PC,INIKEY ; Initialize key routines JSR PC,XK.INT ; Initialize the XK port ;** PUT ERROR CHECK IN HERE ** RTS PC ; Return to sender .sbttl Reset routine when file transfer is complete .PSECT $CODE$, RO DONETRANS: BLSCAL TT.TEXT,#M$POS,+ ; Position the cursor MOV #SUCC$L,R1 ; Get the successful message and length MOV #M$SUCC,R2 ; BIT #TRUE,R0 ; See if transfer was successful BNE DONEOK ; If OK then branch MOV #ABOR$L,R1 ; Bad transfer so get the aborted MOV #M$ABOR,R2 ; message and length DONEOK: JSR PC,KILKEY ; Kill off any pending QIO BLSCAL TT.TEXT,R2,+ ; Ouput the correct transfer done BLSCAL TT.TEXT,#M$RES,+ ; messages BLSCAL TT.OUTPUT,,- ; BIT #TRUE,NOSCRN ; Check to see if we are watching BNE 99$ ; transfer, If not then branch CALL WTRES ; Do a regular wait for resume 20$: JSR PC,S$RXFR ; Reset screen transfer info 99$: JSR PC,XK.SHT ; Close the XK port and reset parms RTS PC ; Return to caller .sbttl Name Fixing Routine for $Search ; ; This routine fixes the name string built by search by removing old ; characters that were left from the previous file name. ; ; INPUT: The size of the new file name ; and pointer to the bytes of the name. ; ; OUTPUT: The file name written as specified by the ; fil.normal.form flag. ; ; REGISTERS: { No registers are permanently smashed } ; ; R0 => Holds the address of the file.name block. ; R1 => Holds the address of the resultant string block. ; R2 => Holds the counter for the length of the new ; file name. ; .PSECT $CODE$, RO FIXNAM: JSR R1,$SAVE3 ; Save registers one thru three. ; ; Set up R2 as the counter, put the address of the file name into R3, ; put the address of the resultant string into R1. ; Decide if we wish to remove any thing off the dame build by the resultant ; string. ; MOV FILE.SIZE,R2 ; Set up R2 to contain the max length. MOV #FILE.NAME,R3 ; Put the destination into R3. MOV #RESSTR,R1 ; Put address of source into R1. CMP FIL.NORMAL.FORM,#FNM.FULL ; Do we want anything cut off ? BNE 10$ ; Yes we do, branch. ; ; If here then we want the entire name used. ; 5$: MOVB (R1)+,(R3)+ ; Move the string. BEQ 99$ ; Branch if the moved byte was a null. SOB R2,5$ ; Subtract one and branch if not zero. BR 30$ ; Branch due to error. ; ; If here then we want only the " NAME.EXT", or "NAME.EXT;ver" ; 10$: CMPB (R1)+,#'] ; Incrament the pointer until the byte BNE 10$ ; pointed to is a "]". ; ; When here it means we are at the beginning of the name. ; 20$: CMP FIL.NORMAL.FORM,#FNM.UNTRAN ; Want to keep version number? BEQ 25$ ; Yes, skip check CMPB (R1),#'; ; Is the next byte a ";". BEQ 99$ ; Yes, branch we don't want version #'s 25$: MOVB (R1)+,(R3)+ ; Move in the file-name and extension. BEQ 99$ ; Return if done SOB R2,20$ ; Sub one and branch if result isn't 0. ; ; If we are here then there is a problem, return an internal error code ; to the calling routine. ; 30$: MOV #INTERR,R0 ; Return error code in R0. RTS PC ; Return to caller. ; ; When here it means the name is moved into the file.name field, put its ; length into file.size. Then restore the smashed registers. ; 99$: SUB R2,FILE.SIZE ; Find size of string, put it in file.s MOV #KNORMAL,R0 ; Set up normal return. RTS PC ; Return to caller. .sbttl Set Null Routines ; Sets a null after the end of each file name in file.n. ; ; INPUT: ; The only input required is the buffer address, ; and the offset. ; ; OUTPUT: ; The output is the old buffer with the nulls inserted. ; ; REGISTERS: ; R2 => Carries down the offset value. ; R3 => Brings down the address of the buffer. .PSECT $CODE$, RO SETNUL: JSR R1,$SAVE3 ; Save registers one thru three. MOV NOCHOS,R1 ; Get the number choosen MOV #FSIZE,R2 ; Put the address of the lengths in R2. MOV #FILES,R3 ; Put address of buffer into R3. ; ; At this point you wish to move to the end of the file name pointed to ; by R3 and set a null byte after it. ; 10$: ADD (R2),R3 ; Add contents of R2 to the address ; located in R3. MOVB #.CHNUL,(R3) ; Set a null byte. ; ; At this point you want to move on to the next file name. To do that you ; must go back to the beginning of the current file name, and then incrament ; to the next file name. Then you incrament the pointer in R2 to point to ; the length of this new file name. ; SUB (R2),R3 ; Subtract the value at R2 from R5. ADD #50.,R3 ; Add 50 to whats at R3. ADD #2,R2 ; Increment to the next size. SOB R1,10$ ; Loop for all files choosen ; ; When we get here we have set a null byte after each file name ; RTS PC ; Return to caller. .SBTTL Increment to Next File Routine ;++ ; This routine sets up for the next file to be transfered by ; moving the file name to front of the buffer, and the length ; of the name to the beginning of its block. ; ; INPUT: File.n contains the filename to be moved, filpoi ; contains the pointer to the file name. ; File.s contains the file name length to be moved, ; sizpoi contains the pointer to that length. ; ; OUTPUT: Name of the next file is at beginning of File.n, and ; the corresponding length is in the beginning of its ; block. ; ; REGISTERS: ; R2 => Holds address of old locations. ; R1 => Holds address of target location. ; .PSECT $CODE$, RO INFLNM: JSR R1,$SAVE2 ; Save R1 to R2. ; ; This part will move the file size of the current file from fsize to ; file.size. ; MOV #FSIZE,R2 ; Put address of size into R2. ADD SIZPOI,R2 ; Move pointer in R2 MOV (R2),FILE.SIZE ; Move size of current filname into ; file.s location. ; ; Here we initialize the pointer to point at the current file. ; MOV #FILES,R2 ; Put address of source into R2. ADD FILPOI,R2 ; Move pointer in R2. MOV #FILE.NAME,R1 ; Put address of destination into R1. ; ; This loop will move the file from files to file.name, exiting the loop ; when it moves over a null byte. ; 80$: MOVB (R2),(R1)+ ; Move the byte in R2 into R1. TSTB (R2)+ ; Was the source byte a "null" ? BNE 80$ ; No , continue the loop. ; ; When we get here we want to set the pointers for the next file, then ; return to the calling routine. ; ADD #2,SIZPOI ; Add 2 to filename size pointer. ADD #50.,FILPOI ; Add 50 to filename pointer. INC LSTFG ; Increment the last file flag. RTS PC ; Yes, return to caller. .SBTTL Swap Name Routine ; This routine moves the name from a source buffer to ; a destination buffer ; ; INPUT: The file name in the source buffer. ; ; OUTPUT: The file name in the destination buffer. ; ; REGISTERS: ; R1 => Counter of the length of the name ; R2 => Holds address of source buffer ; R3 => holds address of destination buffer ; ; SWAPNM - Requires no input, moves data from rcvbuf to file.name. ; .PSECT $CODE$, RO SWAPNM: MOV #RCVBUF,R2 ; Put address of source buffer into R2. MOV #FILE.NAME,R3 ; Put address of destination into R5. CLR FILE.SIZE ; Clear the counter. ; ; This loop does the file movement. It will exit the loop if it moves ; either an escape or a null. Until then it moves the contents of the ; source file in R2 into file.name. ; 10$: CMPB (R2),#.CHESC ; Is the byte an escape ? BEQ 99$ ; Yes then we are done. MOVB (R2)+,(R3)+ ; Move byte from source to destination. BEQ 99$ ; Leave the routine if null INC FILE.SIZE ; Increment R1. BR 10$ ; Branch back. ; ; Return to the caller ; 99$: RTS PC ; Return to caller. .SBTTL Status Error Check ; ; Senchk checks the status return of the RMS calls. ; ; It first checks to see if it was successful,and ; then if unsuccessful it sees if the error was ; due to an EOF. ; ; REGISTERS: ; R1 => pointer to either RAB block or FAB block. ; .PSECT $CODE$, RO SENCHK: $FETCH R0,STS,R1 ; Get the status and put it in R0. TST R0 ; Test the status code for success. BMI 20$ ; If negative then branch. MOV #KNORMAL,R0 ; Set up a successful return code. RTS PC ; Return to caller ;++ ; If here the we are checking for errors ;-- ; ; Check for end of file ; 20$: CMP #ER$EOF,R0 ; Check for EOF BNE 40$ ; If no then skip. MOV #EOF,R0 ; Set up false return flag RTS PC ; Return to caller ; ; If here check for no more files ; 40$: CMP #ER$NMF,R0 ; Is error due to no more files. BNE 50$ ; If no then branch. MOV #NOMORFILES,R0 ; Set up false return flag. RTS PC ; Return to caller ; ; If here check for record to big ; 50$: CMP #ER$RTB,R0 ; Was the record too big ? BNE 60$ ; No branch. MOV #REC.TOO.BIG.,R0 ; Set up false return RTS PC ; Return to the caller ; ; If here call error routine and return an RMS error ; 60$: JSR PC,RMSERR ; Jump to error output routine. MOV #RMS11,R0 ; Set up false retrn flag. RTS PC ; Return to calling routine. .SBTTL End of KERFIL.MAC .END