.MCALL .MODULE .MODULE TRANSF,VERSION=19,COMMENT=,AUDIT=YES ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only with the ; inclusion of the above copyright notice. This software, or ; any other copies thereof, may not be provided or otherwise ; made available to any other person except for use on such ; system and to one who agrees to these license terms. Title ; to and ownership of the software shall at all times remain ; in Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. .SBTTL ABSTRACT .ENABL LC ;+ ; ; The purpose of this program is to provide the host end of a ; file transfer utility using VTCOM/XL. It is designed so that ; it may be used under RT-11 or the RT EMulator. ; ; Assembly procedure: ; .R MACRO ; *TRANSF=TRANSF ; *^C ; .R LINK ; *TRANSF=TRANSF ; *^C ; ; Things yet to do: ; ----------------- ; ;* 1) Restructure ;* 2) GETFIL -> GETIF and GETOF ;* 3) save/set tty characteristics ; a) xon/xoff for input ;* b) lower case ;* c) special mode ;* d) inhibit i/o wait ;* 4) restore tty characteristics ;* 5) timout routine (15 seconds?) ;* 6) don't forget .FETCH/.RELEA ;* 7) actual transfer ;* a) from host ;* b) to host ;* 8) ^C trapping ;* 9) Remove SET TT NOCRLF requirement ; ;- .SBTTL EDIT HISTORY ; X01 (000) 17-Oct-82 Host to remote transfer complete. ; ; X01 (001) 18-Oct-82 GETMSG was stacking R1-R3 each time an ; invalid message prefix was received. It ; was also trapping if no text was received ; between the APC and the ST. ; ; X01 (002) 18-Oct-82 Remote to host transfer complete. ; ; X01 (003) 18-Oct-82 Code clean-up. ; ; X01 (004) 19-Oct-82 Altered protocol flow if errors occur during ; transfer either direction. ; ; X01 (005) 20-Oct-82 Moved .SCCA into SETTTY/RESTTY routines. Also ; added support for ^C abort of file transfers. ; ; X01 (006) 25-Oct-82 Removed incorrectly working ^C abort routine. ; ; X01 (007) 24-Feb-83 Added .{N}LIST BEX to ERROR. macro to inhibit ; text expansion for listing. Also corrected ; some incorrect comments. ; ; X01 (008) 21-Mar-83 Force 'SET TT NOCRLF' in case it's not set. ; ; X01 (009) 25-Mar-83 Code for previous change only works under V5. ; New code will work under V4 or V5. ; ; X01 (010) 25-Mar-83 Added code to report errors if unable to attach ; the terminal under multi-terminal. ; ; X01 (011) 13-Apr-83 Added code which passes file size to VTCOM when ; doing HOST->RT transfers. ; ; X01 (012) 13-Sep-83 Changed packet sending from single character ; I/O (.TTYOU) to full buffer (.PRINT). ; ; X01 (013) 13-Sep-83 Added setting of EDIT$ in JSW to disable SL. Also ; fixed restore of JSW in routine RESTTY. ; ; X01 (014) 21-Sep-83 Added support for the use of the compression ; encoding technique built into VTCOM. Added support ; for abort of file transfers (this time ; it really works folks). ; ; X01 (015) 02-Oct-83 Added CSI-style prompting. ; ; Y01 (000) 06-Oct-83 Add protocol version to 's' and 'r' messages. ; ; Y01 (001) 07-Oct-83 Modified STATS routine for /LOG so a warning message ; is reported if there were any retries, added /B (bell) ; support (which implies /LOG) and re-added interactive ; mode prompts (which implies /LOG also). ; ; Y01 (002) 12-Oct-83 STATS routine was not printing full retry message ; if /B(ells) selected. ; ; Y01 (003) 18-Oct-83 Yet another fix of the STATS routine. ; ; Y01 (004) 06-Dec-83 Roll-back to pre-split version, new option characters ; ; Y01 (005) 13-Dec-83 Check for wildcard characters to return error message ; ; Y01 (006) 21-Dec-83 Fixed OPTION routine. It was rejecting /T/T as ; conflicting if on input side but not rejecting if ; on output side. Fixed so it is legal on both. ; ; Y01 (007) 10-Jan-84 Retry count is not being reset before TOHOST ; transfers, so multiple transfers initiated from ; CSI level cause the error count to be incorrect ; ; V05 (008) 23-Jan-84 Ready for release ; ; V05 (009) 28-Jan-84 Support for TSX single-character mode ; ; V05 (010) 01-Feb-84 The checksum is expected by VTCOM to be sent ; un-compressed. Also added code to determine the ; lead-in character to use under TSX. ; ; V05 (011) 03-Feb-84 SETTTY/RESTTY routines were not working correctly ; for forcing NOCRLF. (Found due to TSX) ; ; V05 (012) 07-May-84 Fix to SETTTY/RESTTY (again?!) to correctly ; force NOCRLF while operating under V5. ; ; V05 (013) 14-May-84 Added .RCTRL call before first prompt. ; ; V05 (014) 28-Jun-84 Due to change to KMON, switches may be passed ; in lower case, must convert to upper before ; comparing. ; ; V05 (015) 09-Jul-84 Change to KMON removed, OPTION code left in, but ; fixed. It shouldn't do indiscriminate clearing ; of bit 40 to convert from lower to upper case. ; ; V05 (017) 04-NOV-86 Heuristics to bump packet size based on error ; rate. ; V05 (018) 06-NOV-1990 bracket error messages in ;+/;ERROR/.../;- ; ; V05 (019) 16-NOV-1990 add VRUN stuff in JSX .SBTTL DEFINITIONS ; RT-11 MACROS WE WILL USE .MCALL .PRINT, .GTLIN, .EXIT .MCALL .CSISP, .TTYOU, .SCCA .MCALL .MTSTA, .RCTRL, .TTINR .MCALL .MRKT, .CMKT, .FETCH .MCALL .RELEA, .LOOKU, .ENTER .MCALL .READW, .WRITW, .PURGE .MCALL .CLOSE, .GTJB, .MTATC ;009 .MCALL .MTGET, .MTSET, .MTDTC ;009 .MCALL .GVAL, .TWAIT, .PVAL .MCALL .RCTRL .LIBRARY "SRC:SYSTEM" .MCALL .JSWDF .JSXDF .SYCDF .JSWDF .JSXDF .SYCDF ; PROTOCOL VERSION INFORMATION $$$VER == <^R1.0> ;GLOBAL FOR LINK MAP ; VECTOR ASSIGNMENTS ;009 ;009 EMT.V = 30 ;EMT VECTOR ;009 ;009 ; RT-11 SYSCOM LOCATIONS ; RMON FIXED OFFSETS ;008 ;008 SYSVER = 276 ;MONITOR VERSION NUMBER ;009 SYSGEN = 372 ;SYSGEN FEATURES WORD ;009 TSXP$ = 100000 ;RUNNING UNDER TSX PLUS MTTY$ = 020000 ;MULTI-TERMINAL SUPPORT ;009 $TCFIG = 424 ;->TERMINAL CONFIGURATION WORD ;008 CRLF$ = 000002 ;IGNORE WIDTH BIT ;008 ;008 ; I/O CHANNEL IOCHAN = 0 ;CHANNEL USED FOR INPUT/OUTPUT ; CHARACTERS CTRL.C = 3 BELL = 7 TAB = 11 LF = 12 CR = 15 CTRL.M = 35 SPACE = 40 ESC = 233 INAPC = +<'_*400> ;INCOMING MESSAGE PREFIX INST = +<'\*400> ;INCOMING MESSAGE SUFFIX ; TRANSFER PARAMETERS BLKMIN = 16. ;MINIMUM PACKET LENGTH BLKMAX = 512. ;MAXIMUM PACKET LENGTH .SBTTL MACRO DEFINITIONS ; ALTERNATE BRANCH INSTRUCTIONS .MACRO BR. LABEL JMP LABEL .ENDM .MACRO BEQ. LABEL,?ALT BNE ALT JMP LABEL ALT: .ENDM .MACRO BCS. LABEL,?ALT ;010 BCC ALT ;010 JMP LABEL ;010 ALT: ;010 .ENDM ;010 ;010 .MACRO BNE. LABEL,?ALT BEQ ALT JMP LABEL ALT: .ENDM ; ERROR REPORTING MACRO .MACRO ERROR. SEVER,TEXT,CR=YES ..MASK = 0 ..FLAG = 0 .IRPC XXX, .IF EQ ..FLAG .IF IDN SEVER,XXX ..FLAG = 1 .IFF .IIF EQ ..MASK ..MASK = 1 ..MASK = ..MASK*2 .ENDC .ENDC .ENDR .IF NE ..FLAG .SAVE .PSECT .TEXT. ... = . .NLIST BEX ;007 .BYTE ..MASK .ASCII |'SEVER'TEXT| .IF IDN CR,YES .BYTE 0 .IFF .BYTE 200 .ENDC .LIST BEX ;007 .RESTORE MOV #...,R0 JSR PC,ERRPRO .IFF .ERROR ;INVALID SEVERITY ''SEVER'' .ENDC .ENDM .ASECT .=$JSX .WORD VBGEX$!ALL64$ .SBTTL START OF CUSP ;+ ; ; TRANSF ; Top-level routine to orchestrate the program, calls ; the routines which: ; get the command (direction and file specs) ; process the command (do the transfer) ; ;- .PSECT .CODE. TRANSF: BIS #EDIT$,@#$JSW ;DISABLE SL FOR THE DURATION ;013 10$: JSR PC,GETCOM ;DETERMINE TRANSFER INFO JSR PC,PROCOM ;PROCESS THE COMMAND BR 10$ .SBTTL GETCOM - COLLECTS TRANSFER INFO FROM USER ;+ ; ; GETCOM ; Dispatches to routines to: ; determine direction of transfer ; obtain input file spec ; obtain output file spec ; ; RETURN: ; Host end file handler has been .FETCHed ; ;- .ENABL LSB GETCOM: MOV SP,SPSAVE ;SAVE PRE-CSI STACK POINTER 10$: .RCTRL ;RESET EFFECT OF A .GTLIN #CMDLIN,#M.CSIP ;PROMPT FOR THE COMMAND STRING BCS 40$ ;IN CASE LINE IS TOO LONG... TSTB CMDLIN ;WAS THERE ANY RESPONSE? BNE 20$ ;YES... .PRINT #M.ID ;NOPE, RESPOND WITH THE PROGRAM ID BR 10$ 20$: MOV #CMDLIN,R0 ;R0->RESPONSE JSR PC,WILDCK ;CHECK IT FOR WILD CARDS BCC 30$ ;NONE... ;+ ;ERROR ERROR. F, ;- BR 10$ 30$: .CSISP #FILSPC,#DEFEXT,#CMDLIN ;PROMPT FOR AND GET COMMAND STRING BCC 60$ ;NO ERRORS... 40$: MOV #CSIERR,R0 ;R0->CSI ERROR DISPATCH TABLE JSR PC,EMTERR ;GO REPORT THE ERROR 50$: MOV SPSAVE,SP ;ERRORS, RESTORE PRE-CSI STACK BR GETCOM ;TRY AGAIN 60$: JSR PC,OPTION ;GO HANDLE THE OPTIONS BCS 50$ ;IN CASE OF AN OPTION ERROR TST PROMPT ;DOES USER WANT PROMPTING? BNE 80$ ;YES, GO DO IT MOV ISPEC,-(SP) ;GET INPUT DEVICE NAME BIS OSPEC,(SP)+ ; MERGE WITH OUTPUT DEVICE NAME BEQ GETCOM ;NEITHER WAS SPECIFIED... MOV #ISPEC,R1 ;SET TO MOVE INPUT FILE NAME MOV #IFILE,R2 ; WHERE WE WANT IT .REPT 4 MOV (R1)+,(R2)+ .ENDR MOV #OSPEC,R1 ;SET TO MOVE OUTPUT FILE NAME MOV #OFILE,R2 ; WHERE WE WANT IT .REPT 4 MOV (R1)+,(R2)+ .ENDR MOV #IFILE,R1 ;SET TO DEFAULT UNSPECIFIED FILE SPECS MOV #OFILE,R2 TST OFILE ;WAS OUTPUT FILE SPECIFIED? BEQ 70$ ;NOPE... MOV #OFILE,R1 ;YES, REVERSE POINTERS MOV #IFILE,R2 TST IFILE ;WAS INPUT FILE SPECIFIED? BNE 90$ 70$: .REPT 4 MOV (R1)+,(R2)+ .ENDR MOV #<^RDK >,-10(R2) ;DEFAULT THE UNSPECIFIED FILE TO DK: BR 90$ 80$: BIS #GTLIN$,@#$JSW ;MAKE PROMPTING NON-TERMINATING JSR PC,GETDIR ;GET TRANSFER DIRECTION JSR PC,GETIF ;GET INPUT FILE NAME JSR PC,GETOF ;GET OUTPUT FILE NAME BIC #GTLIN$,@#$JSW ;RE-ENABLE TERMINATING .GTLIN 90$: MOV #IFILE,R1 ;ASSUME HOST->TERMINAL TST DIRECT ;CORRECT ASSUMTION? BEQ 100$ ;YES... MOV #OFILE,R1 ;NOPE, TERMINAL->HOST 100$: .FETCH LOMEM,R1 ;FETCH HANDLER WE'LL NEED BCC 110$ ;GOT IT... ;+ ;ERROR ERROR. F,,CR=NO JSR PC,ERRDEV ;REPORT THE OFFENDING DEVICE NAME ;- BR GETCOM 110$: RTS PC .DSABL LSB .SBTTL PROCOM - PROCESS TRANSFER COMMAND ;+ ; ; PROCOM ; Calls routines to: ; announce the transfer ; perform the transfer ; print transfer statistics ; announce completion of transfer ; ; RETURN: ; Host end file handler has been .RELEAsed ; ;- PROCOM: JSR PC,PREXFR ;ANNOUNCE PRE-TRANSFER STUFF TST DIRECT ;WHICH DIRECTION IS TRANSFER? BNE 10$ JSR PC,FROMHO ;FROM HOST TO TERMINAL BR 20$ 10$: JSR PC,TOHOST ;FROM TERMINAL TO HOST 20$: BCS 30$ ;IF ERRORS, JUST RETURN JSR PC,STATS ;PRINT TRANSFER STATS JSR PC,POSTXF ;DO POST-TRANSFER STUFF 30$: MOV #IFILE,R1 ;ASSUME HOST->TERMINAL TST DIRECT ;CORRECT? BEQ 40$ ;YES... MOV #OFILE,R1 ;NOPE, TERMINAL->HOST 40$: .RELEA R1 ;RELEASE THE HANDLER WE USED RTS PC .SBTTL OPTION - HANDLES OPTIONS ;+ ; ; OPTION ; Sets flags according to options on the stack. ; ; CALL: ; .CSIxx ; JSR PC,OPTION ; ; this causes the return address to be above the stack information ; returned by the CSI call. We use R5 as the stack pointer for the ; duration of this routine. ; ; RETURNS: ; c-bit = 0, Options okay, flags set ; c-bit = 1, Invalid option, conflicting options ; stack not completely unloaded ; ;- .ENABL LSB OPTION: MOV SP,R5 ;USE R5 FOR OUR STACK POINTER TST (R5)+ ;BYPASS THE RETURN ADDRESS MOV #177777,DIRECT ;RESET SOME FLAGS CLR LOG ;DEFAULT IS /NOLOG (QUIET) CLR PROMPT ;DEFAULT IS NON-INTERACTIVE CLR BELLS ;DEFAULT IS NO BELLS WITH /LOG MOV (R5)+,R0 ;SAVE COUNT OF OPTIONS TO PROCESS BEQ 80$ ;NONE TO PROCESS... 10$: TST (R5) ;WAS A VALUE SPECIFIED? BPL 20$ ;NOPE... MOV (R5)+,(R5) ;YES, DISCARD IT BIC #100000,(R5) ; AND GET RID OF THE INDICATOR BIT 20$: CMPB (R5),#'A+40 ;IS OPTION LOWER CASE? BLO 25$ ;NOPE... CMPB (R5),#'Z+40 ;MAYBE, CHECK UPPER RANGE BHI 25$ ;NOPE... BIC #40,(R5) ;CONVERT OPTION TO UPPER CASE 25$: CMPB (R5),#'R ;INTERACTIVE MODE REQUEST? BEQ OPT.I ;YES... CMPB (R5),#'S ;BELLS REQUESTED? BEQ OPT.B ;YES... CMPB (R5),#'T ;SPECIFYING TERMINAL SIDE? BEQ OPT.T ;YES, GO FIGURE OUT WHICH SIDE CMPB (R5),#'W ;/LOG SPECIFIED? BEQ OPT.W ;BRANCH IF SO, HANDLE IT ;+ ;ERROR ERROR. F,,CR=NO .TTYOU (R5) .PRINT #M.CRLF ;- BR 90$ OPT.T: TSTB 1(R5) ;OPTION ASSOCIATED WITH OUTPUT FILE? BEQ 40$ ;YES... TST DIRECT ;NO, IF OPTION HAS NOT BEEN USED OR ; ALREADY SPECIFIES REMOTE->HOST BHI 60$ ;WE FORCE IT TO REMOTE->HOST ;+ ;ERROR 30$: ERROR. F, ;- BR 90$ 40$: CMP DIRECT,#2 ;ALREADY SET REMOTE->HOST? BEQ 30$ ;YES, CAN'T HAVE THAT 50$: CLR DIRECT ;SET HOST->REMOTE BR 70$ 60$: MOV #2,DIRECT ;SET REMOTE->HOST BR 70$ OPT.B: INC BELLS ;SELECTING BELLS BR OPT.W ; (BELLS IMPLIES LOGGING) OPT.I: INC PROMPT ;DO INTERACTIVE PROMPTING FOR INFO ; (INTERACTIVE IMPLIES LOGGING) OPT.W: INC LOG ;DISPLAY INFORMATION ON EACH XFER 70$: TST (R5)+ ;DISCARD CHARACTER DEC R0 ;MORE OPTIONS TO CHECK? BGT 10$ ;YES... 80$: TST (PC)+ ;GOOD RETURN (CARRY = 0) 90$: SEC ;ERROR RETURN (CARRY = 1) ROL -(SP) ;SAVE THE CARRY TST DIRECT ;WAS IT SPECIFIED? BPL 100$ ;YES, DON'T TOUCH IT CLR DIRECT ;NOPE, DEFAULT TO HOST->REMOTE 100$: ROR (SP)+ ;RESTORE THE CARRY MOV (SP),-(R5) ;PUT RETURN ADDRESS ON OUR STACK MOV R5,SP ;RESET THE STACK POINTER RTS PC .DSABL LSB .SBTTL GETDIR - GET TRANSFER DIRECTION (INTERACTIVE) ;+ ; ; GETDIR ; Prompts for and sets the transfer direction flag ; ; RETURN: ; DIRECT = 0 if transfer is HOST->TERMINAL ; DIRECT = 2 if transfer is TERMINAL->HOST ; ;- .ENABL LSB GETDIR: CLR DIRECT ;DEFAULT DIRECTION TO HOST->TERMINAL .GTLIN #CMDLIN,#M.ORIG ;PROMPT FOR AND GET LOCATION OF ; ORIGINAL FILE MOV #CMDLIN,R0 ;R0->RESPONSE TSTB (R0) ;WAS THERE ANY? BEQ 10$ ;NOPE, TAKE DEFAULT (HOST->TERMINAL) MOV #S.HOST,R1 ;YES, SET TO COMPARE AGAINST DEFAULT JSR PC,CMPSTR ;DID USER SELECT DEFAULT? BEQ 10$ ;YES... MOV #S.TERM,R1 ;SET TO TRY OTHER ALTERNATIVE JSR PC,CMPSTR BNE GETDIR ;NEITHER, ASK HIM AGAIN MOV #2,DIRECT ;SELECT DIRECTION TERMINAL->HOST 10$: RTS PC .DSABL LSB .SBTTL GETIF - GET INPUT FILE SPEC (INTERACTIVE) ;+ ; ; GETIF ; Prompts for and gets input file name ; ; RETURN: ; IFILE contains RAD50 input file name ; ;- .ENABL LSB GETIF: MOV #M.OHF,R1 ;GUESS AT HOST->TERMINAL TST DIRECT ;CORRECT GUESS? BEQ 10$ ;YEP... MOV #M.OTF,R1 ;NOPE, TERMINAL->HOST 10$: .GTLIN #CMDLIN,R1 ;PROMPT FOR ORIGINAL FILE NAME TSTB CMDLIN ;ANY RESPONSE? BEQ 10$ ;NOPE, KEEP PROMPTING FOR ONE MOV #CMDLIN,R0 JSR PC,WILDCK BCC 15$ ;+ ;ERROR ERROR. F, ;- BR GETIF 15$: MOV SP,SPSAVE ;SAVE STACK BEFORE CALL .CSISP #FILSPC,#DEFEXT,#CMDLIN ;PARSE FOR INPUT FILE NAME MOV SPSAVE,SP ;RESTORE STACK BCC 20$ ;+ ;ERROR ERROR. F,,CR=NO .PRINT #CMDLIN ;ECHO THE BAD SPEC ;- BR GETIF 20$: MOV #ISPEC,R0 ;R0->PARSED FILE SPEC MOV #IFILE,R1 ;R1->WHERE TO SAVE IT MOV (R0)+,(R1)+ MOV (R0)+,(R1)+ MOV (R0)+,(R1)+ MOV (R0)+,(R1)+ RTS PC .DSABL LSB .SBTTL GETOF - GET OUTPUT FILE SPEC (INTERACTIVE) ;+ ; ; GETOF ;007 ; Prompts for and gets output file name ;007 ; ; RETURN: ; OFILE contains RAD50 output file name ;007 ; ;- .ENABL LSB GETOF: MOV #M.CTF,R2 ;ASSUME HOST->TERMINAL TST DIRECT ;CORRECT ASSUMTION? BEQ 10$ ;YES... MOV #M.CHF,R2 ;NOPE, TERMINAL->HOST 10$: .PRINT R2 MOV #ISPEC,R0 ;R0->DEFAULT FILE SPEC MOV #<^RDK >,(R0) MOV #TMPSTR,R1 ;R1->STRING CONVERSION BUFFER JSR PC,CVFILE ;CONVERT FILE TO ASCII MOVB #200,(R0) ;INHIBIT APPENDED .PRINT R1 ;PRINT FILE NAME .GTLIN #CMDLIN,#M.QUER ;COMPLETE THE QUERY AND GET RESPONSE TSTB CMDLIN ;ANY RESPONSE? BEQ 20$ ;NOPE, USE DEFAULT MOV #CMDLIN,R0 JSR PC,WILDCK BCC 15$ ;+ ;ERROR ERROR. F, ;- BR GETOF 15$: MOV SP,SPSAVE ;SAVE STACK .CSISP #FILSPC,#DEFEXT,#CMDLIN ;PARSE OUTPUT FILE SPEC MOV SPSAVE,SP BCC 20$ ;+ ;ERROR ERROR. F,,CR=NO .PRINT #CMDLIN ;ECHO THE OFFENDING SPEC ;- BR GETOF 20$: MOV #ISPEC,R0 ;R0->NEW OUTPUT FILE SPEC MOV #OFILE,R1 ;R1->WHERE TO SAVE OUTPUT FILE NAME MOV (R0)+,(R1)+ MOV (R0)+,(R1)+ MOV (R0)+,(R1)+ MOV (R0)+,(R1)+ RTS PC .DSABL LSB .SBTTL PREXFR - PRE TRANSFER INFO ;+ ; ; PREXFR ; Reports pre-transfer info: (If /LOG) ; output file name ; input file name ; ;- PREXFR: TST LOG ;ARE WE LOGGING THIS INFO? BEQ 30$ ;NOPE... .PRINT #M.CREA ;LET EM KNOW TRANSFER IS STARTING TST DIRECT ;HOST->TERMINAL? BNE 10$ ;NOPE... .PRINT #M.TT ;YES, ADD 'TT::' 10$: MOV #OFILE,R0 ;R0->OUTPUT FILE NAME MOV #TMPSTR,R1 ;R1->WHERE TO PLACE IT JSR PC,CVFILE ;CONVERT IT TO ASCII MOVB #200,(R0) ;INHIBIT .PRINT R1 .PRINT #M.FROM ; 'FROM' TST DIRECT ;HOST->TERMINAL BEQ 20$ ;YES... .PRINT #M.TT ;NOPE, ADD 'TT::' 20$: MOV #IFILE,R0 ;R0->INPUT FILE NAME MOV #TMPSTR,R1 ;R1->WHERE TO PLACE IT JSR PC,CVFILE ;CONVERT IT TO ASCII .PRINT R1 ;PRINT IT (WITH ) 30$: RTS PC .SBTTL FROMHO - PERFORMS HOST TO TERMINAL TRANSFER ;+ ; ; FROMHO ; Performs the actual file transfer from a file on the host ; to a file on the remote. ; ; RETURN: ; c-bit = 0 if transfer successful ; c-bit = 1 if transfer failed ; ; NOTES: ; host file is opened for input on entry and purged before ; return ; ;- .ENABL LSB FROMHO: JSR PC,SETTTY ;SAVE/SET TERMINAL CHARACTERISTICS BCS. 100$ ;WAS UNABLE TO ATTACH TERMINAL ;010 .LOOKU #AREA,#IOCHAN,#IFILE ;OPEN THE INPUT FILE BCC 10$ MOV #LKPERR,R0 ;R0->LOOKUP ERROR DISPATCH TABLE MOV #IFILE,R1 ;R1->FILE NAME JSR PC,EMTERR BR. 100$ 10$: MOV R0,ISIZE ;SAVE SIZE OF FILE 20$: MOV #'R!40,R0 ;TELL REMOTE TO RECEIVE A FILE JSR PC,HEADER ; First word in message 'r' is TRANSF's protocol version. VTCOM ; looks at this to determine if it should be talking to us. If ; the version matches VTCOM's, a ACK will be received. Else VTCOM ; will print a informative message, telling the user of the protocol ; version mismatch, then it will send us a standard 'zx' packet. MOV #$$$VER,R0 ;R0 = VERSION OF PROTOCOL JSR PC,ENCODE ;SEND IT OFF TO VTCOM ; Now pass the compression encoding table (if set) CLR COMPFG ;MAKE SURE TABLE ISN'T USED UNTIL ; BOTH ENDS HAVE A COPY MOV COMPSZ,R1 ;GET COMPRESSION TABLE SIZE BEQ 25$ ;TABLE HAS NO ENTRIES... MOV R1,R0 ;FIRST SEND THE TABLE SIZE JSR PC,ENCODE MOV #COMPTB,R2 ;R2->COMPRESSION TABLE 22$: MOV (R2)+,R0 ;GET A WORD OF THE TABLE JSR PC,ENCODE ;ENCODE IT DEC R1 ;ANY MORE TO SEND? BGT 22$ ;YES... 25$: MOV #OFILE,R0 ;R0->OUTPUT FILE NAME (RAD50) MOV #TMPSTR,R1 ;R1->CONVERSION BUFFER JSR PC,CVFILE ;CONVERT FILENAME FROM RAD50 TO ASCII ;011 ; NOW WE APPEND THE FILE SIZE (OF THE FORM [n]) ;011 ;011 MOV R1,-(SP) ;SAVE R1 FOR AWHILE ;011 MOV R0,R1 ;R1->AREA FOLLOWING FILE-SPEC ;011 MOVB #'[,(R1)+ ;START FILE-SIZE INFO ;011 MOV ISIZE,R0 ;GET THE SIZE (FROM THE .LOOKUP);011 JSR PC,CVBTOD ;CONVERT IT AND PLACE IN BUFFER ;011 MOVB #'],(R1)+ ;COMPLETE THE SIZE INFO ;011 CLRB (R1) ;END IT IN A NULL BYTE ;011 MOV R1,R0 ;R0->NULL BYTE AT END OF STRING ;011 MOV (SP)+,R1 ;RESTORE R1 ;011 ;011 CLRB 1(R0) ;ADD EXTRA NULL BYTE SUB R1,R0 ;R0=LENGTH OF CONVERTED STRING (BYTES) MOV R0,R1 ;SAVE IT INC R1 ASR R1 ;R1=LENGTH OF STRING (WORDS) MOV #TMPSTR,R2 ;R2->STRING TO SEND 30$: MOV (R2)+,R0 ;R0=WORD TO SEND JSR PC,ENCODE ;ENCODE IT DEC R1 ;MORE WORDS TO DO? BGT 30$ ;YEP... JSR PC,TRAILR ;NOPE, SEND THE TRAILER MOV COMPSZ,COMPFG ;NOW THAT OTHER END HAS A COPY OF ; THE COMPRESSION ENCODING TABLE, WE ; CAN START USING IT (UNLESS IT'S ; EMPTY, THEN WE DON'T) CLR COMPCT JSR PC,GETMSG ;GET A MESSAGE CMP R0,#18. ;RECEIVE ACK? BEQ 40$ ;YES, START SENDING FILE CMP R0,#6. ; 'zx' ABORT? BEQ. FABORT CMP R0,#7. ; 'zy' EOF? BEQ. FEOF CMP R0,#24. ; TIMEOUT? BNE 20$ ;+ ;ERROR ERROR. F, ;- BR. 100$ 40$: MOV #-1,BLOCKS ;RESET 'BLOCKS TRANSFERRED' COUNT ; (-1 SO 'INC' WILL BUMP TO 0) CLR ERRORC ;RESET ERROR COUNT MOV #BLKMAX,BLKSIZ ;MAKE MESSAGES MAXIMUM SIZE CLR MSGNUM ; AND RESET THE MESSAGE TOGGLE CLR REQSCT ;Reset 'required success count' CLR CURSCT ; and 'current success count' 50$: INC BLOCKS ;BUMP THE BLOCK COUNT CLR OFFSET ;RESET THE PARTIAL BLOCK OFFSET CLR ERROFG ;Reset error flag .READW #AREA,#IOCHAN,#IBUF,#256.,BLOCKS ;READ A BLOCK BCC 60$ ;NO ERRORS... TSTB @#$ERRBY ;EOF ERROR? BEQ. FDONE MOV #RDERR,R0 ;R0->READ ERROR DISPATCH TABLE MOV #IFILE,R1 ;R1->INPUT FILE NAME (RAD50) JSR PC,EMTERR ;REPORT THE ERROR BR FEOF ; AND ABORT THE TRANSFER ;004 60$: CMP OFFSET,#512. ;COMPLETED THIS BLOCK? ; (IN CASE OF SPLIT TRANSFER) BGE 92$ ;Yes, go check on errors MOV MSGNUM,R0 ;NO, SET TO PREFIX A MESSAGE ADD #60,R0 ; WITH MESSAGE TOGGLE (ASCII 0 OR 1) JSR PC,HEADER ;SEND THE HEADER MOV #IBUF,R1 ;R1->BLOCK TO SEND ADD OFFSET,R1 ;ADD OFFSET FOR THIS PARTIAL BLOCK MOV BLKSIZ,R2 ;R2=BLOCK SIZE ASR R2 ; IN WORDS 70$: MOV (R1)+,R0 ;GET A WORD JSR PC,ENCODE ;ENCODE IT AND SHIP TO REMOTE DEC R2 ;MORE TO DO? BGT 70$ ;YES... JSR PC,TRAILR ;SHIP THE TRAILER MESSAGE JSR PC,GETMSG ;GET THE RESPONSE MESSAGE TST CCSTAT ;HAVE WE BEEN 'D? BNE FEOF ;YES, GO DO AN ABORT CMP R0,#6. ; 'zx' - ABORT BEQ FABORT CMP R0,#7. ; 'zy' - EOF BEQ FEOF MOV MSGNUM,R1 ;R1=MESSAGE NUMBER ADD #11.,R1 ;MAKE IT CODE 'x0' OR 'x1' - NAK CMP R0,R1 ;WAS OUR MESSAGE NAK'ED? BNE 90$ ;NOPE... INC REQSCT ;Yes, bump required success count CLR CURSCT ; and reset current success count MOV SP,ERROFG ;Now set the error flag ;dbg .TTYOU #'v ASR BLKSIZ ;YES, HALVE CURRENT MESSAGE SIZE CMP BLKSIZ,#BLKMIN ;LESS THAN MINIMUM SIZE? BGE 80$ ;NOPE... MOV #BLKMIN,BLKSIZ ;YES, CAN'T BE LESS THAN MINIMUM 80$: BR 60$ ;TRY SENDING IT AGAIN 90$: ADD #19.-11.,R1 ;MAKE IT CODE 'y0' OR 'y1' - ACK CMP R0,R1 ;WAS OUR MESSAGE ACK'ED? BNE 60$ ;NOPE, TRY SENDING IT AGAIN NEG MSGNUM ;MSGNUM=1-MSGNUM INC MSGNUM ADD BLKSIZ,OFFSET ;SET TO SEND NEXT PARTIAL BLOCK BR 60$ ; Here are the heuristics for bumping packet size based on error ; rate over the serial line. 92$: ;dbg .TTYOU #'* TST ERROFG ;Errors sending that block? BNE 50$ ;Yes, on to next one... 94$: INC CURSCT ;Bump current success count CMP BLKSIZ,#BLKMAX ;Already at maximum packet size? BGE 50$ ;Yes, can't get any bigger... CMP CURSCT,REQSCT ;Nope, have we been good long enough? BLT 50$ ;Nope... ;dbg .TTYOU #'^ ASL BLKSIZ ;Yes, so double packet size BR 96$ DEC REQSCT ;Reduce required success count BNE 96$ ; (to a minimum MOV #1,REQSCT ; of one) 96$: CLR CURSCT ;We have to be good again... JMP 50$ ; FEOF is used to handle abort of a transfer due to ; errors which occur at either end. FEOF: MOV #"ZX!<40*400+40>,R0 ;SET TO SEND 'zx' TO REMOTE JSR PC,HEADER JSR PC,TRAILR ;+ ;ERROR ERROR. F, ;- JSR PC,GETMSG CMP R0,#6. ; 'zx' ABORT? BNE 100$ ;NOPE... FABORT: MOV #"YZ!<40*400+40>,R0 ;SET TO SEND 'yz' TO REMOTE JSR PC,HEADER JSR PC,TRAILR ;+ ;ERROR ERROR. F, ;- BR 100$ FDONE: MOV #"ZY!<40*400+40>,R0 ;TELL REMOTE 'END-OF-FILE' JSR PC,HEADER JSR PC,TRAILR JSR PC,GETMSG ;GET THE RESPONSE CMP R0,#6. ; 'zx' ABORT? BEQ FABORT CMP R0,#7. ; 'zy' EOF? BEQ FEOF CMP R0,#21. ; 'yz' EOF ACK? BNE FDONE ;NO, KEEP SIGNALLING TST (PC)+ 100$: SEC ROR -(SP) ;SAVE CARRY JSR PC,RESTTY ;RESTORE TERMINAL CHARACTERISTICS .PURGE #IOCHAN ;YES, THEN PURGE THE INPUT CHANNEL ROL (SP)+ ;RESTORE CARRY RTS PC .DSABL LSB .SBTTL TOHOST - TRANSFERS FILE FROM TERMINAL TO HOST ;+ ; ; TOHOST ; Performs the actual file transfer from a file on the remote ; to a file on the host. ; ; RETURN: ; c-bit = 0 if transfer successful ; c-bit = 1 if transfer failed ; ; NOTES: ; host file is open for output on entry and either closed ; (successful transfer) or purged (failed transfer) before ; return. ; ;- .ENABL LSB TOHOST: JSR PC,SETTTY ;SAVE/SET TERMINAL CHARACTERISTICS BCS. 90$ ;WAS UNABLE TO ATTACH TERMINAL ;010 .ENTER #AREA,#IOCHAN,#OFILE,#-1 BCC 10$ MOV #ENTERR,R0 ;R0->ENTER ERROR DISPATCH TABLE MOV #OFILE,R1 ;R1->FILE NAME JSR PC,EMTERR BR. 90$ 10$: MOV #'S!40,R0 ;TELL REMOTE TO SEND A FILE JSR PC,HEADER ; First word in message 's' is TRANSF's protocol version. VTCOM ; looks at this to determine if it should be talking to us. If ; the version matches VTCOM's, a ACK will be received. Else VTCOM ; will print a informative message, telling the user of the protocol ; version mismatch, then it will send us a standard 'zx' packet. MOV #$$$VER,R0 ;R0 = VERSION OF PROTOCOL JSR PC,ENCODE ;SEND IT OFF TO VTCOM ; Now pass the compression encoding table (if set) CLR COMPFG ;MAKE SURE TABLE ISN'T USED UNTIL ; BOTH ENDS HAVE A COPY MOV COMPSZ,R1 ;GET COMPRESSION TABLE SIZE BEQ 15$ ;TABLE HAS NO ENTRIES... MOV R1,R0 ;FIRST SEND THE TABLE SIZE JSR PC,ENCODE MOV #COMPTB,R2 ;R2->COMPRESSION TABLE 12$: MOV (R2)+,R0 ;GET A WORD OF THE TABLE JSR PC,ENCODE ;ENCODE IT DEC R1 ;ANY MORE TO SEND? BGT 12$ ;YES... 15$: MOV #IFILE,R0 ;R0->FILE NAME TO SEND MOV #TMPSTR,R1 ;R1->CONVERSION BUFFER JSR PC,CVFILE ;CONVERT FILENAME FROM RAD50 TO ASCII CLRB 1(R0) ;ADD EXTRA NULL BYTE SUB R1,R0 ;R0=LENGTH OF CONVERTED STRING (BYTES) MOV R0,R1 ;SAVE IT INC R1 ASR R1 ;R1=LENGTH OF STRING (WORDS) MOV #TMPSTR,R2 ;R2->STRING TO SEND 20$: MOV (R2)+,R0 ;R0=WORD TO SEND JSR PC,ENCODE ;ENCODE IT DEC R1 ;MORE WORDS TO DO? BGT 20$ ;YEP... JSR PC,TRAILR ;NOPE, SEND THE TRAILER MOV COMPSZ,COMPFG ;NOW THAT OTHER END HAS A COPY OF ; THE COMPRESSION ENCODING TABLE, WE ; CAN START USING IT (UNLESS IT'S ; EMPTY, THEN WE DON'T) CLR COMPCT JSR PC,GETMSG ;GET A RESPONSE CMP R0,#17. ; 'ys' ACK? BEQ 30$ ;YES, START GETTING THE FILE CMP R0,#6. ; 'zx' ABORT? BEQ FABORT ;YES... CMP R0,#7. ; 'zy' EOF? BEQ. FEOF ;YES... CMP R0,#24. ;TIMEOUT? BNE 10$ ;NOPE, KEEP SIGNALING... ;+ ;ERROR ERROR. F, ;- BR 90$ 30$: CLR ERRORC ;RESET THE ERROR CLR BLOCKS ; AND BLOCK COUNTS, CLR OFFSET ; SPLIT BLOCK OFFSET, CLR MSGNUM ; AND START MESSAGES AT 0 40$: JSR PC,GETMSG ;GET A MESSAGE FROM THE REMOTE TST CCSTAT ;HAVE WE BEEN 'D? BNE. FEOF ;YES, GO DO AN ABORT MOV #3,R1 ;R1=MESSAGE NUMBER WE EXPECT ADD MSGNUM,R1 CMP R0,R1 ;IS IT THE MESSAGE WE EXPECT? BEQ 50$ ;YES, GO PROCESS IT CMP R0,#6. ; 'zx' ABORT? BEQ. FABORT ;YES... CMP R0,#7. ; 'zy' EOF? BEQ TDONE ;YES, WE'RE DONE MOVB CODE$,R0 ;R0=RECEIVED CODE SWAB R0 BIS #'X!40,R0 ;NAK IT JSR PC,HEADER JSR PC,TRAILR BR 40$ 50$: MOV #DECBUF,R0 ;R0->DECODED MESSAGE MOV #OBUF,R1 ;R1->HOST FILE OUTPUT BUFFER ADD OFFSET,R1 ; PLUS OFFSET FOR SPLIT BLOCKS MOV MSGLEN,R2 ;R2=LENGTH OF MESSAGE (IN WORDS) 60$: MOV (R0)+,(R1)+ ;MOVE A WORD OF MESSAGE DEC R2 ;MORE TO DO? BGT 60$ ;YES... MOV MSGLEN,R0 ;R0=MESSAGE LENGTH (IN WORDS) ASL R0 ;CONVERT IT TO A BYTE COUNT ADD R0,OFFSET ;UPDATE THE SPLIT BLOCK OFFSET CMP OFFSET,#512. ;COMPLETE BLOCK? BLT 80$ ;NOPE... .WRITW #AREA,#IOCHAN,#OBUF,#256.,BLOCKS ;WRITE THE BLOCK BCC 70$ ;NO ERRORS... MOV #WRTERR,R0 ;R0->WRITE ERROR DISPATCH TABLE MOV #OFILE,R1 ;R1->FILE NAME JSR PC,EMTERR ;REPORT THE ERROR BR. FEOF ;ABORT THE TRANSFER ;004 70$: INC BLOCKS ;ONWARD CLR OFFSET 80$: MOV MSGNUM,R0 ;R0=MESSAGE NUMBER ADD #60,R0 ;MAKE IT PRINTABLE SWAB R0 BIS #'Y!40,R0 ;ACK THE MESSAGE JSR PC,HEADER JSR PC,TRAILR NEG MSGNUM ;MSGNUM=1-MSGNUM INC MSGNUM BR 40$ TDONE: MOV #"YZ!<40*400+40>,R0 ;R0=EOF ACK JSR PC,HEADER JSR PC,TRAILR TST (PC)+ 90$: SEC ROR -(SP) ;SAVE CARRY JSR PC,RESTTY ;RESTORE TERMINAL CHARACTERISTICS TST (SP) ;TRANSFER FAILED? BPL 100$ ;IF POSITIVE, NO... .PURGE #IOCHAN ;YES, PURGE OUTPUT CHANNEL BR 110$ 100$: .CLOSE #IOCHAN ;CLOSE CHANNEL BCC 110$ ;+ ;ERROR ERROR. F,,CR=NO MOV #OFILE,R1 ;R1->FILE NAME JSR PC,ERRFIL ; APPEND IT TO THE ERROR MESSAGE ;- 110$: ROL (SP)+ ;RESTORE CARRY RTS PC .DSABL LSB .SBTTL STATS - REPORT TRANSFER STATISTICS ;+ ; ; STATS ; Reports transfer statistics: ; blocks transferred (If /LOG) ; count of errors which occurred ; ;- .ENABL LSB STATS: TST BELLS ;BELLS DESIRED ON ERRORS? BEQ 15$ ;NOPE... MOV #M.1BEL,R0 ;YES, DEFAULT TO NO ERRORS TST ERRORC ;WELL, WERE THERE ANY? BEQ 10$ ;NOPE... MOV #M.3BEL,R0 ;YES, DRAW ATTENTION TO THE FACT 10$: .PRINT 15$: TST LOG ;ARE WE LOGGING? BNE 25$ ;YES... TST ERRORC ;NO, BUT WERE THERE ANY ERRORS? BEQ 50$ ;NOPE... ;+ ;ERROR 20$: ERROR. W,,CR=NO ;YES, ALWAYS REPORT ERRORS BR 30$ ;- 25$: .TTYOU #SPACE MOV BLOCKS,R0 ;GET TOTAL BLOCKS TRANSFERRED JSR PC,DECOUT ; PRINT IT .PRINT #M.STAT ; 'BLOCKS TRANSFERRED WITH' ;+ ;ERROR 30$: MOV ERRORC,R0 JSR PC,DECOUT MOV #M.RTR1,R0 ;ASSUME 1 RETRY DEC ERRORC ;ONLY ONE RETRY? BEQ 40$ ;YEP... MOV #M.RTRY,R0 ;NOPE, MORE THAN ONE 40$: .PRINT TST LOG ;LOGGING? BEQ 50$ TST COMPCT ;WAS COMPRESSION ENCODING USEFUL? BEQ 50$ ;NOPE... .TTYOU #SPACE ;YES, START LINE WITH A SPACE MOV COMPCT,R0 ;GET THE NUMBER OF ENCODE CHARACTERS ASL R0 ;SHIFT FOR NUMBER NOT SENT JSR PC,DECOUT ;LET THE USER KNOW .PRINT #M.COMP ; JUST WHAT IT SAVED HIM ;- 50$: RTS PC .DSABL LSB .SBTTL POSTXF - POST TRANSFER INFORMATION ;+ ; ; POSTXF ; Reports post-transfer information: (If /LOG) ; output file ; input file ; ;- POSTXF: TST LOG ;LOGGING SELECTED? BEQ 30$ ;NOPE... TST DIRECT ;HOST->TERMINAL? BNE 10$ ;NOPE... .PRINT #M.TT ;YES, ADD 'TT::' 10$: MOV #OFILE,R0 ;R0->OUTPUT FILE NAME MOV #TMPSTR,R1 ;R1->WHERE TO PLACE IT JSR PC,CVFILE ;CONVERT IT TO ASCII MOVB #200,(R0) ;INHIBIT .PRINT R1 .PRINT #M.DONE ; 'CREATED FROM' TST DIRECT ;HOST->TERMINAL BEQ 20$ ;YES... .PRINT #M.TT ;NOPE, ADD 'TT::' 20$: MOV #IFILE,R0 ;R0->INPUT FILE NAME MOV #TMPSTR,R1 ;R1->WHERE TO PLACE IT JSR PC,CVFILE ;CONVERT IT TO ASCII .PRINT R1 ;PRINT IT (WITH ) 30$: RTS PC .SBTTL SETTTY - SAVE/SET TERMINAL CHARACTERISTICS ;+ ; ; SETTTY ; Saves the terminal characteristic bits and sets bits ; we need for this whole thing to work. ;008 ; ; RETURN: ; OJSW contains old JSW contents ;008 ; OTTCNF contains old terminal configuration word contents ;008 ; ;- .ENABL LSB ;010 ;010 SETTTY: .SCCA #AREA,#CCSTAT ;ENABLE ^C TRAPPING ;005 CLR CCSTAT ;RESET ^C ABORT INDICATOR MOV @#$JSW,OJSW ;SAVE CURRENT JSW CONTENTS ;008 BIS #TTLC$!TTSPC$!TCBIT$,@#$JSW ;SET LOWER CASE, ; TT SPECIAL MODE, ; INHIBIT TERMINAL I/O WAIT .RCTRL ;MAKE THEM TAKE AFFECT MOV R0,-(SP) ;SAVE SOME REGISTERS FOR AWHILE MOV R1,-(SP) .GVAL #AREA,#SYSGEN ;R0 = SYSGEN FEATURES WORD BIT #MTTY$,R0 ;MULTI-TERMINAL SUPPORT? BEQ 10$ ;NOPE... ;009 .GTJB #AREA,#JOBINF ;GET INFO FOR THIS JOB ;009 .MTATC #AREA,#0,J.LUN ;ATTACH LUN FOR THIS JOB ;009 BCC 5$ ;GOT IT ;010 ;+ ;ERROR ERROR. F, ;010 ;- BR 50$ ;010 ;010 5$: .MTGET #AREA,#MTSTAT,J.LUN ;GET STATUS FOR THIS LUN ;010 MOV M.TSTS,OTTCNF ;SAVE OLD CONFIGURATION BIC #CRLF$,M.TSTS ;SET ;009 .MTSET #AREA,#MTSTAT,J.LUN ;SET STATUS FOR THIS LUN ;009 BR 40$ ;009 ;009 10$: .GVAL #AREA,#SYSVER ;R0 = SYSTEM VERSION NUMBER CMPB R0,#5 ;VERSION 5 OR LATER? BHIS 20$ ;YES... ;009 MOV @#EMT.V,R0 ;PRIOR TO V5, TTCNFG IS THE WORD;009 TST -(R0) ; BEFORE THE EMT PROCESSOR ;009 BR 30$ 20$: .GVAL #AREA,#$TCFIG ;Get pointer to terminal status word 30$: MOV (R0),OTTCNF ;Save old terminal status BIC #CRLF$,(R0) ; and force to 'NOCRLF' ; Okay, that takes care of running under RT. Now we're nice and ; do some special things for TSX plus. CLR TSXFLG ;RESET THE TSX FLAG .GVAL #AREA,#SYSGEN ;R0 = SYSGEN FEATURES WORD BIT #TSXP$,R0 ;RUNNING UNDER TSX PLUS? BEQ 40$ ;NOPE... MOV SP,TSXFLG ;YES, SET THE TSX FLAG .GVAL #AREA,#-4 ;R0 = TSX PLUS LEAD-IN CHARACTER MOVB R0,M.TSXS ; NOW SET IT IN THE TSX STRINGS MOVB R0,M.TSXS+2 ; WHICH ENABLE AND DISABLE MOVB R0,M.TSXR ; SINGLE-CHARACTER ACTIVATION MODE MOVB R0,M.TSXR+2 ; AND TAPE MODE .PRINT #M.TSXS ;SET THE TERMINAL STATE UNDER TSX 40$: TST (PC)+ ;GOOD RETURN (CARRY = 0) ;010 50$: SEC ;ERROR RETURN (CARRY = 1) ;010 MOV (SP)+,R1 ;RESTORE SAVED REGISTERS MOV (SP)+,R0 RTS PC ;010 .DSABL LSB ;010 .SBTTL RESTTY - RESTORE TERMINAL CHARACTERISTICS ;+ ; ; RESTTY ; Restores terminal characteristics (restores JSW from OJSW ;008 ; and terminal configuration word from OTTCNF) ;008 ; ;- RESTTY: .SCCA #AREA,#0 ;TURN OFF ^C TRAPPING ;013 MOV R0,-(SP) ;SAVE SOME REGISTERS FOR AWHILE MOV R1,-(SP) .GVAL #AREA,#SYSGEN ;R0 = SYSGEN FEATURES WORD BIT #MTTY$,R0 ;MULTI-TERMINAL SUPPORT? BEQ 10$ ;NOPE... ;009 MOV OTTCNF,M.TSTS ;SET TO RESTORE OLD STATUS ;009 .MTSET #AREA,#MTSTAT,J.LUN ;NOW DO IT ;009 .MTDTC #AREA,J.LUN ;WE'RE DONE, FREE THE TERMINAL ;009 BR 40$ ;009 ;009 10$: .GVAL #AREA,#SYSVER ;R0 = SYSTEM VERSION NUMBER CMPB R0,#5 ;VERSION 5 OR LATER? BHIS 20$ ;YES... ;009 MOV @#EMT.V,R0 ;PRIOR TO V5, TTCNFG IS THE WORD;009 TST -(R0) ; BEFORE THE EMT PROCESSOR ;009 BR 30$ 20$: .GVAL #AREA,#$TCFIG ;Get address of status word 30$: MOV OTTCNF,(R0) ;Restore old terminal settings 40$: .PRINT #M.CR ;RESET CARRAIGE POSITION ;009 MOV OJSW,@#$JSW ;RESTORE OLD CONFIGURATION BITS ;013 .RCTRL ;MAKE THEM TAKE AFFECT ;013 ; Again, so far we've taken care of running under RT. Now ; we do the restore when running under TSX TST TSXFLG ;RUNNING UNDER TSX? BEQ 50$ ;NOPE... .PRINT #M.TSXR ;YES, RESET TERMINAL STATE UNDER TSX 50$: MOV (SP)+,R1 ;RESTORE SAVED REGISTERS MOV (SP)+,R0 RTS PC .SBTTL HEADER - SEND MESSAGE HEADER TO REMOTE ;+ ; ; HEADER ; Sends the APplication Code to the remote along with ; the code specified in R0. Also presets the checksum. ; ; CALL: ; R0 = code to send ; hi byte = second character ; lo byte = first character ; ; RETURN: ; OCHECK initialized ; ;- HEADER: MOV R0,OCHECK ;PREPARE THE CHECKSUM MOV R0,-(SP) ;SAVE THE CHARACTERS TO SEND .PRINT #M.APC ;START WITH THE APPLICATION CODE .TTYOU (SP) ;FOLLOWED BY THE FIRST CHARACTER SWAB (SP) .TTYOU (SP)+ ;AND THE SECOND MOV #MSGBUF,MSGPTR ;RESET BUFFER POINTER ;012 RTS PC .SBTTL TRAILR - SEND TRAILER TO REMOTE ;+ ; ; TRAILR ; Sends the accumulated checksum followed by the String ; Terminator message. ; ; CALL: ; OCHECK = accumulated checksum ; ;- TRAILR: MOV OCHECK,R0 ;R0=CURRENT CHECKSUM NEG R0 ;SEND IT NEGATED JSR PC,ENCNOC ; (AND UN-COMPRESSED) MOVB #200,@MSGPTR ;SET .PRINT FENCE ;012 .PRINT #MSGBUF ;PRINT THE PACKET ;012 .PRINT #M.ST ;COMPLETE THE MESSAGE RTS PC .SBTTL GETMSG - GET MESSAGE FROM REMOTE ;+ ; ; GETMSG ; Gets a message from the remote. ; ; RETURN: ; R0 = completion code ; DECBUF contains decoded message ; MSGSIZ contains message size (in words) ; ; completion codes returned: ; 01 - s 'send file' 13 - xz ; 02 - r 'receive file' 14 - xx ; 03 - 0 'message 0' 15 - xy ; 04 - 1 'message 1' 16 - y? ; 05 - z? 17 - ys 'ACK send' ; 06 - zx 'ABORT' 18 - yr 'ACK receive' ; 07 - zy 'EOF' 19 - y0 'ACK message 0' ; 08 - x? 20 - y1 'ACK message 1' ; 09 - xs 'NAK send' 21 - yz 'ACK EOF' ; 10 - xr 'NAK receive' 22 - yx ; 11 - x0 'NAK message 0' 23 - yy ; 12 - x1 'NAK message 1' 24 - TIME OUT ; ;- GETMSG: MOV R1,-(SP) ;SAVE SOME REGISTERS FIRST MOV R2,-(SP) MOV R3,-(SP) 5$: JSR PC,GETBYT ;GET A CHARACTER BCS 40$ ;IN CASE OF TIMEOUT... CMPB R0,# ;IS IT AN ? BNE 5$ ;NOPE, IGNORE IT MOVB R0,PREFIX ;YES, SAVE IT FOR LATER CHECK JSR PC,GETBYT ;GET ANOTHER CHARACTER BCS 40$ ;IN CASE OF TIMEOUT... MOVB R0,PREFIX+1 ;SAVE IT FOR UPCOMING CHECK 7$: CMP PREFIX,#INAPC ;HAVE WE RECEIVED EXPECTED ? BNE 5$ ;IF NOT, KEEP TRYING... ;001 MOV #MSGBUF,R3 ;R3->MESSAGE BUFFER 10$: JSR PC,GETBYT ;GET A MESSAGE BYTE BCS 40$ CMPB R0,# ;? BEQ 20$ ;YES, END OF MESSAGE... MOVB R0,(R3)+ ;NOPE, SAVE IT IN THE BUFFER BR 10$ ;GO GET ANOTHER 20$: MOVB R0,PREFIX ;SAVE IT FOR A LATER CHECK JSR PC,GETBYT ;GET ANOTHER CHARACTER BCS 40$ ;IN CASE OF TIMEOUT... MOVB R0,PREFIX+1 ;SAVE IT FOR UPCOMING CHECK CMP PREFIX,#INST ;HAVE WE RECEIVED EXPECTED ? BNE 7$ ;NO, CHECK FOR AN ... SUB #MSGBUF+1,R3 ;R3=MESSAGE LENGTH (IN BYTES) MOV #MSGBUF,R1 ;R1->MESSAGE BUFFER MOVB (R1)+,R0 ;GET THE MOV R0,CODE$ ; AND SAVE IT FOR CHECKSUM DEC R3 ;REDUCE MESSAGE LENGTH MOV #CODES$,R2 ;R2->VALID CODE CHARACTERS 30$: TSTB (R2) ;END OF TABLE? BEQ 50$ ;YES... CMPB R0,(R2)+ ;NOPE, MATCHES CHARACTER? BNE 30$ ;NOPE, TRY ANOTHER SUB #CODES$,R2 ;YES, GET IT'S POSITION BR 60$ 40$: MOV #24.,CODE ;TIMEOUT, CODE 24 BR 140$ 50$: CLR R2 ;NOT FOUND, POSITION=0 60$: CMP R2,#5 ;NOTE: I DON'T EVEN UNDERSTAND BLT 120$ ; MOST OF THIS YET, IT'S JUST BGT 80$ ; TRANSLATED FROM THE BASIC+ ; VERSION FOR RSTS. ; HERE IF CODE=5 MOV R2,-(SP) ;SAVE CURRENT CODE MOVB (R1)+,R0 ; GET SECOND CODE CHARACTER DEC R3 ;REDUCE MESSAGE LENGTH MOVB R0,SECND$ ;SAVE IT FOR CHECKSUM LATER MOV #CODES$+5,R2 ;R2->SUBCODE CHARACTERS 70$: TSTB (R2) ;END OF TABLE? BEQ 100$ ;YES... CMPB R0,(R2)+ ;CHARACTER MATCHES? BNE 70$ ;NOPE, TRY ANOTHER SUB #CODES$+5,R2 ;YES, GET IT'S POSITION BR 110$ ; HERE IF CODE IS >5 80$: SUB #5,R2 ;CODE=(CODE-5*8)+POS(SECND$,CODES$) ASL R2 ASL R2 ASL R2 MOV R2,-(SP) ;SAVE CURRENT CODE VALUE MOVB (R1)+,R0 ;GET SECOND CODE CHARACTER DEC R3 ;REDUCE MESSAGE LENGTH MOVB R0,SECND$ ;SAVE IT FOR CHECKSUM LATER MOV #CODES$,R2 ;R2->SUBCODE CHARACTERS 90$: TSTB (R2) ;END OF TABLE? BEQ 100$ ;YES... CMPB R0,(R2)+ ;CHARACTER MATCHES? BNE 90$ ;NOPE... SUB #CODES$,R2 ;YES, GET IT'S POSITION BR 110$ 100$: CLR R2 ;NOT FOUND, POSITION=0 110$: ADD (SP)+,R2 ;MERGE WITH CURRENT CODE VALUE 120$: MOV R2,CODE ;SAVE CODE FOR LATER MOV CODE$,ICHECK ;PRIME THE INCOMING CHECKSUM ; (WITH CODE$ AND SECND$) MOV #DECBUF,R2 ;R2->DECODED MESSAGE BUFFER CLR MSGLEN ;RESET FOR NOW 130$: JSR PC,DECODE ;CONVERT THREE CHARACTERS MOV R0,(R2)+ ;PLACE IN DECODE BUFFER INC MSGLEN ;BUMP MESSAGE SIZE (IN WORDS) TST R3 ;ANY MORE CONVERSION TO DO? BGT 130$ ;IF >0, YES ;001 DEC MSGLEN ;DON'T COUNT CHECKSUM IN TRANSFER TST ICHECK ;SPEAKING OF WHICH, IS CHECKSUM ZERO? BEQ 140$ ;YES, SO CHECK THE CODE NEG CODE ;NOPE, NEGATE CODE 140$: MOV CODE,R0 ;GET COMPLETION CODE BLE 160$ ;IF <1, INVALID PREFIX OR BAD CHECKSUM MOV #ERRCOD,R1 ;R1->TABLE OF ERROR CONDITIONS 150$: TST (R1) ;END OF TABLE? BEQ 170$ ;YES, NOT FOUND, NOT AN ERROR... CMP R0,(R1)+ ;NOPE, CHECK THIS ENTRY, MATCH? BNE 150$ ;NOPE... 160$: INC ERRORC ;BUMP ERROR COUNT 170$: MOV (SP)+,R3 ;RESTORE THE WORK REGISTERS MOV (SP)+,R2 MOV (SP)+,R1 RTS PC .SBTTL GETBYT - GET BYTE FROM REMOTE (WITH TIMEOUT) ;+ ; ; GETBYT ; Get a character from the console. If no character is ; available at the time of the request, we try to get ; a character with time-out in effect. ; ; RETURN: ; c-bit = 0 ; R0 = character ; c-bit = 1 ; time-out (15 seconds) occurred ; ;- .ENABL LSB GETBYT: .TTINR ;TRY TO GET A CHARACTER BCC 40$ ;GOT ONE, NO TIME-OUT NEEDED CLR TIMOUT ;RESET TIMEOUT INDICATOR CLR TIME ;SET HIGH-ORDER MOV #15.*60.,TIME+2 ; AND LOW-ORDER TIME-OUT (15 SECONDS) 10$: .MRKT #MAREA,#TIME,#TIMCMP,#1 ;POST A TIME-OUT BCS 10$ ;TRY AGAIN 20$: .TTINR ;TRY TO GET A CHARACTER BCC 30$ ;GOT ONE... TST (PC)+ ;HAS TIMEOUT OCCURRED? TIMOUT: .BLKW ; : TIMEOUT INDICATOR BNE 50$ ;YES, REMOTE NOT THERE... BR 20$ ;NOPE, TRY AGAIN .TWAIT #TAREA,#TIMBLK ;SLEEP A LITTLE BR 20$ ; AND THEN TRY AGAIN 30$: MOV R0,-(SP) ;GOT A CHARACTER, SAVE IT .CMKT #MAREA,#1,#TIME ; SO WE CAN CANCEL .MRKT MOV (SP)+,R0 ;RETURN CHARACTER IN R0 40$: CMPB R0,#CTRL.C ;IS THE CHARACTER A ? BNE 45$ ;NOPE, RETURN IT INC CCSTAT ;YES, FLAG IT SO WE CAN ABORT CLEANLY BR GETBYT ;OTHERWISE, 'S ARE IGNORED 45$: TST (PC)+ ;GOOD RETURN (CARRY CLEAR) 50$: SEC ;BAD RETURN (CARRY SET) RTS PC ; TIME-OUT COMPLETION ROUTINE TIMCMP: MOV R0,TIMOUT ;USE ID AS TIMEOUT INDICATOR RTS PC .DSABL LSB .SBTTL ERRPRO - ERROR PROCESSOR ;+ ; ; ERRPRO ; Processes the error message information pointed to by R0. ; Sets USERRB, prints '?facility-severity-text' and returns. ; ; CALL: ; R0 -> error message specifier: ; 1 byte for USERRB mask ; 1 byte for severity ; remainder of text (ending in <0> or <200> byte ; ; RETURN: ; updated USERRB with new mask ; SEVER = severity character ; ;- ERRPRO: BISB (R0)+,@#$USRRB ;SET USER ERROR BYTE MOVB (R0)+,SEVER ;SET SEVERITY MOV R0,-(SP) ;SAVE R0 .PRINT #FACILI ;PRINT '?facility-severity- .PRINT (SP)+ ; text' RTS PC .SBTTL EMTERR - PROCESSES EMT ERRORS ;+ ; ; EMTERR ; Prints the appropriate error message as indicated in ; ERRBYT using the table pointed to by R0 as a base. ; ; CALL: ; R0 -> table to be used for dispatching ; R1 -> 4-word block containing file name ; ;- EMTERR: MOVB @#$ERRBY,-(SP) ;GET REASON FOR FAILURE BIC #^C<377>,(SP) ;ISOLATE IT ASL (SP) ;CONVERT TO BYTE OFFSET ADD (SP)+,R0 ;R0->TABLE ENTRY MOV (R0),R0 ;GET IT ADD R0,PC ;DISPATCH TO IT ERRDSP: ; CSI ERROR DISPATCH TABLE CSIERR: .WORD CSI000-ERRDSP ;CSISP ERROR 0 (INVALID COMMAND LINE) .WORD CSI001-ERRDSP ;CSISP ERROR 1 (INVALID DEVICE) ; LOOKUP ERROR DISPATCH TABLE LKPERR: .WORD LKP000-ERRDSP ;LOOKUP ERROR 0 (CHANNEL ALREADY OPEN) .WORD LKP001-ERRDSP ;LOOKUP ERROR 1 (FILE NOT FOUND) .WORD LKP002-ERRDSP ;LOOKUP ERROR 2 (DEVICE IN USE) ; ENTER ERROR DISPATCH TABLE ENTERR: .WORD LKP000-ERRDSP ;ENTER ERROR 0 (CHANNEL IN USE) .WORD ENT001-ERRDSP ;ENTER ERROR 1 (DEVICE FULL) .WORD LKP002-ERRDSP ;ENTER ERROR 2 (DEVICE IN USE) .WORD ENT003-ERRDSP ;ENTER ERROR 3 (PROTECTED FILE) ; READ ERROR DISPATCH TABLE RDERR: .WORD RD000-ERRDSP ;READ ERROR 0 (READ PAST EOF) .WORD RD001-ERRDSP ;READ ERROR 1 (HARDWARE ERROR) .WORD RD002-ERRDSP ;READ ERROR 2 (CHANNEL NOT OPEN) ; WRITE ERROR DISPATCH TABLE WRTERR: .WORD WRT000-ERRDSP ;WRITE ERROR 0 (WRITE PAST EOF) .WORD WRT001-ERRDSP ;WRITE ERROR 1 (HARDWARE ERROR) .WORD RD002-ERRDSP ;WRITE ERROR 2 (CHANNEL NOT OPEN) .SBTTL EMT ERROR REPORTING ROUTINES ;+ ; ; NOTE: ; ERRFIL appends the file name ; ERRDEV appends the device name ; ;- ;+ ;ERROR CSI000: ERROR. F, RTS PC CSI001: ERROR. F, RTS PC LKP000: ERROR. F, RTS PC LKP001: ERROR. F,,CR=NO ERRFIL: MOV R1,R0 ;GET POINTER TO OFFENDING FILE MOV #TMPSTR,R1 ;R1->CONVERSION BUFFER JSR PC,CVFILE ;CONVERT IT .PRINT R1 ;AND PRINT IT RTS PC LKP002: ERROR. F, RTS PC ENT001: ERROR. F,,CR=NO ERRDEV: MOV (R1),R0 ;GET THE OFFENDING DEVICE (RAD50) MOV #TMPSTR,R1 ;R1->WHERE TO PUT CONVERTED STRING JSR PC,CVRTOA ;CONVERT FROM RAD50 TO ASCII MOVB #':,(R1)+ ;ADD 'DEVICE' DELIMITER CLRB (R1) ; AND TERMINATE WITH NULL BYTE JSR PC,COMPRS ;COMPRESS THE STRING .PRINT #TMPSTR ;PRINT THE OFFENDING SPECIFICATION RTS PC ENT003: ERROR. F,,CR=NO BR ERRFIL RD000: ERROR. F, RTS PC RD001: ERROR. F,,CR=NO BR ERRFIL RD002: ERROR. F, RTS PC WRT000: ERROR. F, RTS PC WRT001: ERROR. F,,CR=NO BR ERRFIL ;- .SBTTL CMPSTR - STRING COMPARE ROUTINE ;+ ; ; CMPSTR ; Compares the string pointed to by R0 (string1) against the ; string pointed to by R1 (string2) and returns the result ; of the comparison. ; ; Conditions of match: ; String1 equals string2 for each position up to LEN(string2). ; ; Conditions of non-match: ; String1 not equal to string2 in any position or LEN(string1) ; is greater than LEN(string2). ; ; CALL: ; R0 -> string1 ; R1 -> string2 ; ; RETURN: ; R0 -> string1 ; ; z-bit=1 if strings match ; and R1 -> character beyond last matching character ; z-bit=0 if strings don't match ; and R1 -> character beyond non-matching character ; ;- CMPSTR: MOV R0,-(SP) ;SAVE R0 FOR RETURN 10$: TSTB (R0) ;END OF STRING1? BEQ 30$ ;YES, STRINGS MATCH TSTB (R1) ;END OF STRING2? BEQ 20$ ;YES, STRINGS DONT MATCH CMPB (R0)+,(R1)+ ;DO STRINGS MATCH IN THIS POSITION? BEQ 10$ ;YES... 20$: MOV (SP)+,R0 CLZ ;ZERO=0 FOR NO MATCH RTS PC 30$: MOV (SP)+,R0 SEZ ;ZERO=1 FOR MATCH RTS PC .SBTTL ENCODE - WORD TO ASCII CONVERTER ;+ ; ; ENCODE ; Converts the word in R0 to three ascii characters which are ; sent to the remote. The three characters are generated by ; taking bits <15:12>, <11:06> and <05:00> and adding 40(8) ; to each (to make them printable). The checksum is also ; updated by the contents of the word ; ; If the compression encoding table has any entries and the ; word passed in R0 matches one of them, then the word is ; encoded as a single byte which is 140(8) plus the offset ; into the encoding table. ; ; CALL: ; R0 = 16-bit word to convert ; ; RETURN: ; R0 munged ; OCHECK = accumulated checksum ; ;- .ENABL LSB ENCNOC: MOV R1,-(SP) ;SAVE THE WORK REGISTERS MOV R2,-(SP) BR 20$ ;NOW ENCODE WITHOUT COMPRESSION ENCODE: MOV R1,-(SP) ;SAVE SOME WORK REGISTERS MOV R2,-(SP) TST COMPFG ;COMPRESSION ENCODING IN EFFECT? BEQ 20$ ;NOPE... MOV COMPSZ,R2 ;R2=TABLE SIZE (IN WORDS) MOV #COMPTB,R1 ;R1->COMPRESSION TABLE 10$: CMP R0,(R1)+ ;IS THIS THE ENTRY TO USE? BEQ 15$ ;YES... DEC R2 ;NOPE, MORE TABLE TO DO? BGT 10$ ;YES... BR 20$ ;NOPE, CODE IT NORMALLY 15$: SUB #COMPTB+2,R1 ;DETERMINE THE OFFSET ASR R1 ;SHIFT FROM BYTE TO WORD OFFSET ADD #140,R1 ;INDICATE IT'S A COMPRESSION BYTE ADD R1,OCHECK ;ADD IT TO THE CHECKSUM MOVB R1,@MSGPTR ;PLACE CHARACTER IN THE MESSAGE BUFFER INC MSGPTR INC COMPCT BR 30$ 20$: ADD R0,OCHECK ;UPDATE THE CHECKSUM MOV R0,-(SP) ;MAKE A COPY OF THE WORD BIC #<^C170000>,R0 ;STRIP TO BITS <15:12> SWAB R0 ;MOVE THEM TO THE LOW BYTE ASR R0 ;WHERE WE RIGHT-JUSTIFY THEM ASR R0 ASR R0 ASR R0 ADD #40,R0 ;ADJUST TO RANGE 40-57 MOVB R0,@MSGPTR ;MOVE FIRST CHARACTER TO BUFFER ;012 INC MSGPTR ; AND BUMP BUFFER POINTER ;012 MOV (SP),R0 ;GET THE WORD AGAIN BIC #<^C7700>,R0 ;STRIP TO BITS <11:06> ASL R0 ;FORCE THEM TO THE HIGH BYTE ASL R0 SWAB R0 ;NOW PLACE IN THE LOW BYTE ADD #40,R0 ;ADJUST TO RANGE 40-137 MOVB R0,@MSGPTR ;MOVE SECOND CHARACTER TO BUFFER;012 INC MSGPTR ; AND BUMP BUFFER POINTER ;012 MOV (SP)+,R0 ;TIME FOR THE LAST CHARACTER BIC #<^C77>,R0 ;STRIP TO BITS <05:00> ADD #40,R0 ;ADJUST TO RANGE 40-137 MOVB R0,@MSGPTR ;MOVE THIRD CHARACTER TO BUFFER ;012 INC MSGPTR ; AND BUMP BUFFER POINTER ;012 30$: MOV (SP)+,R2 ;RESTORE THE WORK REGISTERS MOV (SP)+,R1 RTS PC .DSABL LSB .SBTTL DECODE - ASCII TO WORD CONVERTER ;+ ; ; DECODE ; Converts the three characters pointed to by R1 to a 16-bit ; word returned in R0 using the first character as bits <15:12>, ; the second as bits <11:06> and the third as bits <05:00>. ; The three character are ascii, so they must be reduced by ; 40(8). ; ; If compression encoding is being done and the character ; is 140(8) or greater, it is the single byte encoding of the ; offset into the table for the entry. ; ; CALL: ; R1 -> buffer area ; R3 = remaining message length (in bytes) ; ; RETURN: ; R0 = 16-bit word ; R1 = R1 + 3 (= R1 + 1 if a compression byte) ; R3 = R3 - 3 (= R3 - 1 if a compression byte) ; ICHECK = accumulated checksum ; ;- DECODE: MOVB (R1)+,R0 ;GET A CHARACTER DEC R3 ;REDUCE REMAINING MESSAGE LENGTH TST COMPFG ;IS COMPRESSION ENCODING IN EFFECT? BEQ 10$ ;NOPE, DECODE NORMALLY CMPB R0,#140 ;IS IT A COMPRESSION BYTE? BLO 10$ ;NOPE... ADD R0,ICHECK ;ACCUMULATE CHECKSUM SUB #140,R0 ;DETERMINE TABLE OFFSET ASL R0 ;SHIFT FROM WORD TO BYTE OFFSET MOV COMPTB(R0),R0 ;GET THE DECODED WORD INC COMPCT ;KEEP TRACK OF ENCODED BYTES BR 20$ 10$: SUB #40,R0 ;ADJUST TO RANGE 0-17 SWAB R0 ;MOVE TO HIGH BYTE ASL R0 ;AND SHIFT TO WHERE BITS BELONG ASL R0 ASL R0 ASL R0 MOV R0,-(SP) ;SAVE CURRENT CONVERSION RESULT MOVB (R1)+,R0 ;GET SECOND CHARACTER DEC R3 ;REDUCE REMAINING MESSAGE LENGTH SUB #40,R0 ;ADJUST TO RANGE 0-77 SWAB R0 ;MOVE TO HIGH BYTE ASR R0 ;AND SHIFT TO WHERE BITS BELONG ASR R0 BIS R0,(SP) ;MERGE WITH CURRENT RESULT MOVB (R1)+,R0 ;GET FINAL CHARACTER DEC R3 ;REDUCE REMAINING MESSAGE LENGTH SUB #40,R0 ;ADJUST TO RANGE 0-77 BIS (SP)+,R0 ; AND MERGE TO PRODUCE FINAL RESULT ADD R0,ICHECK ;ACCUMULATE THE CHECKSUM 20$: RTS PC .SBTTL CVBTOD - CONVERT BINARY TO DECIMAL ;011 ;011 ;+ ;011 ; ;011 ; CVBTOD ;011 ; Converts the binary value passed in R0 to a string of ;011 ; ascii characters which is the decimal equivalent and ;011 ; places them in the buffer pointed to by R1 ;011 ; ;011 ; CALL: ;011 ; R0 = 16-bit number ;011 ; R1 -> conversion buffer ;011 ; ;011 ; RETURNS: ;011 ; R0 = 0 ;011 ; R1 -> byte following last digit in converted number ;011 ; ;011 ;- ;011 ;011 CVBTOD: MOV R0,-(SP) ;SAVE THE NUMBER PASSED TO US ;011 CLR R0 ;SET FOR CRUDE DIVIDE BY 10. ;011 10$: INC R0 ;BUMP QUOTIENT ;011 SUB #10.,(SP) ;REDUCE NUMBER BY 10. ;011 BHIS 10$ ;IF SIGN DIDN'T CHANGE... ;011 ADD #10.+60,(SP) ;MAKE REMAINDER PRINTABLE ;011 DEC R0 ;REDUCE QUOTIENT ;011 BEQ 20$ ;IF ZERO, TIME TO PRINT ;011 JSR PC,CVBTOD ;OTHERWISE, RECURSE ! ;011 20$: MOVB (SP)+,(R1)+ ;STORE A CONVERTED DIGIT ;011 RTS PC ;UNWIND THE RECURSION ;011 .SBTTL CVFILE - CONVERT RAD50 FILENAME ;+ ; ; CVFILE ; Converts the RAD50 filespec pointed to by R0 to ascii ; characters placed in the buffer pointed to by R1. ; ; CALL: ; R0 -> RAD50 filespec block ; R1 -> buffer ; ; RETURN: ; R0 -> null byte following converted file name ; R1 -> converted file name ; ;- CVFILE: MOV R1,-(SP) ;SAVE STRING POINTER FOR LATER MOV R2,-(SP) ;WE NEED A TEMPORARY REGISTER MOV R0,R2 ;R2->NAME BLOCK (RAD50) MOV (R2)+,R0 ;GET DEVICE NAME CMP R0,#<^RDK > ;? BEQ 10$ ;YES, IGNORE IT JSR PC,CVRTOA ; CONVERT IT MOVB #':,(R1)+ ;ADD DELIMITER 10$: MOV (R2)+,R0 ;FIRST HALF OF FILENAME JSR PC,CVRTOA ; CONVERT IT MOV (R2)+,R0 ;SECOND HALF OF FILENAME JSR PC,CVRTOA ; CONVERT IT MOV (R2)+,R0 ;GET FILE TYPE BEQ 20$ ; IF ZERO, BYPASS IT AND DELIMITER MOVB #'.,(R1)+ ;ADD DELIMITER JSR PC,CVRTOA ; CONVERT FILE TYPE 20$: CLRB (R1) ;TERMINATE STRING MOV (SP)+,R2 ;RESTORE SAVED REGISTERS MOV (SP)+,R1 MOV R1,R0 ;R0->STRING TO COMPRESS JSR PC,COMPRS RTS PC .SBTTL CVRTOA - RAD50 TO ASCII CONVERTER ;+ ; ; CVRTOA ; Converts the RAD50 word in R0 to 3 ASCII characters placed ; in the buffer pointed to by R1. ; ; CALL: ; R0 = RAD50 word to convert ; R1 -> buffer to place converted characters ; ; RETURN: ; R0 = original R1 ; R1 -> byte following last converted character ; ;- CVRTOA: MOV R1,-(SP) ;SAVE SOME REGISTERS FIRST MOV R2,-(SP) MOV R1,R2 ;R2->BUFFER PASSED TO US MOV #3100,R1 ;FIRST CHARACTER IS JSR PC,DIVIDE ; QUOTIENT OF VALUE/3100 MOVB RADLST(R0),(R2)+ MOV R1,R0 ;SECOND CHARACTER IS MOV #50,R1 ; QUOTIENT OF PREVIOUS REMAINDER/50 JSR PC,DIVIDE MOVB RADLST(R0),(R2)+ MOVB RADLST(R1),(R2)+ ;THIRD CHARACTER IS REMAINDER MOV R2,R1 ;RETURN UPDATED BUFFER POINTER MOV (SP)+,R2 ;RESTORE SAVED REGISTER MOV (SP)+,R0 ;RETURN R0->STRING RTS PC .SBTTL COMPRS - SPACE COMPRESSION ROUTINE ;+ ; ; COMPRS ; Removes spaces from the string pointed to by R0. ; (compression ends on a <0> byte) ; ; CALL: ; R0 -> string to compress ; ; RETURN: ; R0 -> null byte at end of compressed string ; ;- COMPRS: MOV R1,-(SP) ;SAVE A REGISTER MOV R0,R1 10$: MOVB (R0)+,(R1) ;MOVE A CHARACTER BEQ 20$ CMPB (R1),#SPACE ;WAS IT A SPACE? BEQ 10$ ;YES, IGNORE IT INC R1 ;NO, THEN BUMP OUTPUT POINTER BR 10$ 20$: MOV R1,R0 ;RETURN POINTER TO END OF STRING MOV (SP)+,R1 ;RESTORE REGISTER RTS PC .SBTTL DIVIDE - DIVISION ROUTINE ;+ ; ; DIVIDE ; Divides the value in R0 by the value in R1 and returns ; the quotient in R0 and the remainder in R1. ; ;- DIVIDE: MOV R0,-(SP) ;SAVE THE NUMBER CLR R0 ;RESET QUOTIENT 10$: INC R0 ;BUMP QUOTIENT SUB R1,(SP) ;DIVISION DONE BY SUCCESSIVE SUBTRACTS BHIS 10$ ;DO UNTIL SIGN CHANGES ADD (SP)+,R1 ;CORRECT REMAINDER DEC R0 ;CORRECT QUOTIENT RTS PC .SBTTL DECOUT - DECIMAL OUTPUT ROUTINE ;+ ; ; DECOUT ; Prints the decimal ASCII respresentation of the binary number ; in R0. ; ;- DECOUT: MOV R0,-(SP) ;SAVE CURRENT NUMBER CLR R0 ;SET TO DIVIDE BY 10. 10$: INC R0 SUB #10.,(SP) BHIS 10$ ADD #10.+60,(SP) ;CORRECT DIGIT AND MAKE PRINTABLE DEC R0 ;CORRECT QUOTIENT BEQ 20$ ;IF ZERO, TIME TO PRINT JSR PC,DECOUT ;OTHERWISE, ! RECURSE ! 20$: .TTYOU (SP)+ ;PRINT A DIGIT RTS PC ;RETURN RECURSIVELY .SBTTL WILDCK - CHECK FOR WILDCARD CHARACTERS ;+ ; ; WILDCK ; Checks for and returns an indication of wildcard characters ; ('*' or '%') in the string pointed to by R0. ; ; CALL: ; JSR PC,WILDCK ; ; R0 -> string to check (terminated with a zero byte) ; ; RETURNS: ; c-bit = 0, no wildcards found ; c-bit = 1, wildcards found ; ;- WILDCK: TSTB (R0) ;END OF STRING? BEQ 10$ ;YES, NO WILDCARDS FOUND CMPB (R0),#'* ;IS THIS A WILDCARD CHARACTER? BEQ 20$ ;YES... CMPB (R0)+,#'% ;MAYBE, IS IT THE OTHER TYPE? BEQ 20$ ;YES... BR WILDCK ;TRY THE NEXT CHARACTER 10$: TST (PC)+ 20$: SEC RTS PC .SBTTL MESSAGE AREA .PSECT .TEXT. .NLIST BEX ; PROGRAM WELCOME MESSAGE M.ID: .NLCSI TYPE=I,PART=ALL PATLVL::.ASCII / / M.CRLF: .BYTE 0 M.CR: .BYTE 15,200 ;009 ; ERROR MESSAGE PREFIX FACILI: .NLCSI TYPE=I,PART=PREFIX SEVER: .ASCII /x-/<200> ; CSI AND INTERACTIVE MODE PROMPTS M.CSIP: .ASCII /*/<200> M.ORIG: .ASCII /Original is on Host or Terminal ? /<200> M.OHF: .ASCII /Name of original (Host) file? /<200> M.CTF: .ASCII /Name of file to create on Terminal M.OTF: .ASCII /Name of original (Terminal) file? /<200> M.CHF: .ASCII /Name of file to create on Host M.QUER: .ASCII /> ? /<200> ; PRE/POST TRANSFER INFORMATION M.CREA: .ASCII /Creating /<200> M.TT: .ASCII /_TT::/<200> M.DONE: .ASCII / created/ M.FROM: .ASCII / from /<200> ; TRANSFER STATISTICS MESSAGES M.3BEL: .BYTE BELL,BELL M.1BEL: .BYTE BELL,200 M.STAT: .ASCII / blocks transferred with /<200> M.RTR1: .ASCIZ / retry./ M.RTRY: .ASCIZ / retries./ M.COMP: .ASCIZ / characters saved through compression encoding./ ; RESPONSE COMPARISON STRINGS S.HOST: .ASCIZ /HOST/ ;DEFAULT S.TERM: .ASCIZ /TERMINAL/ ;ALTERNATIVE ; COMMUNICATIONS STRINGS M.APC: .BYTE ESC,'_,200 ;MESSAGE START M.ST: .BYTE ESC,'\,200 ;MESSAGE END ; RAD50 CONVERSION TABLE RADLST: .ASCII / ABCDEFGHIJKLMNOPQRSTUVWXYZ$.%0123456789/ ; MESSAGE CODES CODES$: .ASCIZ /sr01zxy/ ; TERMINAL STATE STRINGS FOR TSX PLUS M.TSXS: .BYTE CTRL.M,'S ;SINGLE-CHARACTER ACTIVATION MODE ON .BYTE CTRL.M,'W ;TAPE MODE ON .BYTE 200 M.TSXR: .BYTE CTRL.M,'T ;SINGLE-CHARACTER ACTIVATION MODE OFF .BYTE CTRL.M,'X ;TAPE MODE OFF .BYTE 200 .EVEN .LIST BEX .SBTTL IMPURE DATA AREA .PSECT .DATA. LIMITS: .LIMIT ;PROGRAM LIMITS LOMEM = LIMITS+2 TMPSTR: .BLKB 32. ;TEMPORARY STRING SPACE ; COMMAND/RESPONSE INFORMATION CMDLIN: .BLKB 134. ;COMMAND/RESPONSE BUFFER SPSAVE: .BLKW ;SAVED STACK POINTER PROMPT: .BLKW ; : INTERACTIVE MODE PROMPTING BELLS: .BLKW ; : BELLS ON ERRORS IN /LOG LOG: .BLKW ;= 0 /NOLOG, <> 0 /LOG FILSPC: OSPEC: .BLKW 3*5 ;OUTPUT FILE SPECS ISPEC: .BLKW 6*4 ;INPUT FILE SPECS ISIZE: .BLKW ;INPUT FILE SIZE (BLOCKS) IFILE: .BLKW 4 ;INPUT FILE NAME OFILE: .BLKW 4 ;OUTPUT FILE NAME DEFEXT: .WORD 0,0,0,0 ;DEFAULT FILE TYPES ; TRANSFER INFORMATION DIRECT: .BLKW ;TRANSFER DIRECTION ; 0 = HOST->REMOTE ; 2 = REMOTE->HOST BLOCKS: .BLKW ;BLOCKS TRANSFERRED ERRORC: .BLKW ;ERRORS ENCOUNTERED MSGNUM: .BLKW ;MESSAGE TOGGLE BLKSIZ: .BLKW ;MESSAGE SIZE OFFSET: .BLKW ;BLOCK OFFSET (FOR SPLIT BLOCKS) ERROFG: .BLKW ; : Block transfer error flag REQSCT: .BLKW ; : 'Required success count' CURSCT: .BLKW ; : 'Current success count' ; TTY/JOB INFORMATION ;009 ;009 OJSW: .BLKW ;OLD JSW CONTENTS OTTCNF: .BLKW ;OLD CONFIGURATION WORD CONTENTS;008 TSXFLG: .BLKW ;TSX FLAG JOBINF: ;009 J.JNUM: .BLKW ;JOB NUMBER ;009 J.HIGH: .BLKW ;JOB'S HIGH MEMORY LIMIT ;009 J.LOW: .BLKW ;JOB'S LOW MEMORY LIMIT ;009 J.CHAN: .BLKW ;POINTER TO I/O CHANNEL SPACE ;009 J.IMP: .BLKW ;POINTER TO JOB'S IMPURE AREA ;009 J.LUN: .BLKB ;LUN OF JOB'S TERMINAL ;009 .BLKB ;RESERVED ;009 J.VIRT: .BLKW ;JOB'S VIRTUAL HIGH LIMIT ;009 .BLKW 2 ;RESERVED ;009 J.NAME: .BLKW 3 ;LOGICAL JOB NAME (ASCII) ;009 ;009 MTSTAT: ;009 M.TSTS: .BLKW ;TERMINAL CONFIGURATION WORD 1 ;009 M.TST2: .BLKW ;TERMINAL CONFIGURATION WORD 2 ;009 M.TFIL: .BLKB ;CHARACTER REQUIRING FILLERS ;009 M.FCNT: .BLKB ;FILLER COUNT ;009 M.TWID: .BLKB ;CARRAIGE WIDTH ;009 M.TSTW: .BLKB ;TERMINAL STATUS BYTE ;009 ;009 ; EMT BLOCKS AREA: .BLKW 10. ;FOR EMTS OTHER THAN TIMER REQUESTS MAREA: .BLKW 4 ;FOR MARK-TIME REQUESTS TIME: .BLKW 2 ;TIME-OUT INTERVAL TAREA: .BLKW 2 ;FOR TIMED-WAIT REQUESTS TIMBLK: .WORD 0 ; SLEEP TIME .WORD 2 ; 1/30 SECOND (ENOUGH TIME FOR 32 ; CHARACTERS AT 9600 BAUD) CCSTAT: .WORD 0 ;^C STATUS WORD ; CHECKSUM INFORMATION OCHECK: .BLKW ;OUT-GOING MESSAGE CHECKSUM ICHECK: .BLKW ;IN-COMING MESSAGE CHECKSUM ; BUFFERS IBUF: .BLKW 256. ;HOST INPUT FILE BUFFER OBUF: .BLKW 256. ;HOST OUTPUT FILE BUFFER ;*** Begin critical ordering PREFIX: .BLKB ;FOR INCOMING MESSAGE IDENTIFICATION .BLKB ;*** End critical ordering ;*** Begin critical ordering CODE$: .BLKB SECND$: .BLKB ;*** End critical ordering CODE: .BLKW ;INCOMING MESSAGE CODE VALUE MSGLEN: .BLKW ;INCOMING MESSAGE LENGTH (WORDS) ERRCOD: .WORD 5 ;MESSAGE CODES WHICH ARE ERRORS .WORD 6 .WORD 8. .WORD 9. .WORD 10. .WORD 11. .WORD 12. .WORD 13. .WORD 14. .WORD 15. .WORD 24. .WORD 0 ;TABLE FENCE ; Compression encoding information COMPCT: .BLKW ;COUNT OF COMPRESSION BYTES USED COMPFG: .BLKW ; : COMPRESSION ENCODING FLAG COMPSZ::.WORD COMPTE ;COUNT OF ENTRIES IN TABLE COMPTB::.WORD 0 ;ZERO WORD (BINARY) .WORD 4767 ;JSR PC,--- (BINARY) .WORD 207 ;RTS PC (BINARY) .WORD 167 ;JMP --- (BINARY) .WORD 16746 ;MOV ---,-(SP) (BINARY) .WORD CR+ ; (ASCII) .WORD SPACE+ ; (ASCII) .WORD TAB+ ; (ASCII) .WORD LF+ ; (ASCII) COMPTE = <.-COMPTB>/2 .BLKW 37-<<.-COMPTB>/2> ;DECLARE SPACE FOR REST OF TABLE MSGPTR: .WORD MSGBUF ;OUTGOING MESSAGE BUFFER POINTER;012 ;012 MSGBUF: .BLKB 2+<512.*3/2>+3 ;INCOMING MESSAGE BUFFER ; MUST BE LARGE ENOUGH TO CONTAIN ; THE LARGEST POSSIBLE INCOMING ; MESSAGE (WHICH WOULD CONSIST OF ; TWO BYTES OF CODE INFO, 512. ; ENCODED BYTES (3 FOR 2), AND ; THREE BYTES FOR THE CHECKSUM) .EVEN DECBUF: .BLKW 256. ;DECODED MESSAGE BUFFER .END TRANSF