Trailing-Edge
-
PDP-10 Archives
-
k20v7b
-
decnet-tools/dnsnup.mac
There are 9 other files named dnsnup.mac in the archive. Click here to see a list.
; UPD ID= 58, SNARK:<6.1.UTILITIES>DNSNUP.MAC.9, 16-Dec-84 20:20:24 by GLINDELL
;Do not search for DF.XMT in ROUTER explicitly - anywhere will do
; UPD ID= 22, SNARK:<6.1.UTILITIES>DNSNUP.MAC.8, 28-Jul-84 10:39:19 by NICHOLS
;Allow alternate symbols in checks added by edit 18
; UPD ID= 21, SNARK:<6.1.UTILITIES>DNSNUP.MAC.7, 26-Jul-84 06:55:38 by DMCDANIEL
; Change last KF.XMT to DF.XMT.
; UPD ID= 18, SNARK:<6.1.UTILITIES>DNSNUP.MAC.6, 16-Jul-84 08:11:31 by PALMIERI
;Check values of message block/MSD symbols against those of the running
;monitor to detect any version skew.
;SNARK:<6.1.UTILITIES>DNSNUP.MAC.4 2-Apr-84 17:32:35, Edit by NICHOLS
;Call APRSRV subrs UPDTCK and LGTAD for date/time to be accurate
; to the millisecond
;SNARK:<6.1.UTILITIES>DNSNUP.MAC.2 2-Apr-84 17:23:14, Edit by NICHOLS
;Add code to store input and output Line Ids
;Change KF.QOB to KF.XMT for newer monitors. EDIT by PALMIERI
; CHANGE KF.XMT TO KF.QOB SO IT WILL ASSEMBLE FOR KL2102. BRANNON
;WORK:<NICHOLS>DNSNUP.MAC.8 26-Jan-84 16:37:15, Edit by NICHOLS
;Fix circular buffer logic at BP0
;<6.1.MONITOR>DNSNUP.MAC.6, 30-Mar-83 14:48:39, Edit by CHALL
;Correct ungrammatical error message
;<GRANT.DECNET.5>DNSR.MAC.5, 13-Apr-81 11:41:10, EDIT BY GRANT
;Internal message header now 7 words, was 4
;<PERF-TOOLS>DNSR.MAC.14, 25-Mar-81 11:18:44, EDIT BY GRANT
;Add new object types
;Print out object number as well as descriptive string
;<PERF-TOOLS>DNSR.MAC.11, 31-Oct-80 16:56:10, EDIT BY MURPHY
;COMBINED DNSEND AND DNREAD AGAIN
TITLE DNSNUP - SNOOP PROGRAM TO COLLECT DECnet MESSAGES
SEARCH PROLOG,MACSYM,MONSYM,D36PAR,SCPAR,NIPAR
SALL
.REQUIRE REL:SYMSUB
EXTERN ST2ADR,ADR2ST
SUBTTL Declarations
;Items in data block
MAXMSG==<^D600+3/4> ;MAX LENGTH OF MESSAGE IN WORDS
TABLEN==6000 ;WORDS IN THE CIRCULAR BUFFER
NBPT==3 ;NUMBER OF BREAKPOINTS
CCZCHN==0 ;^Z CHANNEL
OPDEF IFIW [1B0] ;INSTRUCTION FORMAT INDIRECT WORD
PIOFF==400
PION==200
I=P6 ;INDEX FOR RELOCATABLE CODE
RC=13 ;ROUTER CIRCUIT BLK PTR FROM ROUTER.MAC
PURGE P6
BPRPAG==100 ;BREAK-POINT PAGE IN USER-SPACE
BPRCOD==BPRPAG_11 ;BREAK-POINT ADDRESS IN USER-SPACE
SUBTTL Structure Definitions
;
;Note that these BEGSTRs are copied in DNTATL, the formatting
;program for this trace.
BEGSTR FH ;File header
WORD LNG ;Length of this header
FIELD FLG,9 ;Flags to indicate what kind of entry
FIELD TYP,9 ;Entry type
TYP.FH==1 ; Entry type of file header
HWORD MGL ;Length of the message block
WORD UPT ;UPTIME corresponding to UDT below
WORD UDT ;UDT corresponding to UPT above
WORD PVR ;Trace program version number (location 137)
WORD MVR ;Monitor version number
WORD CFG,5 ;CONFIG string fom this monitor
ENDSTR
BEGSTR MH ;Message header
WORD LNG ;Length of entire entry
FIELD FLG,6 ;Flags to indicate what kind of entry
FIELD IOL,3 ;Input, output or local
XP IOL.IN,1 ;Input (avoid zero for error detection)
XP IOL.OT,2 ;Output message
XP IOL.LO,3 ;Local message
FIELD TYP,9 ;Entry type
TYP.MH==2 ; Entry type of message record
HWORD LST ;Cumulative count of lost messages
WORD UPT ;UPTIME as of entry
WORD UDT ;UDT as of entry
WORD OMB ;Original MB pointer
WORD ILN ;Input Line ID (or zero if none)
WORD OLN ;Output Line ID (or zero if none)
ENDSTR
SUBTTL Start of Program
;TOP
BLOCK 1000
TIMER: RESET
MOVE P,[IOWD PDLEN,PDL]
CALL CHKSNP ; Check to see if our D36PAR symbols match
; the values that the monitor has for them
XMOVEI I,BPRCOD ;GET USER-MODE INDEX FOR RELOCATABLE STORAGE
XJRSTF [0
REL3]
ERJMP .+1
TDZA T1,T1 ;ZERO = WE HAVE NO EXTENDED ADDRESSING
REL3: SETO T1, ;NON-ZERO = WE HAVE EXTENDED ADDRESSING
MOVEM T1,MONTYP(I)
MOVEI T1,.FHSLF ;SET UP PSI SYSTEM TO GET ^Z WHICH STOPS SNOOP
MOVE T2,[LEVTAB,,CHNTAB]
SIR
EIR
MOVE T2,[1B<CCZCHN>]
AIC
MOVE T1,[.TICCZ,,CCZCHN]
ATI ;ENABLE ^Z INTERRUPT
SETZM CMNBLK+.CMFLG ;CLEAR OUT RESCAN ADDRESS AND FLAGS
MOVX T1,<XWD .PRIIN,.PRIOU> ;GET INPUT AND OUTPUT JFN
MOVEM T1,CMNBLK+.CMIOJ ;SAVE IT IT THE COMMAND. BLOCK
MOVE T1,[POINT 7,[ASCIZ |Output File: |]] ;GET THE PROPMT TEXT
MOVEM T1,CMNBLK+.CMRTY ;SAVE IT
MOVE T1,[POINT 7,TXTBUF] ;POINT TO THE TEXT BUFFER
MOVEM T1,CMNBLK+.CMBFP ;BUFFER POINTER
MOVEM T1,CMNBLK+.CMPTR ;AND POINTER TO NEXT TO BE PARSED
MOVEI T1,^D132*5 ;GET THE LENGTH OF THE BUFFERS
MOVEM T1,CMNBLK+.CMCNT ;SAVE IT
SETZM CMNBLK+.CMINC ;CLEAR OUT THE COUNT OF CHARS LEFT
MOVE T1,[POINT 7,ATOM] ;POINT TO THE ATOM BUFFER
MOVEM T1,CMNBLK+.CMABP ;SAVE IT
MOVEI T1,^D132*5 ;GET THE LENGTH
MOVEM T1,CMNBLK+.CMABC ;AND SAVE THAT TOO
MOVEI T1,JFNARG ;GET THE POINTER TO THE JFN BLOCK
MOVEM T1,CMNBLK+.CMGJB ;SAVE IT
MOVEI T1,CMNBLK ;POINTER TO BLOCK
MOVEI T2,[FLDDB.(.CMINI)] ;INIT THE LINE
COMND ;DO IT
RESC: MOVEI T2,[FLDDB.(.CMOFI,<CM%DPP+CM%HPP+CM%SDH>,0,<FILE FOR LOGGING>,<DECNET.MSG>)]
COMND ;SCAN IT OFF
TXNE T1,CM%RPT ;HAVE TO DO A RESCAN FROM HERE?
JRST RESC ;YES,THEN DO IT
MOVEM T2,FILJFN ;SAVE THE JFN FOR LATER
MOVEI T2,[FLDDB.(.CMCFM)] ;WAIT FOR CONFIRM
COMND ;HERE
SETZM INDEX(I)
SETZM TOTAL(I)
SETZM PNTR(I)
SETZM LAST
SETZM LPRINT
SETZM LSTTOD
SETZM ITIME
SETZM LTOD(I)
SETZM TABLE(I)
HRLI T1,TABLE(I)
HRRI T1,TABLE+1(I)
BLT T1,TABLE+TABLEN-1(I)
SETZM OVRFLO(I)
MOVEI T1,.SNPLC
MOVEI T2,<BPRLEN+777>/1000
MOVEI T3,BPRPAG
SNOOP ;INITIALIZE THE BREAK POINTS
JSP T1,ERROR
LSH T2,11 ;CHANGE MONITOR PAGE # TO MONITOR ADDRESS
MOVEM T2,INDEX(I) ;STORE FOR RELOCATABLE CODE
; ..
SUBTTL RELOCATE BREAKPOINT CODE
; ..
MOVSI Q1,-INSTBL
TIMER1: HLRZ T1,INSTAB(Q1)
HRRZ T2,INSTAB(Q1)
ADD T2,INDEX(I)
HRRM T2,BPRCOD(T1)
AOBJN Q1,TIMER1
;LOOK UP SYMBOLS
MOVSI Q1,-SYMTBL
JUMPE Q1,TIMER4
TIMER2: MOVEI T1,.SNPSY
MOVE T2,SYMTAB(Q1)
MOVE T3,SYMTAB+1(Q1)
SNOOP
JSP T1,ERROR
HLRE T3,SYMTAB+2(Q1) ;GET SYMBOL OFFSET
ADD T2,T3 ;ADJUST VALUE BY OFFSET
HRRZ T3,SYMTAB+2(Q1)
CAIL T3,TIMER ;IN LOCAL CODE?
ADDM T2,0(T3) ;YES
CAIGE T3,TIMER ;IN BREAKPOINT CODE?
ADDM T2,BPRCOD(T3)
ADD Q1,[2,,2]
AOBJN Q1,TIMER2
;SET BREAKPOINTS
TIMER4: MOVSI Q1,-NBPT
SETBP1: MOVEI T1,.SNPDB
MOVEI T2,1(Q1)
MOVE T3,BP1ADR(Q1)
SKIPE MONTYP(I)
JRST [ HLRZ T4,BPI(Q1) ;EXT ADR BP ROUTINE ENTRY
HRLI T4,(XPCW) ;CONSTRUCT BP INSTRUCTION
JRST SETBP2]
HRRZ T4,BPI(Q1)
HRLI T4,(JSR) ;CONSTRUCT BP INSTRUCTION
SETBP2: ADD T4,INDEX(I)
TLZ T4,37
SNOOP
JSP T1,ERROR
AOBJN Q1,SETBP1
;OPEN OUTPUT FILE FOR DATA
MOVE T1,FILJFN
MOVE T2,[440000,,OF%RD+OF%WR]
OPENF
JRST ERROPN
;START SNOOPING
MOVEI T1,.SNPIB
SNOOP
JSP T1,ERROR
HRROI T1,[ASCIZ/
Type ^Z to stop snooping /]
PSOUT
MOVE T1,EXMADR(I) ;GET THE POINTER TO THE PLACE TO PUT IT
ADD T1,I ;ADD IN THE INDEX
MOVEI T2,FH.LEN ;SIZE OS THIS ENTRY
MOVEM T2,FH.LNG(T1) ;SAVE THE LENGTH
MOVSI T2,TYP.FH ;GET THE TYPE
HRRI T2,MB.LEN ;GET THE LENGTH OF THE MESSAGE BLOCK
MOVEM T2,FH.FLG(T1) ;SAVE IT
PUSH P,T1 ;SAVE T1
GTAD ;GET THE UDT
MOVE T3,T1 ;SAVE IT
TIME ;GET THE UPTIME
MOVE T2,T1 ;AND SAVE IT
POP P,T1 ;AND RESTORE PDL
DMOVEM T2,FH.UPT(T1) ;SAVE IT IN THE HEADER
SETZM FH.PVR(T1) ;ZERO VERSION NUMBER
ADDI T1,FH.LEN ;GET THE LENGTH
SUB T1,I ;SUBTRACT OFF INDEX
MOVEM T1,DEPADR(I) ;STORE IT
AOS PENMSG(I) ;INCREMENT NUMBER OF PENDING MESSAGES
TIMER3: SKIPE P2,PENMSG(I) ;ANY MESSAGES PENDING?
JRST REDMSG ;YES, THEN READ THE MESSAGE INTO FILE
SKIPE QUITF ;HAVE TO STOP NOW?
JRST TYPANS ;RIP OUT SNOOP POINTS AND DO PENDING OUTPUT
SNOOZE: MOVEI T1,^D50 ;SLEEP FOR
WAITX: DISMS ;THIS MUCH TIME
JRST TIMER3 ;AND CONTINUE
;^Z INTERRUPT TO STOP DATA COLLECTION
CCZINT: MOVEM T1,INTAC1 ;SAVE AN AC
SETOM QUITF ;SET FLAG TO QUIT
HRRZ T1,PIPC2 ;CHECK PC
CAIN T1,WAITX+1 ;AT DISMS?
MOVEI T1,TIMER3 ;YES, DEBRK TO TIMER3
HRRM T1,PIPC2
MOVE T1,INTAC1
DEBRK
LEVTAB: PIPC1
PIPC2
PIPC3
CHNTAB: 2,,CCZINT
BLOCK ^D35
SUBTTL RAW DATA OUTPUT
TYPANS: MOVEI T1,.SNPUL ;PULL OUT ALL OUR SNOOP POINTS
SNOOP ;FROM THE MONITOR
JSP T1,ERROR ;BAD BAD ERROR
TYPAN1: HRRZ T1,FILJFN
TLO T1,400000
CLOSF
JRST ERRCLS
HRROI T1,[ASCIZ/
[DNTATL will format the output for you]/
]
PSOUT
HALTF ;ALL DONE
SUBTTL CHKSNP - Check a few symbols
;Here to see if a few of our compiled in symbol values agree with those
; the monitor we are snooping on has.
DEFINE CKSYMS,<
;; Symbol,Alternate,Module (any module or global if blank)
CHKSYM (DF.XMT, , )
CHKSYM (MB.LEN, , )
CHKSYM (MD.ALA, $MDALA , )
CHKSYM (MD.ALL, $MDALL , )
CHKSYM (MD.BYT, $MDBYT , )
CHKSYM (UD.DAT, $UDDAT , )
CHKSYM (UD.MSD, $UDMSD , )
>;END OF DEFINE CKSYMS
DEFINE CHKSYM (sym,altsym,module,%tag1,%tag2),<
MOVX T1,.SNPSY ;;Snoop for a symbol value
MOVE T2,[RADIX50,sym] ;;In particular, sym
IFB <module>,<SETZ T3,> ;;No particular module
IFNB <module>,<MOVE T3,[RADIX50,module]> ;;This particular module
SNOOP% ;;Return value in T2
JRST %tag1 ;;Can't find this symbol in monitor
CAIN T2,sym ;;Same as our value?
JRST %tag2 ;;Yes, success
TMSG <?Symbol SYM in DNSNUP does not agree with value in monitor.
Please recompile DNSNUP with correct D36PAR.UNV.>
HALTF
%tag1:!
IFB <altsym>,<
TMSG <?Can't get symbol SYM from monitor via SNOOP JSYS>
HALTF
>;end of IFB <altsym>
IFNB <altsym>,<
MOVX T1,.SNPSY ;;Snoop for a symbol value
MOVE T2,[RADIX50,altsym] ;;In particular, altsym
IFB <module>,<SETZ T3,> ;;No particular module
IFNB <module>,<MOVE T3,[RADIX50,module]> ;;This particular module
SNOOP% ;;Return value in T2
IFNSK.
TMSG <?Can't get symbol SYM or ALTSYM from monitor via SNOOP JSYS>
HALTF
ENDIF.
CAIN T2,sym ;;Same as our value?
IFSKP.
TMSG <?Symbol ALTSYM in DNSNUP does not agree with value in monitor.
Please recompile DNSNUP with correct D36PAR.UNV.>
HALTF
ENDIF.
>;END OF IFNB <altsym>
%tag2:! ;;Success
>;END OF DEFINE CHKSYM
CHKSNP: CKSYMS ;Check the symbols, exit if mismatch
RET ;If we get here, all is OK
ERROR: HRROI T1,[ASCIZ |?Fatal error occurred while snooping: |]
PSOUT
MOVX T1,.PRIOU ;DESTINATION DESIGNATOR
MOVX T2,<.FHSLF,,-1> ;MY LAST ERROR
MOVX T3,0 ;UNLIMITED ERRSTR LENGTH
ERSTR
HALTF
ERROPN: TMSG <?Unable to open trace file>
HALTF
ERRCLS: TMSG <?Unable to close trace file>
HALTF
SUBTTL REDMSG - Output to the message file
REDMSG: MOVE P3,EXMADR(I) ;GET ADDRESS OF NEXT MESSAGE
ADD P3,I ;ADD IN THE OFFSET
SKIPLE T1,@P3 ;GET LENGTH OF THE ENTRY
JRST OUTMSG ;LENGTH IS GOOD, SEND IT OUT
JUMPE T1,[TMSG <?Zero length message encountered in buffer>
JRST TYPANS] ;CLOSE THE FILE AND EXIT NOW
MOVE P3,ORGADR(I) ;GET THE ORIGINAL ADDRESS
MOVEM P3,EXMADR(I) ;STORE IT
ADD P3,I ;RELOCATE IT
XMOVEI T1,@P3 ;LENGTH OF MESSAGE TO COPY
OUTMSG: MOVE T2,P3 ;GET COPY OF ADDRESS IN T2
OUTMS1: SETZ T4, ;NUMBER OF WORDS LEFT OVER FOR NEXT PASS
MOVE T1,FILJFN ;GET THE OUTPUT JFN
MOVX T2,<POINT 36,(I)> ;GET AN INDEXED BYTE POINTER
HRR T2,EXMADR(I) ;GET THE POINTER TO THE DATA
MOVN T3,(P3) ;GET THE LENGTH OF THE MESSAGE IN WORDS
OUTMS2: SETZ T4, ;TERMINATING BYTE
SOUT ;OUTPUT IN DUMP MODE
ERJMP OUTERR ;OUTPUT ERROR, DIE
ADD P3,MH.LNG(P3) ;ADD IN THE LENGTH OF THE MESSAGE
SUB P3,I ;SUBTRACT OFF THE INDEX
SKIPGE P3 ;GONE NEGATIVE
MOVE P3,ORGADR(I) ;GET THE ORIGINAL BACK
MOVEM P3,EXMADR(I) ;THIS WILL BE OUR NEXT ADDRESS
SOSG PENMSG(I) ;ANY MORE MESSAGE
JRST TIMER3 ;RETURN TO SEE IF ANYMORE
JRST REDMSG ;DO THE NEXT ONE THEN
OUTERR: TMSG <?File Output error>
JRST TYPANS ;GIVE UP NOW
SUBTTL Breakpoints
;BREAKPOINT INSTRUCTIONS
DEFINE BPTR (Q)<
BPTR1(\Q)>
DEFINE BPTR1 (Q)<
XBP'Q'R,,BP'Q'R>
BPI:
XX==0
REPEAT NBPT,<
BPTR XX
XX=XX+1>
DEFINE SYM (NAME,PTR,MODUL,OFFSET)<
RADIX50 0,NAME
IFNB <MODUL>,<RADIX50 0,MODUL>
IFB <MODUL>,<0>
IFNDEF NAME,<
NAME:>
XWD OFFSET,PTR>
FILBUF: BLOCK ^D256 ;ENOUGH FOR A VERY BIG MESSAGE
QUITF: BLOCK 1
JFNARG: BLOCK ^D16
ATOM: BLOCK ^D<132>
TXTBUF: BLOCK ^D<132>
CMNBLK: BLOCK .CMGJB+1
OUTJFN: 0
FILJFN: 0
LAST: 0
LPRINT: 0
LSTTOD: 0
NXTTCK: 0
ITIME: 0
BP1ADR: 0 ;MONITOR ADDR OF BP 1 (RECEIVED MSGS)
BP2ADR: 0 ;MONITOR ADDR OF BP 2 (SENT MSGS)
BP3ADR: 0 ;MONITOR ADDR OF BP 3 (LOCAL MSGS)
STRNGL==20
STRING: BLOCK STRNGL
SYMBOL: BLOCK 10
PRGNML==40
PRGNAM: BLOCK PRGNML
FRKCNT: 0
FRKTBL==1000
FRKTAB: BLOCK FRKTBL
PDLEN==100
PDL: BLOCK PDLEN
;MACROS FOR GENERATING MONITOR AND LOCAL REFERENCES IN RELOCATED CODE
;MONITOR SYMBOL REFERENCE
DEFINE MONREF (INST,MSY,%TAG)<
%TAG:! INST
MONRR <SYM MSY,%TAG
>>
;SET OF REMOTE MACROS FOR ABOVE
DEFINE MONRR (..XXX)<
MONRR2 <..XXX>,
>
DEFINE MONRR2 (..NEW,..OLD)<
DEFINE MONRR (..XXX)<
MONRR2 <..XXX>,<..OLD
..NEW
>>>
DEFINE MONRH <
DEFINE MONRR2 (..NEW,..OLD)<
..OLD>
MONRR ()>
;LOCAL SYMBOL REFERENCE
DEFINE LOCREF (INST,LSY,%TAG)<
%TAG:! INST
LOCRR < %TAG,,LSY
>>
;SET OF REMOTE MACROS FOR ABOVE
DEFINE LOCRR (..XXX)<
LOCRR2 <..XXX>,
>
DEFINE LOCRR2 (..NEW,..OLD)<
DEFINE LOCRR (..XXX)<
LOCRR2 <..XXX>,<..OLD
..NEW
>>>
DEFINE LOCRH <
DEFINE LOCRR2 (..NEW,..OLD)<
..OLD>
LOCRR ()>
DEFINE BP (Q)<
XBP'Q'R:0
0
0
LOCREF <1,,0>,XBP'Q'
BP'Q'R: 0
XBP'Q': CONO PI,PIOFF
>
DEFINE ENDBP (Q)<
MOVE I,SAV1I(I)
CONO PI,PION
LOCREF <SKIPE>,MONTYP
LOCREF <XJRSTF>,XBP'Q'R
LOCREF <JRSTF @0>,BP'Q'R>
LIT
SUBTTL Relocatable Code for SNOOPing
LOC BPRPAG_11
PHASE 0 ;RELOCATABLE CODE INDEXED BY I
BPR: ;START OF RELOCATABLE CODE FOR LENGTH CALC
BP (0)
LOCREF <MOVEM I,>,SAV1I
LOCREF <MOVE I,>,INDEX
MOVEM Q1,SAV1Q1(I)
MOVEI Q1,IOL.IN ;THIS IS BPT 1, RECEIVED MESSAGES
JRST BP0(I) ;DO THE WORK
RBP0: MOVE Q1,SAV1Q1(I) ;RETURN TO RBP0
ENDBP (0)
BP (1)
LOCREF <MOVEM I,>,SAV1I
LOCREF <MOVE I,>,INDEX
MOVEM Q1,SAV1Q1(I)
MOVEI Q1,IOL.OT ;THIS IS BPT 2, SENT MESSAGES
CAXN T1,DF.XMT ;IS IT A TRANSMIT REQUEST?
JRST BP0(I) ;YES, DO THE WORK
RBP1: MOVE Q1,SAV1Q1(I) ;RETURN TO RBP1
ENDBP (1)
BP (2)
LOCREF <MOVEM I,>,SAV1I
LOCREF <MOVE I,>,INDEX
MOVEM Q1,SAV1Q1(I)
MOVEI Q1,IOL.LO ;THIS IS BPT 3, LOCAL MESSAGES
JRST BP0(I) ;DO THE WORK
RBP2: MOVE Q1,SAV1Q1(I) ;RETURN TO RBP2
ENDBP (2)
SUBTTL Common Code for SNOOP Break Points
;Note that the SNOOP code is assumed to be executing in section 1, and
;that references to data contained in the SNOOP code are assumed to be local.
;We arrive at the SNOOP break point with register MB pointing to the
;message block being traced.
IFN MDALA+1,<
PRINTX ?Code at BP0 Depends on MDALA being a full-word, its not>
IFN MDBYT+1,<
PRINTX ?Code at BP0 depends on MDBYT being a full-word, its not>
IFN MDALL-777777,<
PRINTX ?Code at BP0 depends on MDALL being a RH-word, its not>
BP0: DMOVEM T1,SAV1T1(I) ;I ALREADY SAVED AND SET UP
DMOVEM T3,SAV1T3(I)
MOVEI T2,<MB.LEN+MH.LEN>*4 ;GET MINIMUM COPY LENGTH
XMOVEI T4,UD.DAT(MB) ;GET PTR TO USER DATA AREA OF MSG BLK
CAMN T4,MD.ALA+UD.MSD(MB) ;IS USER DATA IN THE MESSAGE BLOCK?
JRST NOUBLK(I) ;YES
ADD T2,MD.BYT+UD.MSD(MB) ;NO, ADD IN THE LENGTH OF USER DATA
ADDI T2,7*4 ;ADD FUDGE WORDS TO COVER OFFSETS
NOUBLK: ADDI T2,3 ;MAKE SURE WE END UP ON A WHOLE WORD
ASH T2,-2 ;CONVERT IT TO WORDS
CAILE T2,MAXMSG+MB.LEN+MH.LEN ;MORE THAN WE ALLOW ONE ENTRY TO BE?
MOVX T2,MAXMSG+MB.LEN+MH.LEN ;YES, USE MAX
SKIPN T3,DEPADR(I) ;GET DEPOSIT (PUTTER) ADDRESS
JRST BP1A(I) ;NOT SET UP, DROP THIS MESSAGE
MOVE T4,T3 ;CALC END OF RANGE WE'LL COPY INTO
ADD T4,T2 ;ADD IN LENGTH OF MSG IN WORDS
CAMGE T4,TOPADR(I) ;WOULD WE GO PAST END OF CIRCULAR BUFFER?
JRST NOWRAP(I) ;NO
ADD T3,I ;YES, MAKE ABSOLUTE ADDR
SETOM (T3) ;TELL USER-MODE WE ARE WRAPPING NOW
MOVE T3,ORGADR(I) ;GET ADDR OF ORIGINAL TOP OF BUFFER
MOVE T4,T3 ;CALC END OF RANGE WE'LL COPY INTO
ADD T4,T2 ;ADD IN LENGTH OF MSG IN WORDS
NOWRAP: CAMGE T3,EXMADR(I) ;START OF NEW RANGE BELOW TAKER?
CAMGE T4,EXMADR(I) ;YES, END OF NEW RANGE ABOVE TAKER?
TRNA ;NO, THEN COPY NEW MSG INTO CIRC BUFFER
JRST FULLBF(I) ;YES, WRAP AROUND, PUNT AND COUNT A LOST MSG
ADD T3,I ;MAKE T3 ABSOLUTE ADDR OF COPY TARGET
STOR T2,MHLNG,(T3) ;SAVE LENGTH OF THIS ENTRY
DPB Q1,[POINTR(MH.IOL(T3),MHIOL)](I) ; 1=INPUT, 2=OUTPUT, 3=LOCAL
MOVX T1,TYP.MH ;RECORD TYPE IS 'MESSAGE HEADER'
DPB T1,[POINTR(MH.TYP(T3),MHTYP)](I) ; SAVE THE TYPE
MOVE T1,LSTMSG(I) ;CUMULATIVE NUMBER
STOR T1,MHLST,(T3) ; OF LOST MESSAGES
MONREF (<CALL>,UPDTCK) ;GET SYSTEM UP TIME IN MS
STOR T1,MHUPT,(T3) ;SAVE TIME STAMP FOR ENTRY
MONREF (<CALL>,LGTAD) ;COMPUTE DAYS AND FRACTION
STOR T1,MHUDT,(T3) ;SAVE IT IN MESSAGE HEADER
LOAD T1,RCLID,(RC) ;GET LINE ID FROM CIRCUIT BLOCK
STOR T1,MHILN,(T3) ;STORE AS INPUT CIRCUIT POINTER
STOR T1,MHOLN,(T3) ;ALSO STORE AS OUTPUT CIRCUIT POINTER
STOR MB,MHOMB,(T3) ;SAVE ORIGINAL MESSAGE BLOCK POINTER
ADDI T3,MH.LEN ;POINT TO THE END OF THE HEADER
MOVE T2,MB ;GET SOURCE POINTER
MOVEI T1,MB.LEN ;GET NUMBER OF WORDS TO MOVE
EXTEND T1,BLTINS(I) ;DO THE EXTEND
XMOVEI T2,UD.DAT(MB) ;GET THE POINTER TO THE USER DATA
CAMN T2,MD.ALA+UD.MSD(MB) ;WAS THE USER DATA WITHIN THE MB?
JRST GIVUSR(I) ;YES, THEN JUST GIVE CURRENT STUFF TO USER
MOVE T1,MD.BYT+UD.MSD(MB) ;GET LENGTH OF USER DATA IN BYTES
ADDI T1,7*4 ;ADD FUDGE WORDS TO COVER OFFSETS
REPEAT 0,<
HRRZ T3,MD.ALL+UD.MSD(MB) ;LOAD ALLOCATED LENGTH
CAMLE T1,T2 ;MORE THAN ALLOCATED LENGTH?
MOVE T1,T2 ;YES, USE ALLOCATED LENGTH?
>
ADDI T1,3 ;ROUND UP
ASH T1,-2 ;CONVERT BYTE COUNT TO WORD COUNT
MOVE T2,MD.ALA+UD.MSD(MB) ;PTR TO USER DATA BLOCK (SOURCE FOR XBLT)
EXTEND T1,BLTINS(I) ;XBLT THE USER DATA BLOCK
GIVUSR: SUB T3,I ;SUBTRACT OFF THE INDEX REGISTER
MOVEM T3,DEPADR(I) ;SAVE NEW DEPOSIT ADDRESS
AOS T1,PENMSG(I) ;INCREMENT NUMBER OF PENDING MESSAGES
JRST BP1A(I) ;AND DO THE NORMAL FINISH CODE
FULLBF: AOS T1,LSTMSG(I) ;INCREMENT NUMBER OF LOST MESSAGES
BP1A: ADDI Q1,-1(I) ;Q1 HAS BP # (1,2 OR 3)
XMOVEI Q1,@[IFIW RBP0(I) ;RETURN ADDR FOR BP0 (RECEIVED MSG)
IFIW RBP1(I) ;RETURN ADDR FOR BP1 (SENT MSG)
IFIW RBP2(I)](Q1) ;RETURN ADDR FOR BP2 (LOCAL MSG)
DMOVE T1,SAV1T1(I)
DMOVE T3,SAV1T3(I)
JRST 0(Q1) ;AND RETURN TO CALLING ROUTINE
BLTINS: XBLT ;XBLT INSTRUCTION
SAV1T1: 0 ;SNOOP
SAV1T2: 0 ; BREAK
SAV1T3: 0 ; POINTS
SAV1T4: 0 ; SAVE
SAV1Q1: 0 ; ACs
SAV1I: 0 ; HERE
PNTR: 0
LTOD: 0
JOBNUM: 0
MONTYP: 0 ;NON-ZERO IF WE HAVE EXTENDED ADDRESSING
ORGADR: TABLE ;POINTER TO THE TABLE
EXMADR: TABLE ;ADDRESS USER IS CURRENTLY TAKING FROM
DEPADR: TABLE ;ADDRESS MONITOR IS PUTTING INTO
TOPADR: TABLE+TABLEN-1 ;TOP OF THE BUFFER
LSTMSG: BLOCK 1 ;LOST MESSAGE COUNTER
PENMSG: BLOCK 1 ;NUMBER OF MESSAGES PENDING
INDEX: 0
TOTAL: 0
TABLE: BLOCK TABLEN
OVRFLO: 0
FORKN: 0
LIT ;LITERALS IN PHASED CODE
BPRLEN==.-BPR
DEPHASE
RELOC
INSTAB: LOCRH
INSTBL==.-INSTAB
PIPC1: BLOCK 1 ;STORAGE FOR PC INTERUPT CHANNEL 1
PIPC2: BLOCK 1 ;STORAGE FOR PC INTERUPT CHANNEL 2
PIPC3: BLOCK 1 ;STORAGE FOR PC INTERUPT CHANNEL 3
INTAC1: BLOCK 1 ;STORAGE FOR AC1 ON INTERUPT
SYMTAB:
SYM RTRITR,BP1ADR,ROUTER ;POINT AT WHICH TO COLLECT INPUT MSGS
SYM RTROTR,BP2ADR,ROUTER ;POINT AT WHICH TO COLLECT OUTPUT MSGS
SYM RTRLTR,BP3ADR,ROUTER ;POINT AT WHICH TO COLLECT LOCAL MSGS
MONRH
SYMTBL==.-SYMTAB
END TIMER