.TITLE PMR - PASSTHROUGH TASK .IDENT /V01.09/ ; ; COPYRIGHT (C) 1980 BY ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ; ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND 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. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY ; TRANSFERRED. ; ; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE ; AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT ; CORPORATION. ; ; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ; SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. ; ; ; MODULE DESCRIPTION: ; ; POOR MAN'S ROUTING PASSTHROUGH TASK ; ; ; DISTRIBUTED SYSTEMS SOFTWARE ENGINEERING ; ; IDENT HISTORY: ; ; 1.00 13-JUN-80 J. A. SCHRIESHEIM ; ; 1.01 17-JUN-80 ; SUPPORT FOR ACCESS CONTROL ; ; 1.02 19-JUN-80 ; MULTI-BUFFER I/O, HANDLE INTERRUPT MESSAGES ; ; 1.03 27-JUN-80 ; RETURN ADDITIONAL ERROR MESSAGES ; ; 1.04 2-JUL-80 ; MOVED NAME TRANSLATION CODE INTO "PMRTRN" ; ; 1.05 8-JUL-80 ; SET EXIT FLAG DURING LINK ABORT PROCESSING ; ; 1.06 1-OCT-80 ; RETURNED LOCAL NODE NAME IN ERROR MESSAGES ; ; 1.07 11-DEC-80 ; ADDED LOGGING SUPPORT ; ; 1.08 15-DEC-80 ; ONLY SPEAK PMR PROTOCOL IF NAME IS "PMR". ; ELSE, CONNECT TO TARGET TASK ON TARGET NODE. (USE PMR AS A LOGGER) ; ; 1.09 8-JAN-81 ; SUPPORT FOR OPTIONAL DATA WHEN USING PMR AS A LOGGER ; .SBTTL MACRO CALLS AND LOCAL DATA ; ; MACRO LIBRARY CALLS ; .MCALL ALUN$,DIR$,EXIT$S,WTSE$,SETF$,ASTX$S,WSIG$S .MCALL OPNW$,CLSW$,GNDW$,ACCW$,NETDF$,RECW$,SNDW$,REC$,SND$,DSCW$ .MCALL REJW$,ABTW$,SPAW$,XMIW$,GLNW$ NETDF$ ; DEFINE NETWORK SYMBOLS PM$LOG=0 ; ENABLE LOGGING SUPPORT ; ; LOCAL MACROS ; .MACRO BUFF N ; DEFINE A BUFFER .BLKW 2 .IF GE <-N> .BYTE INLUN,OULUN .IFF .BYTE OULUN,INLUN .ENDC BUFF'N::.BLKB BUFSIZ .ENDM BUFF .MACRO DIRW$ DPB ; EXECUTE A DIRECTIVE AND MOV DPB,-(SP) ; ... WAIT FOR RESOURCES CALL .DIRW .ENDM DIRW$ .MACRO LOG OFFSET,?LBL ; LOG A MESSAGE .IF DF PM$LOG MOV LOGBLK,-(SP) ; GET THE LOGGING BLOCK ADDRESS BEQ LBL ; IF EQ, LOGGING NOT ACTIVE ADD #OFFSET,(SP) ; POINT TO TABLE ENTRY MOV @(SP),(SP) ; GET ROUTINE POINTER CALL @(SP) ; CALL ROUTINE LBL: TST (SP)+ ; CLEAN OFF STACK .ENDC .ENDM LOG ; ; LOCAL DEFINITIONS ; MBLUN==1 ; LUN FOR NETWORK MAILBOX INLUN==2 ; LUN FOR INCOMING LINK OULUN==3 ; LUN FOR OUTGOING LINK FILUN==4 ; LUN FOR FILE ACCESS NTEFN==1 ; FLAG FOR GENERAL NETWORK I/O INEFN==2 ; FLAG FOR INCOMING LINK OUEFN==3 ; FLAG FOR OUTGOING LINK EXEFN==4 ; FLAG TO SYNCHRONIZE TASK EXIT BUFSIZ==1024. ; BUFFER SIZE NUMBUF==4 ; NUMBER OF BUFFERS ; ; LOGGING DESCRIPTOR BLOCK OFFSETS ; .ASECT .=0 LG.INI::.BLKW 1 ; INITIALIZE PMR LOGGING LG.SRC::.BLKW 1 ; LOG SOURCE ROUTINE LG.DES::.BLKW 1 ; LOG DESTINATION ROUTINE LG.STA::.BLKW 1 ; LOG CONNECT STATUS ROUTINE LG.DAT::.BLKW 1 ; LOG DATA MESSAGE ROUTINE LG.INT::.BLKW 1 ; LOG INTERRUPT MESSAGE ROUTINE LG.DSC::.BLKW 1 ; LOG DISCONNECT ROUTINE LG.CLS::.BLKW 1 ; LOG FILE CLOSE ROUTINE .PSECT DATA$P D,RO ; PURE DATA ; ; RSX DPBS ; ALUN1: ALUN$ MBLUN,NS ; ASSIGN MAILBOX LUN ALUN2: ALUN$ INLUN,NS ; ASSIGN LUN FOR INITIATING LINK ALUN3: ALUN$ OULUN,NS ; ASSIGN LUN FOR FORWARDING LINK WTSE: WTSE$ EXEFN ; WAIT FOR EXIT FLAG SETF: SETF$ EXEFN ; SET EXIT FLAG ; ; DECNET DPBS ; OPN: OPNW$ MBLUN,NTEFN,NTSB,,<1> ; OPEN MAILBOX GLN: GLNW$ MBLUN,NTEFN,NTSB,, ; GET LOCAL NODE NAME CLS: CLSW$ MBLUN,NTEFN ; CLOSE MAILBOX GND: GNDW$ MBLUN,NTEFN,NTSB,,; GET NETWORK DATA SPA: SPAW$ MBLUN,NTEFN,NTSB,, ; SPECIFY NETWORK DATA AST INDSC: DSCW$ INLUN,INEFN ; DISCONNECT INITIATING LINK OUDSC: DSCW$ OULUN,OUEFN ; DISCONNECT FORWARDING LINK INABT: DSCW$ INLUN,INEFN ; ABORT INITIATING LINK OUABT: DSCW$ OULUN,OUEFN ; ABORT FORWARDING LINK PMRREC: RECW$ INLUN,INEFN,NTSB,,; PASSTHROUGH MESSAGE RECEIVE .PSECT DATA$I D,RW ; IMPURE DATA ACC: ACCW$ INLUN,NTEFN,NTSB,,; ACCEPT CONNECT REQUEST REJ: REJW$ MBLUN,NTEFN,NTSB,,; REJECT CONNECT REQUEST PMRSND: SNDW$ INLUN,INEFN,NTSB,, ; PASSTHROUGH STATUS RETURN REC: REC$ ,,,RECAST,<,BUFSIZ> ; RECEIVE SND:: SND$ ,,,SNDAST ; TRANSMIT XMI:: XMIW$ ,NTEFN,NTSB,, ; TRANSMIT INTERRUPT ; ; CONNECT DATA ; CONBLK: .BYTE OULUN,OUEFN ; LUN AND EVENT FLAG FOR CONNECT .BLKB 1 ; CURRENT HOP COUNT .BLKB 1 ; OBJECT TYPE .BLKW 1 ; POINTER TO NODE NAME LIST .BLKW 1 ; POINTER TO TARGET TASK NAME .BLKW 1 ; POINTER TO ACCESS CONTROL ; ; ERROR CODE MAPPING TABLE ; .PSECT DATA$P D,RO NSPTBL: .WORD NE$RES,RESERR ; RESOURCE ERROR .WORD NE$NOD,NODERR ; UNRECOGNIZED NODE NAME .WORD NE$NSR,NSRERR ; REMOTE NODE SHUT DOWN .WORD NE$UOB,UOBERR ; UNRECOGNIZED OBJECT .WORD NE$FMT,FMTERR ; INVALID OBJECT NAME FORMAT .WORD NE$MLB,MLBERR ; OBJECT TOO BUSY .WORD NE$ABM,ABMERR ; ABORT BY MANAGEMENT .WORD NE$NNF,NNFERR ; INVALID NODE NAME FORMAT .WORD NE$ACC,ACCERR ; ACCESS CONTROL REJECT .WORD NE$ABO,ABOERR ; NO RESPONSE FROM OBJECT .WORD NE$COM,COMERR ; NODE UNREACHABLE .WORD 0 ; END-OF-TABLE ; ; ERROR MESSAGE STRINGS ; .ENABL LC .NLIST BEX RESERR: .ASCIZ /(#) Insufficient network resources at %/ NODERR: .ASCIZ /(#) "%" is an unrecognized node name/ NSRERR: .ASCIZ /(#) Node % is shutting down/ UOBERR: .ASCIZ /(#) Unrecognized object at %/ FMTERR: .ASCIZ /(#) Object name format invalid at %/ MLBERR: .ASCIZ /(#) Object too busy at %/ ABMERR: .ASCIZ /(#) Abort by management at %/ NNFERR: .ASCIZ /(#) Invalid node name format -- %/ ACCERR: .ASCIZ /(#) Access control rejected at %/ ABOERR: .ASCIZ /(#) No response from object at %/ COMERR: .ASCIZ /(#) Node % is unreachable/ .EVEN ; ; MISC. STORAGE ; .PSECT DATA$I D,RW NTSB:: .BLKW 2 ; I/O STATUS BLOCKS PMRFLG::.BYTE 1 ; FLAG IF USING "PASSTHROUGH PROTOCOL" ; 0 = NO, 1 = YES (DEFAULT) VERSTA::.BLKB 1 ; INCOMING CONNECT VERIFICATION STATUS LOGBLK::.WORD PMRLOG ; ADDRESS OF LOGGING BLOCK ; (0 = NOT SUPPORTED) LOCNAM::.REPT 5 ; BUFFER FOR LOCAL NODE NAME .WORD " .ENDR SBUFF:: .BLKB N.CBL+16. ; SMALL BUFFER N=1 BUFFS: .REPT NUMBUF ; REC/SND DATA BUFFERS BUFF \N N=N+1 .ENDR .LIST BEX .SBTTL PMR - PASSTHROUGH TASK MAIN LINE ;+ ; **-PMR- PASSTHROUGH TASK MAIN LINE OF CODE ; ; ESTABLISH A CONNECTION TO THE NEXT NODE IN THE PATH, AND FORWARD ; DATA RECEIVED FROM EITHER END. ; ;- .PSECT CODE$ I,RO ; PURE CODE PMR:: ; ; PREFORM PREAMBLE ; CALL INIT ; INITIALIZE, GET INCOMING CONNECT BCS 100$ ; IF CS, EXIT CALL GETMES ; GET AND PROCESS THE PMR MESSAGE BCS 100$ ; IF CS, ERROR TST #PMRTRN ; IS NAME TRANSLATION SUPPORTED ? BEQ 5$ ; IF EQ, NO - SKIP IT CALL PMRTRN ; ELSE, TRANSLATE THE FIRST NODE NAME 5$: LOG LG.SRC ; WRITE THE SOURCE DESCRIPTOR LOG LG.DES ; WRITE THE DESTINATION DESCRIPTOR CALL CONECT ; TRY THE CONNECT BCS 100$ ; IF CS, CAN'T PASSTHROUGH DIRW$ #SPA ; SPECIFY NETWORK DATA AST BCS 100$ ; IF CS, EXIT ; ; HANG RECEIVES ON ALL BUFFERS ; MOV #BUFFS,R0 ; POINT TO FIRST BUFFER MOV #NUMBUF,R1 ; SET NUMBER OF BUFFERS 10$: CALL HNGREC ; HANG A RECEIVE ADD #BUFSIZ+6,R0 ; POINT TO NEXT BUFFER DEC R1 ; LOOP TILL DONE FOR ALL BNE 10$ ; ... ; ; WAIT TILL EXIT FLAG IS SET ; DIR$ #WTSE ; AND WAIT FOR THE FLAG 100$: DIRW$ #INDSC ; DISCONNECT THE INCOMING LINK DIRW$ #CLS ; CLOSE THE MAILBOX LOG LG.CLS ; CLOSE THE LOG FILE EXIT$S ; ... AND EXIT .SBTTL INIT - OPEN MAILBOX, GET INCOMING CONNECT ;+ ; **-INIT-INITIAIZE PMR, OPEN MAILBOX AND GET INCOMING CONNECT ; ; THIS ROUTINE ACCESSES THE NETWORK, GETS AND ACCEPTS THE INCOMING ; CONNECT REQUEST. ; ; - INIT: ; ; OPEN ACCESS TO NETWORK ; 5$: DIR$ #ALUN1 ; ASSIGN NETWORK LUN BCS 100$ ; IF CS, EXIT DIR$ #ALUN2 ; ASSIGN INCOMING LUN BCS 100$ ; IF CS, EXIT DIR$ #ALUN3 ; ASSIGN OUTGOING LUN BCS 100$ ; IF CS, EXIT DIRW$ #OPN ; OPEN OUR MAILBOX BCS 100$ ; IF CS, COULDN'T - GO AWAY TSTB NTSB ; ... BMI 99$ ; ... MOVB NTSB+2,VERSTA ; SAVE THE VERFICATION STATUS DIRW$ #GLN ; GET THE LOCAL NODE NAME BCS 100$ ; IF CS, COULDN'T MOV #LOCNAM,R0 ; POINT TO LOCAL NAME 10$: CMPB (R0)+,#' ; LOOK FOR END OF NAME BNE 10$ ; ... CLRB 1(R0) ; MAKE NODE NAME ASCIZ MOVB #':,(R0) ; PUT TERMINATOR AFTER NODE NAME MOVB (R0),-(R0) ; ... ; ; GET AND ACCEPT INCOMING CONNECT ; DIRW$ #GND ; GET THE NETWORK DATA BCS 100$ ; IF CS, ERROR TSTB NTSB ; GET DATA ? BMI 99$ ; IF MI, NO - ERROR CMPB NTSB+1,#NT.CON ; CONNECT REQUEST ? BNE 99$ ; IF NE, NO - ERROR DIRW$ #ACC ; ELSE, TRY TO ACCEPT IT BCS 99$ ; IF CS, ERROR TSTB NTSB ; SUCCESSFUL ACCEPT ? BMI 99$ ; IF MI, NO - ERROR TST (PC)+ ; CLEAR-C AND RETURN 99$: SEC ; INDICATE ERROR 100$: RETURN .SBTTL NDAST - NETWORK DATA AST ROUTINE ;+ ; **-NDAST-NETWORK DATA AST SERVICE ROUTINE ; ; THIS ROUTINE IS CALLED TO PROCESS NETWORK DATA. ; ;- NDAST: 10$: DIRW$ #GND ; GET NETWORK DATA TSTB NTSB ; WAS THERE ANY DATA? BMI 100$ ; IF MI, NO - ALL DONE MOVB NTSB+1,R0 ; ELSE, GET DATA TYPE ASL R0 ; CONVERT TO WORD OFFSET CALL @GNDTAB-2(R0) ; DISPATCH TO CORRECT ROUTINE BR 10$ ; LOOK FOR MORE DATA 100$: ASTX$S ; EXIT THE AST ; ; NETWORK DATA DISPATCH TABLE ; GNDTAB: .WORD GNDCON ; CONNECT REQUEST .WORD GNDINT ; INTERRUPT MESSAGE .WORD GNDDSC ; DISCONNECTS .WORD GNDABO ; ABORTS .WORD GNDABO ; .. .WORD GNDPEM ; NETWORK EVENT .SBTTL GNDCON - PROCESS CONNECT REQUEST .SBTTL GNDINT - PROCESS INTERRUPT MESSAGE .SBTTL GNDDSC - PROCESS DISCONNECT .SBTTL GNDABO - PROCESS ABORT .SBTTL GNDPEM - PROCESS NETWORK EVENT ;+ ; **-GNDCON-PROCESS CONNECT REQUEST ; ; ALL INCOMING ACCEPTS ARE DROPPED ; ;- GNDCON: RETURN ;+ ; **-GNDINT-PROCESS INTERRUPT MESSAGE ; ; ALL INCOMING INTERRUPT MESSAGES ARE TRANSMITTED OVER THE ; OPPOSITE LINK. ; ;- GNDINT: MOV #OULUN,XMI+Q.IOLU ; ASSUME XMI OVER OULUN CMPB NTSB+3,#INLUN ; RECEIVED OVER INLUN ? BEQ 10$ ; IF EQ, YES - XMI OVER OULUN MOV #INLUN,XMI+Q.IOLU ; ELSE USE INLUN 10$: MOVB NTSB+2,XMI+Q.IOPL+2 ; SET LENGTH OF DATA LOG LG.INT ; LOG THE INTERRUPT MESSAGE DIRW$ #XMI ; TRANSMIT IT RETURN ;+ ; **-GNDDSC-PROCESS DISCONNECT ; ; DISCONNECTS ARE HANDLED BY DISCONNECTING THE OPPOSITE LINK. ; ;- .ENABL LSB GNDDSC: DIRW$ #INDSC ; DISCONNECT BOTH (TO MAKE SURE) DIRW$ #OUDSC ; ... BR 10$ ; SET THE EXIT FLAG AND RETURN ;+ ; **-GNDABO-PROCESS ABORT ; ; ABORTS ARE HANDLED BY ABORTING THE OPPOSITE LINK. ; ;- GNDABO: DIRW$ #INABT ; ABORT BOTH (TO MAKE SURE) DIRW$ #OUABT ; ... 10$: LOG LG.DSC ; LOG THE ABORT DIR$ #SETF ; SET THE EXIT FLAG RETURN .DSABL LSB ;+ ; **-GNDPEM-PROCESS NETWORK EVENT ; ; ALL NETWORK EVENTS RECEIVED ARE IGNORED ; ;- GNDPEM: RETURN ; TOSS IT .SBTTL GETMES - GET AND PROCESS THE PASSTHROUGH MESSAGE ;+ ; **-GETMES-GET AND PROCESS THE PASSTHROUGH MESSAGE ; ; THIS ROUTINE RECEIVES AND PARSES THE PASSTHROUGH MESSAGE. ; IF THE TASK IS BEING USED AS A "LOGGER", THEN A FAKE MESSAGE ; IS CONSTRUCTED. THE PARSED FIELDS ARE SET INTO THE CONNECT ; PARAMETER BLOCK. ; ; ; OUTPUTS: ; R5 = ADDRESS OF CONNECT BLOCK WITH: ; P$HOP(R5) = HOP COUNT (UPDATED) ; P$OBJ(R5) = TARGET OBJECT TYPE ; P$NOD(R5) = POINTER TO ASCIZ NODE NAME STRING ; P$NAM(R5) = POINTER TO ASCIZ TASK NAME STRING ; P$ACS(R5) = POINTER TO 3 ASCIZ ACCESS CONTROL STRINGS ;- GETMES: ; ; GET THE PMR MESSAGE IF RUNNING THE PROTOCOL, ELSE GET A "FAKE" MESSAGE ; LOG LG.INI ; INIT LOGGING, FORMAT "FAKE" MESSAGE ; IF WE ARE BEING USED FOR LOGGING ONLY TSTB PMRFLG ; ARE WE RUNNING THE PMR PROTOCOL ? BEQ 4$ ; IF EQ, NO - USE SUPPLIED MESSAGE DIRW$ #PMRREC ; RECEIVE THE PASSTHROUGH MESSAGE BCS 100$ ; IF CS, ERROR TSTB NTSB ; SUCCESS ? BMI 99$ ; IF MI, NO - RETURN MOV #BUFF1,R0 ; POINT TO THE BUFFER 4$: MOV R0,R5 ; ... MOV #BUFF3,R1 ; SET UP FOR A COPY FOR LOGGING MOV NTSB+2,R2 ; GET THE LENGTH 5$: MOVB (R5)+,(R1)+ ; MAKE A COPY DEC R2 ; ... BNE 5$ ; ... CLRB (R1) ; MAKE COPY ASCIZ ; ; PARSE THE MESSAGE ; MOV #CONBLK,R5 ; POINT TO THE CONNECT PARAMETER BLOCK MOVB (R0)+,P$HOP(R5) ; SET THE HOP COUNT INCB P$HOP(R5) ; ... BUMP IT TO INCLUDE US MOV R0,P$NOD(R5) ; SAVE THE NODE NAME STRING POINTER CLR P$ACS(R5) ; ASSUME NO ACCESS CONTROL TO PASS 10$: CMPB (R0)+,#'" ; LOOK FOR DELIMITER BNE 10$ ; ... CMPB -2(R0),#': ; IS THIS THE TARGET DESCRIPTOR ? BEQ 40$ ; IF EQ, YES MOV R0,R1 ; ELSE, NO - ACS STRING, COPY POINTER MOV #SBUFF,R2 ; POINT TO ACS BUFFER MOV R2,P$ACS(R5) ; SET POINTER IN CONBLK 20$: MOVB (R1)+,R3 ; GET NEXT ACS CHAR CMPB R3,#'" ; END OF ACS STRING ? BEQ 30$ ; IF EQ, YES CLRB (R2)+ ; ASSUME END OF STRING CMPB R3,#' ; IS IS A DELIMITER ? BEQ 20$ ; IF EQ, YES - LEAVE NULL MOVB R3,-1(R2) ; ELSE, PUT IT IN THE BUFFER BR 20$ ; ... LOOK AT NEXT 30$: CLRB (R2)+ ; MAKE SURE ALL TERMINATORS ARE THERE CLRB (R2)+ ; ... CLRB (R2)+ ; ... MOVB (R1)+,-1(R0) ; PUT "::" AFTER NODE NAME LIST MOVB (R1)+,(R0)+ ; ... CLRB (R0) ; MAKE THE LIST ASCIZ MOV R1,R0 ; POINT PAST "::" IN STRING BR 10$ ; AND LOOK FOR TARGET DESCRIPTOR 40$: CLRB -1(R0) ; MAKE NODE NAME LIST ASCIZ CALL $CDTB ; CONVERT OBJECT TYPE TO BINARY MOVB R1,P$OBJ(R5) ; SET TARGET OBJECT TYPE BNE 100$ ; IF NE, NO NEED TO SET UP NAME MOV R0,P$NAM(R5) ; ELSE, SET ADDRESS OF NAME STRING 50$: CMPB (R0)+,#'" ; LOOK FOR END OF TARGET DESCRIPTOR BNE 50$ ; ... CLRB -(R0) ; MAKE NAME STRING ASCIZ BR 100$ ; AND RETURN 99$: SEC ; INDICATE ERROR 100$: RETURN .SBTTL CONECT - CONNECT TO NEXT PMR TASK ;+ ; **-CONECT-CONNECT TO NEXT PMR TASK ; ; THIS ROUTINE CONNECTS TO THE NEXT TASK IN THE CHAIN, AND IF ; THE PMR PROTOCOL IS RUNNING (PMRFLG=1), RETURNS AN ACK/NAK ; MESSAGE TO THE PREVIOUS TASK. ; ; INPUTS: ; R5 = ADDRESS OF CONNECT PARAMETER BLOCK ; ; OUTPUTS: ; C-SET ON ERROR ; ;- CONECT: ; ; CONNECT USING THE PMRCON SUBROUTINE ; CALL $CONN ; FORWARD THE CONNECT ; ; FORMAT THE ACK/NAK STATUS MESSAGE ; MOV #BUFF1,R0 ; POINT TO THE BUFFER MOVB #1,(R0)+ ; ASSUME ACK TO SEND MOV #$PATH,R1 ; ASSUME PATH TO RETURN BCC 10$ ; IF CS, RETURN ACK (WITH PATH) INCB -1(R0) ; ELSE, RETURN NAK MOV #$ERROR,R1 ; ASSUME RETURNED ERROR TEXT MOVB $STAT,R2 ; GET STATUS CODE BEQ 10$ ; IF EQ, NOT A LOCAL ERROR CMPB R2,#IE.NRJ ; ELSE, WAS IT A NETWORK REJECT ? BNE 10$ ; IF NE, NO - USE SUPPLIED ERROR MOVB $STAT+2,R2 ; ELSE, GET SECONDARY REASON MOV #NSPTBL,R3 ; POINT TO NSP ERROR TABLE 5$: TST (R3) ; AT END OF TABLE ? BEQ 10$ ; IF EQ, YES CMP R2,(R3)+ ; ELSE, DOES THE ERROR CODE MATCH ? BEQ 7$ ; IF EQ, YES - USE THIS TEXT TST (R3)+ ; ELSE, POP OVER TEXT POINTER BR 5$ ; AND LOOK AT NEXT ERROR CODE 7$: MOV (R3),R1 ; COPY TEXT POINTER 10$: MOVB (R1)+,R2 ; GET NEXT BYTE BEQ 40$ ; IF EQ, FINISHED MOV #$PATH,R3 ; ASSUME NODE PATH TO BE INCLUDED CMPB R2,#'% ; INCLUDE NODE PATH HERE ? BEQ 20$ ; IF EQ, YES MOV #LOCNAM,R3 ; ASSUME LOCAL NAME TO BE INCLUDED CMPB R2,#"# ; INSERT LOCAL NAME HERE ? BNE 30$ ; IF NE, NO 20$: MOVB (R3)+,(R0)+ ; ELSE, COPY STRING BNE 20$ ; ... DEC R0 ; BACK OVER TRAILING NULL BR 10$ ; AND LOOK AT NEXT CHAR 30$: MOVB R2,(R0)+ ; COPY MESSAGE INTO BUFFER BR 10$ ; AND LOOK AT NEXT CHAR 40$: CLRB (R0) ; MAKE STRING ASCIZ (FOR LOGGING) SUB #BUFF1,R0 ; CALC BUFFER LENGTH MOV R0,PMRSND+Q.IOPL+2 ; SET MESSAGE LENGTH ; ; SEND THE MESSAGE IF RUNNING THE PMR PROTOCOL (ELSE, JUST LOG IT) ; TSTB PMRFLG ; SHOULD WE SEND THE PROTOCOL MESSAGE ? BEQ 50$ ; IF EQ, NO - JUST RETURN C-BIT ERROR DIRW$ #PMRSND ; SEND THE ACK/NAK BCS 100$ ; IF CS, RETURN WITH ERROR TSTB NTSB ; GET THERE OK ? BMI 99$ ; IF MI, NO - ERROR 50$: CMPB BUFF1,#1 ; DID WE SEND AN ACK ? BEQ 100$ ; IF EQ, YES - RETURN WITH C-CLEAR 99$: SEC ; ELSE, RETURN WITH ERROR 100$: ROR (SP) ; SAVE C-BIT LOG LG.STA ; LOG STATUS ROL (SP) ; RESTORE C-BIT RETURN .SBTTL RECAST - RECEIVE DATA AST ;+ ; **-RECAST-RECEIVE DATA AST ; ; IF AN ERROR OCCURED, THE EXIT FLAG IS SET. ELSE, THE DATA RECEIVED IS ; FORWARDED OVER THE OTHER LUN. ; ;- .ENABL LSB RECAST: MOV (SP)+,R0 ; GET IOSB ADDRESS TSTB (R0) ; RECEIVE IN ERROR ? BMI SETFLG ; IF MI, YES - SET EXIT FLAG MOV R0,SND+Q.IOSB ; ELSE, SET IOSB FOR SND$ MOV 2(R0),SND+Q.IOPL+2 ; SET LENGTH OF DATA TO SEND MOVB 5(R0),SND+Q.IOLU ; SET SND LUN MOV R0,SND+Q.IOPL ; SET BUFFER ADDRESS ADD #6,SND+Q.IOPL ; ... LOG LG.DAT ; LOG THE DATA DIRW$ #SND ; SEND THE DATA BCC 100$ ; IF CC, NO ERROR SETFLG: DIR$ #SETF ; ELSE, SET THE EXIT FLAG 100$: ASTX$S ; EXIT THE AST RETURN ; RETURN IF CALLED AS SUBROUTINE .DSABL LSB .SBTTL SNDAST - XMIT AST FOR DATA RECEIVED .SBTTL HNGREC - HANG A RECEIVE ON A BUFFER ;+ ; **-SNDAST-XMIT AST FOR DATA RECEIVED ; **-HNGREC-HANG A RECEIVE ON A BUFFER ; ; IF AN ERROR OCCURED, THE EXIT FLAG IS SET. ELSE, ANOTHER RECEIVE REQUEST ; IS ISSUED. ; ;- SNDAST: MOV (SP)+,R0 ; GET IOSB ADDRESS TSTB (R0) ; XMIT IN ERROR ? BMI SETFLG ; IF MI, YES - SET EXIT FLAG HNGREC: MOV R0,REC+Q.IOSB ; SET IOSB ADDRESS MOVB 4(R0),REC+Q.IOLU ; SET LUN FOR RECEIVE MOV R0,REC+Q.IOPL ; SET BUFFER ADDRESS ADD #6,REC+Q.IOPL ; ... DIRW$ #REC ; ISSUE RECEIVE BCS SETFLG ; IF CS, SET EXIT FLAG ASTX$S ; EXIT THE AST RETURN ; RETURN IF CALLED AS SUBROUTINE .SBTTL .DIRW - EXECUTE A DIRECTIVE ;+ ; **-.DIRW-EXECUTE A DIRECTIVE ; ; THIS ROUTINE EXECUTES A DIRECTIVE. IF THE DIRECTIVE FAILS ; DUE TO LACK IF RESOURCES, THE DIRECTIVE WILL BE RE-EXECUTED ; AFTER A SIGNIFICANT EVENT. ; ; INPUTS: ; 2(SP) = ADDRESS OF DPB ; ; OUTPUTS: ; DPB ADDRESS REMOVED FROM STACK ;- .DIRW: 10$: MOV 2(SP),-(SP) ; PUSH DPB ADDRESS ONTO STACK EMT 377 ; EXECUTE THE DIRECTIVE BCC 20$ ; IF CC, OKAY CMPB $DSW,#IE.UPN ; WAS ERROR "NO RESOURCES" ? SEC ; ASSUME NO, INDICATE ERROR BNE 20$ ; IF NE, NO - RETURN WITH ERROR WSIG$S ; ELSE, WAIT A WHILE BR 10$ ; AND TRY AGAIN 20$: MOV (SP)+,(SP) ; CLEAN DPB OFF STACK RETURN .END PMR