Trailing-Edge
-
PDP-10 Archives
-
AP-D471B-SB_1978
-
msgin.bli
There are no other files named msgin.bli in the archive.
!***COPYRIGHT (C) 1974, 1975, 1976, 1977 DIGITAL EQUIPMENT CORP., MAYNARD, MASS.***
MODULE MSGIN(RESERVE(#11,#12,#13,#14),SREG=#17,FREG=#16,DREGS=4,
VREG=#15,MLIST,TIMER=EXTERNAL(SIX12),FSAVE)=
BEGIN
GLOBAL WHYERROR; !ERROR CODES FOR ENTRY INTO THE ERROR LEAF
REQUIRE DATA.BLI; !EVERYONE NEEDS THIS NEAT THING!!
EXTERNAL COMPARE,
UNLINK,
MOVE;
COMMENT;
! ROUTINE SKIPCHUNKS
! ======= ==========
! THIS ROUTINE SKIPS THE SPECIFIED NUMBER OF CHARACTERS GIVEN. IT
! WILL ADVANCE CHUNKS AS REQUIRED TO ACCOMPLISH THIS.
! CALLED WITH 1) POINTER TO FIRST CHUNK
! 2) NUMBER OF CHARACTERS TO SKIP
! 3) FLAG INDICATING WHETHER SKIPPED CHUNKS ARE TO BE DELETED
! RETURNS: LH) CHARACTERS UNSKIPPED IN THIS CHUNK (READY FOR INPUT TO MAKEBP)
! RH) CHUNKPTR
! BOTH 0 IF WE RUN OFF THE END
GLOBAL ROUTINE SKIPCHUNKS( CHUNKPTR, COUNT, FLAG) =
BEGIN
REGISTER
C,
CHUNK;
MAP FORMAT CHUNK;
C _ .COUNT; ! PUT ARGS IN REGISTERS
CHUNK _ .CHUNKPTR;
WHILE .C GTR .CHUNK[C0BCNT] AND .CHUNK NEQ 0 DO
BEGIN
C _ .C - .CHUNK[C0BCNT];
IF .FLAG THEN DELCHNK(.CHUNK);
CHUNK _ .CHUNK[C0LINK]
END;
IF .CHUNK NEQ 0 THEN ! IF WE DIDN'T GO OFF THE END
BEGIN
CHUNK<LH> _ .C; ! RETURN XWD COUNT, CHUNKPTR
RETURN .CHUNK
END;
0 ! ELSE RETURN BAD END
END;
COMMENT;
! ROUTINE MAKEBP
! ======= ======
! THIS ROUTINE MAKES A BYTE POINTER GIVEN A CHUNKPTR AND THE NUMBER OF
! CHARACTERS TO SKIP
! CALLED WITH: 1) POINTER TO THE CHUNK
! 2) CHARACTERS TO SKIP
! RETURNS: A BYTE POINTER TO THE FIRST CHARACTER AFTER THE SKIP
! NOTE: THE CHARACTER MUST BE IN THE CHUNK GIVEN.
GLOBAL ROUTINE MAKEBP( CHUNKPTR, COUNT) =
BEGIN
MAP FORMAT CHUNKPTR;
REGISTER
OUT;
OUT _ 0;
OUT<SIZ> _ ASCIISIZE;
OUT<POS> _ 36 - (.COUNT MOD ASCIIBYTESPERWORD ) * ASCIISIZE;
OUT<RH> _ CHUNKPTR[C0DATA] + .COUNT / ASCIIBYTESPERWORD;
.OUT
END;
COMMENT;
! ROUTINE TC
! ======= ==
! TC PICKS THE TRANSACTION CODE OUT OF THE MESSAGE
ROUTINE TC( MHPTR, SRCPTR)=
BEGIN
REGISTER
CHAR,
COUNT,
BPIN,
BPOUT;
LOCAL
TRCODE,
CHUNKPTR,
CHARLEFT;
MAP FORMAT MHPTR;
MAP FORMAT CHUNKPTR;
MAP FORMAT SRCPTR;
MACRO
NEXTCHAR =
BEGIN
WHILE ( CHARLEFT _ .CHARLEFT - 1 ) LSS 0 DO ! IF NO CHARACTERS LEFT
! IN THIS CHUNK GET ANOTHER
BEGIN
IF ( CHUNKPTR _ .CHUNKPTR[C0LINK]) EQL 0 THEN
RETURN (RETMEM ( .TRCODE, .TRCW ); -1);
BPIN<RH> _ CHUNKPTR[C0DATA];
BPIN<POS> _ 36;
CHARLEFT _ .CHUNKPTR[C0BCNT]
END;
CHAR _ SCANI(BPIN);
IF .CHAR GEQ #141 AND .CHAR LEQ #172 THEN CHAR _ .CHAR - #40 ELSE .CHAR
END$,
STORECHAR = (REPLACEI(BPOUT, .CHAR))$;
CHUNKPTR _ .MHPTR[M0INCHNK];
TRCODE _ GETMEM(.TRCW); ! GET ROOM TO STORE A TRANSACTION CODE
ZERO( .TRCODE, .TRCODE + .TRCW - 1); ! CLEAR THE TRANSACTION CODE FIELD
IF ( CHUNKPTR _ SKIPCHUNKS( .CHUNKPTR, .FILLRB, FALSE)) EQL 0 THEN
RETURN (RETMEM ( .TRCODE, .TRCW ); -1);
COUNT _ .CHUNKPTR<LH>;
BPIN _ MAKEBP( .CHUNKPTR, .COUNT); ! MAKE THE INPUT BYTE POINTER
BPOUT _ (.TRCODE)<36,7>; ! AND THE OUTPUT BYTE POINTER
CHARLEFT _ .CHUNKPTR[C0BCNT] - .COUNT;
COUNT _ 0;
IF .TRCDEL<LH> NEQ 0 THEN
BEGIN
WHILE (( COUNT _ .COUNT + 1) LEQ .TRCLEN) AND (NEXTCHAR NEQ .TRCDEL<RH>) DO STORECHAR;
IF .COUNT LEQ .TRCLEN THEN COUNT _ .COUNT + 1;
END
ELSE
BEGIN
WHILE ( COUNT _ .COUNT + 1) LEQ .TRCLEN DO
BEGIN
NEXTCHAR;
STORECHAR
END
END;
SRCPTR[S0SOT] _ .FILLRB + .FILLRC + .COUNT - 1;
.TRCODE
END;
COMMENT;
! ROUTINE DECODE
! ======= ======
ROUTINE DECODE(MHPTR,SRCPTR)=
BEGIN
REGISTER
TCPTR,
TCTAB,
TCWORDS;
LOCAL
LEAFADDR,
LEAF;
MAP FORMAT LEAFADDR;
MAP FORMAT MHPTR;
MAP FORMAT SRCPTR;
MACRO ERROR = RETURN -1 ^ 18 OR$;
LABEL THIS;
IF ( TCPTR _ TC(.MHPTR, .SRCPTR) ) EQL -1 THEN
BEGIN
WHYERROR _ 3; !ERROR = UNKNOWN TRCODE
ERROR ERLEAF
END;
TCTAB _ TRCODE;
TCWORDS _ .TRCW;
LEAF _
BEGIN
THIS: INCR COUNT FROM 0 TO .TRCODE[-1] - 1 DO
BEGIN
IF COMPARE(.TCPTR, .TCTAB, .TCWORDS) THEN LEAVE THIS WITH .COUNT;
TCTAB _ .TCTAB + .TCWORDS
END
END;
RETMEM( .TCPTR, .TCWORDS); ! GIVE BACK THE MEMORY TC GOT
IF .LEAF LSS 0 THEN
BEGIN
WHYERROR _ 3; !ERROR = UNKNOWN TRCODE
ERROR ERLEAF
END
ELSE
BEGIN
LEAFADDR _ .LFADDR[.LEAF];
IF .SRCPTR[S0LFSTS(.LEAFADDR[N0LLFNO],2)] NEQ 0 THEN
BEGIN
WHYERROR _ 4; !ERROR = DISABLED TERMINAL
ERROR ERLEAF
END
ELSE IF .LEAFADDR[N0ED] THEN
BEGIN
WHYERROR _ 4; !ERROR = DISABLED AT LEAF
ERROR ERLEAF
END
END;
LEAFADDR<LH> _ .LEAF;
.LEAFADDR
END;
EXTERNAL UNLINK,
LINK,
DECREMENT,
INSERT,
CHKRUN,
NEXTINTSN,
BUILD,
DCHNKS,
INLOGMSG,
CHKGH,
CHKMSG,
ROLMSG,
FINDPORT,
SONLEAF,
ERLEAF;
COMMENT;
!LAST MODIFIED: 30 JUL 76 BY CDO
! ROUTINE MSREAD
! ======= ======
! CALLED WHEN THERE IS A BUFFER TO READ
! RETURNS TRUE IF EVERYTHING NORMAL
! FALSE IF SOMETHING WAS WRONG
GLOBAL ROUTINE MSREAD =
BEGIN
REGISTER
CHUNKPTR,
SRCPTR,
MHPTR,
GHPTR;
LOCAL
COUNT,
MPPPTR,
LEAFPTR,
PORT,
TEMP,
UDX,
TRCODEINDEX,
ENDI;
MAP FORMAT CHUNKPTR;
MAP FORMAT SRCPTR;
MAP FORMAT PORT;
MAP FORMAT TEMP;
MAP FORMAT MHPTR;
MAP FORMAT LEAFPTR;
MAP FORMAT GHPTR;
MAP FORMAT LFTAB;
MACRO PURGEFLAG = SRCPTR[S0PURGE]$;
!BEGIN!
! GET A CHUNK
! IF THERE ISN'T ONE TO GET THEN RETURN WITH A FALSE VALUE
IF (CHUNKPTR _ INMSG()) EQL 0 THEN RETURN FALSE;
! BREAK UP THE VALUE RETURNED BY INMSG INTO ITS COMPONENTS
UDX _ .CHUNKPTR<LH>;
CHUNKPTR _ .CHUNKPTR<RH>;
CHUNKPTR[C0LINK] _ 0; ! MAKE SURE THE LINK IS ZERO
! GET THE END INDICATOR
ENDI _ .CHUNKPTR[C0ENDI];
! FIND OUT WHO THE CHUNK COMES FROM
SRCPTR _ 0;
IF ( PORT _ FINDPORT( .UDX) ) NEQ 0 THEN
IF ( SRCPTR _ .PORT[PT0SRCPTR] ) EQL 0 THEN SRCPTR _ .PORT[PT0TMPSRCPTR];
PORT[PT0CARRIER] _ TRUE; !DATA IMPLIES CARRIER
IF .SRCPTR EQL 0 THEN
BEGIN
RETMEM(.CHUNKPTR,.CHUNKPTR[C0WORDS]+C0HEADSIZE); ! IF THE SENDER IS UNKNOWN ZAP THE CHUNK
RETURN FALSE ! AND RETURN FALSE
END;
! IF WE ARE PURGING MESSAGES FROM THIS SOURCE THEN SEE IF WE
! SHOULD STOP PURGING. BUT IN ANYCASE RETURN THE CHUNK TO FREE
! CORE
IF .PURGEFLAG THEN
BEGIN
IF .ENDI GEQ EGI THEN PURGEFLAG _ FALSE;
RETMEM(.CHUNKPTR,.CHUNKPTR[C0WORDS]+C0HEADSIZE);
SRCPTR[S0TSN] _ SRCPTR[S0GHPTR] _ 0;
RETURN TRUE
END;
! IF TSN NOT ALREADY ASSIGNED THEN GET ONE
IF .SRCPTR[S0TSN] EQL 0 THEN SRCPTR[S0TSN] _ NEXTINTSN();
! LINK CHUNK TO SRCTAB
IF (TEMP _ .SRCPTR[S0LCHNK]) EQL 0 THEN SRCPTR[S0LCHNK] _ SRCPTR[S0FCHNK] _ .CHUNKPTR
ELSE SRCPTR[S0LCHNK] _ TEMP[C0LINK] _ .CHUNKPTR;
! IF NOT MESSAGE OR GROUP THEN EXIT MSREAD NOW
IF .ENDI LEQ ESI THEN RETURN TRUE;
! OTHERWISE WE HAVE AT LEAST A MESSAGE, SO MAKE A MESSAGE HEADER
MHPTR _ CREATEMH(0);
! FILL IN CHUNK POINTERS IN MESSAGE HEADER
MHPTR[M0INCHNK] _ MHPTR[M0OUTCHNK] _ .SRCPTR[S0FCHNK];
! CLEAR CHUNK POINTERS IN SRCTAB
SRCPTR[S0CHUNKS] _ 0;
! DATE & TIME STAMP THE CREATED MESSAGE HEADER
STAMP(MHPTR[M0DATE],MHPTR[M0TIME]);
IF (GHPTR _ .SRCPTR[S0GHPTR]) NEQ 0 THEN ! IF GH ALREADY EXISTS
BEGIN
MHPTR[M0SOT] _ 0;
IF .INLOGGING THEN
INLOGMSG( .SRCPTR[S0TSN] ^ 18,
.MHPTR[M0DATE],
.MHPTR[M0TIME],
SRCPTR[ S0ID ], ! NOTE POINTERPNOT VALUE
0,
.MHPTR[M0INCHNK]);
IF .GHPTR[G0CHKPNT] THEN
BEGIN
MHPTR[M0DSKADDR] _ CHKMSG( .GHPTR[G0DSKGHADDR],
.MHPTR[M0DATE],
.MHPTR[M0TIME],
.MHPTR[M0INCHNK],
.MHPTR[M0SOT]);
IF .GHPTR[G0ONDSK] THEN ! IF GROUP IS NOT TO BE KEPT IN CORE
BEGIN
DCHNKS(.MHPTR); ! ZAP THE CHUNKS
MHPTR[M0CHNKS] _ 0 ! AND MARK IT OUT
END
END
ELSE
IF .GHPTR[G0ONDSK] THEN !IF BEING ROLLED OUT
BEGIN
MHPTR[M0DSKADDR] _ ROLMSG( .GHPTR[G0DSKGHADDR],
.MHPTR[M0INCHNK],
.MHPTR[M0SOT]);
MHPTR[M0CHNKS] _ 0
END;
IF .ENDI EQL EGI THEN GHPTR[G0ENDI] _ 1; %EGI% ! SET END INDICATOR IN GH
INSERT(.MHPTR,.GHPTR); !ATTACH MESSAGE
END
ELSE
BEGIN ! IF GH DOESN'T EXIST THEN DECODE TRANSACTION TYPE
LEAFPTR _ DECODE(.MHPTR,.SRCPTR);
TRCODEINDEX _ .LEAFPTR<LH>; ! BREAK UP THE VALUE RETURNED FROM TRCODE
LEAFPTR _ .LEAFPTR<RH>;
IF .PORT[PT0SRCPTR] EQL 0 AND .LEAFPTR<RH> NEQ SONLEAF<0,0> THEN
BEGIN ! IF NOT SIGNED ON AND NOT SIGNING ON
LEAFPTR _ ERLEAF;
WHYERROR _ 1; ! ERROR = NOT SIGNED ON
TRCODEINDEX _ #777777
END;
MHPTR[M0SOT] _ .SRCPTR[S0SOT]; !SAVE NUMBER OF CHARACTERS TO SKIP
SRCPTR[S0SOT] _ 0;
!CHECK FOR PROPER LENGTH MESSAGE HERE ALSO
COUNT_0;
CHUNKPTR_.MHPTR[ M0INCHNK ];
UNTIL .CHUNKPTR EQL 0
DO BEGIN COUNT_.COUNT+.CHUNKPTR[ C0BCNT ];
CHUNKPTR_.CHUNKPTR[ C0LINK ]
END;
IF .MHPTR[ M0SOT ] GTR .COUNT THEN
BEGIN
WHYERROR _ 2; !ERROR = NOT ENOUGH DATA
TRCODEINDEX _ #777777;
LEAFPTR _ ERLEAF
END;
IF .INLOGGING THEN
INLOGMSG( .SRCPTR[S0TSN] ^ 18,
.MHPTR[M0DATE],
.MHPTR[M0TIME],
SRCPTR[S0ID], ! NOTE POINTER NOT VALUE
IF .TRCODEINDEX NEQ #777777 THEN
TRCODE[.TRCODEINDEX*.TRCW] ELSE .TRCODEINDEX,
.MHPTR[M0INCHNK]);
! MAKE A GROUP HEADER, ZERO IT, AND LINK IT TO A LEAF
GHPTR _ CREATEGH(LEAFPTR[N0GHS]);
SRCPTR[S0GHPTR] _ .GHPTR; ! TELL SRCPTR WHERE THE GH IS
! STORE POINTER TO SENDER IN THE GH
GHPTR[G0SENDER] _ SRCPTR[S0ID]; !NOTE: ADDRESS NOT VALUE!
! STORE POINTERS TO THE MESSAGE IN THE GH
GHPTR[G0FMHPTR] _ GHPTR[G0LMHPTR] _ GHPTR[G0OUTMH] _ .MHPTR;
GHPTR[G0LFPTR] _ .LEAFPTR; ! SAVE GROUPS PARENT LEAF IN THE GH
GHPTR[G0LHTSN] _ .SRCPTR[S0TSN]; ! SAVE TSN IN GH
IF .ENDI EQL EGI THEN GHPTR[G0ENDI] _ 1; ! SET END INDICATOR IN GH
IF (.LEAFPTR<RH> LSS ERLEAF<0,0>) AND .CHECKPOINTING AND
.LEAFPTR[N0CHKPNT] THEN
BEGIN !MUST FAILSOFT THIS REAL TRANSACTION
GHPTR[G0DSKGHADDR] _ CHKGH( .LEAFPTR[N0LLFNO], ! CHECKPOINT THE GROUP
.GHPTR[G0TSN],
.GHPTR[G0SENDER],
.MHPTR);
! AND STORE THE DISK GROUP HEADER ADDRESS
GHPTR[G0CHKPNT] _ TRUE ! THIS IS BEING CHECKPOINTED
END;
CHKRUN(.LEAFPTR, 1, .GHPTR); ! INCREMENT THE GROUP COUNT OF THE LEAF,
! ROLL OUT IF QUOTA EXCEEDED,
! AND GET ANYONE OUT OF WAITING IF WE CAN
END;
! IF END OF GROUP THEN CLEAN UP SRCTAB
IF .ENDI EQL EGI THEN SRCPTR[S0TSN] _ SRCPTR[S0GHPTR] _ 0;
TRUE
END;
END;