Trailing-Edge
-
PDP-10 Archives
-
decuslib10-04
-
43,50346/procol.mac
There is 1 other file named procol.mac in the archive. Click here to see a list.
TITLE PROCOL -- INTERPROCESSOR COMMUNICATIONS OVER AN ASYNCHRONOUS LINE
SUBTTL COMMUNICATIONS PROTOCOL ROUTINES
; P. HURLEY/R. SCHMIDT MAYNARD, MASS. OCT-72
; R. PALM SYRACUSE, N.Y. JUNE-74
;*** COPYRIGHT 1972,73,74 DIGITAL EQUIPMENT CORP. MAYNARD, MASS. ***
; THIS MODULE CONTAINS THE ROUTINES WHICH IMPLEMENT THE
; PROTOCOL FOR COMMUNICATIONS WITH ANOTHER PROCESSOR.
; IT CONTAINS THE ROUTINES TO SEND AND RECEIVE A
; MESSAGE.
; ASSEMBLY INSTRUCTIONS:
; MUST BE ASSEMBLED WITH PARAMETER FILE COMPRM.MAC
; .COMPILE COMPRM.MAC+PROCOL.MAC
IFN FTVERSION,<
CUSTVER== 0 ;CUSTOMER VERSION NUMBER
DECVER== 1 ;DEC VERSION NUMBER
DECMVR== 0 ;DEC MINOR VERSION
DECEVR== 102 ;DEC EDIT VERSION
LOC 137 ;SET UP VERSION NUMBER
BYTE (3)CUSTVER(9)DECVER(6)DECMVR(18)DECEVR
RELOC
>
; DEFINE CONSTANTS
SOH= 001 ;START OF HEADER
STX= 002 ;START OF TEXT (DATA)
ETX= 203 ;END OF TEXT
ACK= 240 ;ACKNOWLEDGE
NAK= 120 ;NOT ACKNOWLEDGE
SLPTIM= ^D3000 ;MSEC TO HIBERNATE BEFORE NEXT TRY
HNGACK= ^D5000 ;M-SEC BEFORE SENDING RETRANSMISSION
HNGMES= ^D30000 ;MSEC TO TRY BEFORE GIVING UP
TRYMAX= 10 ;MAXIMUM NO. OF RETRIES (EITHER TO
;SEND A MESS. OR TO ACK AN OLD ONE)
HB.RTC=1B14 ;WAKE ON CHARACTER READY
SUBTTL GENERAL ROUTINES TO HANDLE CHARACTERS AND MESSAGES
;G E T C H R
;CALLED BY PUSHJ P,GETCHR
; ERROR RETURN ;NO CHAR FOUND
; NORMAL RETURN ;RETURNS CHAR IN CHR
EXTERNAL GETCHR ;ROUTINE TO GET A CHARACTER IN C
;N O C H R
;CALLED BY PUSHJ P,NOCHR
;PUTS JOB INTO SLEEP UNTIL CHAR AVAILABLE. TRIES UNTIL TIMEOUT
;OCCURS.
NOCHR: DEBUG(1) ;NO CHARACTER READY, WAIT FOR ONE
MSTIME T1, ;GET CURRENT TIME
MOVEM T1,CURTIM# ;STORE FOR LATER USE
MOVSI T1,(HB.RTC) ;SETUP WAKE CONDITIONS
HRRI T1,SLPTIM ;AND SLEEP TIME
HIBER T1, ;WAIT
JRST NOHIB ;UUO NOT IMPLEMENTED
CHKTIM: MSTIME T1, ;GET DAYTIME
SUB T1,CURTIM ;DID WE TRY
CAIL T1,SLPTIM ;LONG ENOUGH?
POPJ P, ;YES, GIVE ERROR RETURN
JUMPG T1,GET1 ;CHECK AGAIN IF SLEPT AT ALL
MOVEI T1,SLPTIM/5 ;NO CHAR IN COMM LINE BUFFER SO
; MUST BE CHAR IN ANOTHER TTY BUFFER.
HIBER T1, ;UNCONDITIONAL WAIT
JRST NOHIB ;UUO NOT IMPLEMENTED
SOS T1,LPCNT ;DECREMENT TOTAL WAIT COUNTER
JUMPE T1,CPOPJ ;WAITED LONG ENOUGH, ERROR RETURN
GET1: PUSHJ P,GETCHR ;TRY TO GET CHAR FROM COMM LINE
JRST NOCHR ;STILL NO CHAR THERE.
JRST CPOPJ1## ;RETURN WITH CHAR
GET: MOVEI T1,5 ;INIT LOOP COUNT FOR TIMEOUT
MOVEM T1,LPCNT# ; ...
JRST GET1 ;TRY TO FIND CHAR AND WAIT IF
; NECESSARY
NOHIB: MOVEI T1,SLPTIM/^D1000 ;SLEEP TIME IN SECONDS
SLEEP T1, ;SLEEP
JRST CHKTIM ;CHECK ELAPSED TIME
;P U T C H R
;CALLED BY MOVE CHR,CHAR ;CHARACTER IN CHR
; PUSHJ P,PUTCHR ;SEND IT
EXTERNAL PUTCHR ;ROUTINE TO SEND ONE CHARACTER OUT
;R C V B C C
;CALLED BY PUSHJ P,RCVBCC
;RETURNS NEXT BYTE IN CHR WITHOUT AFFECTING CHECKSUM.
;EXITS IN CASE OF TIMEOUT.
RCVBCC: DEBUG(2)
PUSHJ P,GET ;GET CRC BYTE
POPJ P, ;NONE THERE
MSTIME TIME, ;RESET TIMER
JRST CPOPJ1 ;SKIP RETURN
;R C V C H R
;CALLED BY PUSHJ P,RCVCHR
;UPDATES ACCUMULATED CHECKSUM.
;RETURNS NEXT CHAR IN CHR OR EXITS IN CASE OF TIMEOUT.
RCVCHR: DEBUG(3)
PUSHJ P,GET ;GET A BYTE
POPJ P, ;NONE THERE
MSTIME TIME, ;RESET TIMER
MOVE T1,CHR ;COMPUTE CRC:
XOR T1,CRC ;MAKE 8 BIT INDEX
ANDI T1,377 ;CLEAR UNWANTED BITS
LSH CRC,-10 ;SHIFT CRC 8 BITS
XOR CRC,CRCTAB(T1) ;UPDATE IT
JRST CPOPJ1 ;RETURN WITH CHAR
;S A C K
;CALLED BY MOVE T1,MSN ;MESSAGE NUMBER IN T1
; PUSHJ P,SACK ;SEND ACKNOWLEDGE
SACK: MOVEM T1,LMNACK ;SAVE LAST MESSAGE NUMBER ACKED
IORI T1,ACK ;BUILD MESS. IDENT.
SACK1: MOVEM T1,MSI ;STORE IT
DEBUG(4)
SETZ CRC, ;CLEAR CRC
MOVEI CHR,SOH ;GET START OF HEADER CHARACTER
PUSHJ P,SNDCHR ;1ST BYTE OUT
MOVE CHR,MSI
PUSHJ P,SNDCHR ;2ND BYTE OUT
ROT CRC,-10 ;GET BCC0
MOVE CHR,CRC
PUSHJ P,PUTCHR ;SEND IT. DO NO CRC
ROT CRC,10 ;RESTORE CRC
MOVE CHR,CRC
PUSHJ P,PUTCHR ;SEND BCC1
PUSHJ P,CLRINP## ;CLEAR ANY CHARACTERS IN INPUT BUFFER
PUSHJ P,PUTOUT## ;OUTPUT THE MESSAGE
JRST CPOPJ ;RETURN
;S N A K
;ENTERED BY JRST SNAK
;NOT ACKNOWLEDGES CURRENT MESSAGE, RETURNS TO RCVNXT.
;THE MESSAGE NUMBER IN THE NAK IS THE MESSAGE NUMBER EXPECTED
;AND NOT THE MESSAGE NUMBER ACTUALLY RECEIVED. THE MESSAGE NUMBER IN
;THE NAK SHOULD BE IGNORED.
SNAK: DEBUG(5)
SKIPGE T1,MSN ;GET MESSAGE NUMBER. IS IT FLOATING ?
SETZ T1, ;YES. SEND ZERO AS MESSAGE NUMBER
IORI T1,NAK ;MESS. IDENTIFICATION
PUSHJ P,SACK1 ;SEND NAK MESSAGE
MOVEI CNT,MSLMAX ;RESET COUNTER
JRST RCVNXT ;GET NEXT MESSAGE
;SANLDDCBH ROVE CHR,CHAR ;CHARACTER IN CHR
; PUSHJ P,SNDCHR
;SENDS A BYTE AND UPDATES CYCLIC REDUNDANCY CHECK.
SNDCHR: DEBUG(6)
MOVE T1,CHR ;SAVE CHR FOR CRC
PUSHJ P,PUTCHR ;SEND BYTE
XOR T1,CRC ;COMPUTE CRC
ANDI T1,377
LSH CRC,-10
XOR CRC,CRCTAB(T1)
JRST CPOPJ ;RETURN
SUBTTL ROUTINE TO GENERATE INITIAL CRC TABLE
;T A B G E N
;CALLED BY PUSHJ P,TABGEN
;GENERATES CRCTAB (256 WORDS) WITH 16 BIT BYTE DEPENDENT
;CRC RIGHT JUSTIFIED. BIT 35 IS 1 IFF BYTE HAS ODD PARITY.
;MUST BE CALLED AT INITIALIZATION.
ENTRY TABGEN
TABGEN: MOVEI CHR,377 ;START WITH LAST BYTE
CRCNXT: MOVEI T2,7 ;HERE ONCE FOR EACH BYTE
MOVE CRC,CHR ;GET CURRENT CHAR
CRCSHF: LSHC CRC,-1 ;SHIFT IT AND
SKIPGE CRC+1 ;CHECK RIGHT END BIT
XORI CRC,120001 ;HERE IF BIT WAS ON
SOJGE T2,CRCSHF ;NEXT BIT
MOVEM CRC,CRCTAB(CHR) ;STORE CRC
SOJGE CHR,CRCNXT ;NEXT BYTE
CPOPJ: POPJ P, ;NON-SKIP RETURN
SUBTTL PROTOCOL INITIALIZATION ROUTINE
;I N I T P R
;INITIALIZE THE PROTOCOL ROUTINES.
;PERFORM ANY OTHER INITIALIZATION REQUIRED FOR LOCAL ROUTINES.
;MUST BE CALLED AT INITIALIZATION.
;CALLING SEQUENCE:
; PUSHJ P,INITPR
; ALWAYS RETURN HERE
ENTRY INITPR
INITPR:
;SET THE MESSAGE NUMBER TO -1.
;THE RECEIVE ROUTINE INTERPRETS THIS TO MEAN THAT IT SHOULD SET THE
;MESSAGE NUMBER TO THE ONE RECEIVED IF THE MESSAGE RECEIVED WAS
;CORRECT. THE SEND ROUTINE WILL INCREMENT THE MESSAGE NUMBER BY
;ONE BEFORE SENDING A MESSAGE. THEREFORE, IF THESE ROUTINES SEND
;THE FIRST MESSAGE AFTER INITIALIZATION, ITS MESSAGE
;NUMBER WILL BE ZERO (0).
SETOM MSN ;FLOAT THE MESSAGE NUMBER
SETZM PRSTAT ;CLEAR PROTOCOL STATUS WORD
PUSHJ P,TABGEN ;GENERATE THE INITIAL CRC TABLE
MOVSI T1,STATBL ;SETUP TO CLEAR THE PERFORMANCE
HRRI T1,STATBL+1 ; STATISTICS TABLE ENTRIES TO ZERO
MOVEI T2,STATLN-1 ;GET LENGTH OF TABLE -1
SETZM STATBL ;CLEAR THE FIRST ENTRY
JUMPLE T2,.+2 ;ALL DONE IF ONLY ONE
BLT T1,STATBL(T2) ;CLEAR THE REMAINDER OF THE TABLE
IFN FTSNOI,<
MOVEI T1,NAK ;SETUP NAK WITH ZERO MSG. NUMBER
PUSHJ P,SACK1 ;SEND IT OUT.
>
POPJ P, ;RETURN TO CALLER
SUBTTL CSTAT - ROUTINE TO RETURN THE COMMUNICATIONS PERFORMANCE STATISTICS
ENTR (CSTAT) ;ENTRY POINT TO GET PERFORMANCE STATISTICS
SAVE (HIAC) ;SAVE TEMP REGISTERS
SKIPA T1,[XWD -STATLN,STATBL] ;AOBJN POINTER FOR ENTRIES
GETST: AOJ L, ;POINT TO NEXT ARGUMENT
MOVE 0,(T1) ;GET THE STATISTIC VALUE
MOVEM 0,@(L) ;RETURN IT TO THE CALLER
AOBJN T1,GETST ;FOR ALL TABLE ENTRIES
JRST EXIT1 ;RETURN TO CALLER
SUBTTL RECV - TO RECEIVE MESSAGES FROM ANOTHER PROCESSOR
;R E C V
COMMENT %
CALL FROM COBOL:
77 NUMBER
77 FLAG
77 TYPE
01 DUMMY
02 ARRAY OCCURS 211 TIMES
...
ENTER MACRO RECV USING ARRAY, NUMBER, FLAG, TYPE.
...
COBOL SHOULD GENERATE THE FOLLOWING MACRO CODE:
REQUIRES COBOL COMPILER VERSION 5 OR LATER
MOVEI 16,ARGLST
PUSHJ 17,RECV
XWD -4,0
ARGLST: ARG [ARRAY]
ARG 0,NUMBER
ARG 0,FLAG
ARG 0,TYPE
RECV RECEIVES MESSAGES FROM ANOTHER PROCESSOR.
EXTRACTS THE DATA AND STORES THEM AS 8 BIT BYTES
RIGHT JUSTIFIED IN ARRAY. CONTINUES UNTIL EITHER
THE NUMBER'TH BYTE HAS BEEN STORED, OR A TIME-
OUT OCCURS.
RETURNS IN FLAG -1, IF THE REQUEST HAS COMPLETELY
BEEN SATISFIED.
N, IF THERE OCCURED A TIMEOUT
AFTER THE N'TH BYTE WAS PROPER-
LY RECEIVED.
A TIMEOUT OCCURS, WHEN WITHIN 30 SECONDS
NO SOH COULD BE RECOGNIZED BY RCVMES, OR
NO CHARACTER AT ALL COULD BE RECEIVED. %
ENTR (RECV) ;ENTRY POINT TO RECEIVE A MESSAGE
SAVE (HIAC) ;SAVE TEMP ACS
MOVEI T1,@(L) ;GET ARRAY ADDRESS (1ST ARGUMENT)
ARYREF (T1) ;GET REAL ARRAY ADDRESS
HRLI T1,TXTBUF
MOVEM T1,BLTPTR ;INITIALIZE BLT POINTER
AOJ L, ;INCREMENT ARG POINTER
MOVE T1,@(L) ;GET 2ND ARG
MOVEM T1,NUMBER ;SAVE IT
AOJ L, ;INCREMENT ARG POINTER
MOVEI T1,STDMR ;DATA MESSAGE RECEIVED BY SEND
TDNN T1,PRSTAT ;IS IT WAITING ?
SKIPGE T1,MSN ;OR MESSAGE NUMBER FLOATING ?
JRST RECV0 ;YES. DON'T UPDATE MSG NO.
AOJ T1, ;UPDATE MESS NO.
ANDI T1,17 ;TRUNCATE TO 4 BITS
MOVEM T1,MSN ;SAVE 4 BIT MESSAGE NUMBER
RECV0: SETZM FLAG ;ZERO NO. OF PROPERLY RECEIVED CHARS
SETZM RESEND ;AND RESEND COUNTER
RCVNXT: DEBUG(7)
MSTIME TIME, ;INITIALIZE TIMER
RCVNX1: MOVEI CNT,MSLMAX ;INITIALIZE COUNTER
MOVEI T1,STDMR ;DATA MESSAGE ALREADY RECEIVED
TDNN T1,PRSTAT ;DOES CONDITION REALLY EXIST ?
JRST RCVNX2 ;NO. GET THE DATA MESSAGE
ANDCAM T1,PRSTAT ;YES. CLEAR INDICATION
JRST RCVNX3 ;USE DATA ALREADY COLLECTED
RCVNX2: PUSHJ P,RCVMES ;GO RECEIVE A MESSAGE
JRST NOMESS ;THERE WASN'T A COMPLETE ONE
SKIPE T1,ACKCHR ;DID WE GET AN ACKNOWLEDGEMENT INSTEAD?
JRST CHKACK ;YES, GO HANDLE IT
RCVNX3: MOVE T1,MSNRCV ;NOW CHECK MESSAGE NUM
CAME T1,MSN ;IS THIS THE CORRECT MESSAGE
JRST BADMSN ;NO. CHECK OTHER POSSIBLE CONDITIONS
DEBUG(21)
PUSHJ P,SACK ;ACKNOWLEDGE
RCVOK: DEBUG(22)
SETZM RESEND
MOVE CNT,CCRCV# ;GET TEXT COUNT
CAMLE CNT,NUMBER ;GET ALL DATA BYTES WANTED?
MOVE CNT,NUMBER ;YES. RETURN ONLY THOSE ASKED FOR
ADDM CNT,FLAG ;NO. OF PROPERLY RECEIVED BYTES
MOVE T1,BLTPTR ;GET BLT POINTER
HRRZ T2,T1 ;SET UP LAST BLT ADDRESS
ADD T2,CNT
BLT T1,-1(T2) ;TRANSFER TO USER'S ARRAY
IFE FTMRCV,< ;RECEIVE ONE MESSAGE PER REQUEST
JRST RCVXIT ;TAKE SUCCESSFUL RETURN
>
IFN FTMRCV,< ;RECEIVE MULTIPLE MESSAGES IN 1 REQUEST
MOVN T1,CNT ;DECREMENT CHAR REQUEST COUNT BY
ADDM T1,NUMBER ; NUMBER RECEIVED
SKIPG NUMBER ;MORE BYTES WANTED?
JRST RCVXIT ;NO.
ADDM CNT,BLTPTR ;YES. UPDATE BLT POINTER
AOS T1,MSN ;NO. OF NEXT MESS.
ANDI T1,17 ;CLEAR CARRY
MOVEM T1,MSN
JRST RCVNXT ;GET IT
>
RCVXT1: SKIPGE MSN ;MESSAGE NUMBER FLOATING ?
JRST RCVXT2 ;YES. DON'T TOUCH IT
SOS T2,MSN ;NO. MESSAGE NUMBER INCREMENTED AND NOT USED
ANDI T2,17 ;DECREMENT TO PRESERVE MESSAGE NUMBER
MOVEM T2,MSN ;SYNCHRONIZATION
RCVXT2: TDZA T2,T2 ;ERROR EXIT, SET IERR TO 0
RCVXIT: SETO T2, ;SUCCESSFUL EXIT, SET IERR TO -1
MOVEM T2,@(L) ;STORE ERROR FLAG
AOJ L, ;INCREMENT ARG POINTER
MOVE T2,FLAG ;GET ERROR TYPE
MOVEM T2,@(L) ;SET UP FLAGWORD (ITYPE)
EXIT1: AOJ L, ;SET UP RETURN ADR
RESTOR (HIAC) ;RESTORE ACS
JRST EXIT%% ;RETURN TO CALLER THRU EXIT ROUTINE
; HERE IF GOT WHAT LOOKED LIKE AN ACKNOWLEDGEMENT MESSAGE.
; THAT IS, THE HIGH ORDER 4 BITS OF THE SECOND MESSAGE CHARACTER
; (MESSAGE IDENTIFIER) ARE NONZERO AND THE NEXT TWO CHARACTERS ARE
; A CORRECT CRC.
; REGISTER T1 CONTAINS THE ACKNOWLEDGEMENT CHARACTER (ACKCHR)
; RETURNED BY RCVMES.
CHKACK: CAIN T1,ACK_<-4> ;IS THIS A VALID ACK ?
JRST BADAKN ;YES. IGNORE
CAIE T1,NAK_<-4> ;IS THIS A VALID NAK ?
JRST NOMESS ;NO. BAD MESSAGE (NAK IT)
BADAKN: MOVEI T1,UEXPAK ;UNEXPECTED ACKNOWLEDGEMENT
AOS STATBL(T1) ;RECORD THAT IT OCCURRED
JRST RCVNXT ;IGNORE TO AVOID ACK/NAK LOOPS
; HERE IF GOT ERROR RETURN FROM RCVMES.
NOMESS: DEBUG(24)
CAIGE CNT,MSLMAX ;HAVE WE RECEIVED ANY LEGAL CHARACTERS
JRST SNAK ;YES, SEND A NAK OUT
DEBUG(25)
MSTIME T1, ;GET CURRENT TIME
SUB T1,TIME ;CALCULATE TIME SINCE START
CAIGE T1,HNGMES ;HAVE WE WAITED LONG ENOUGH
JRST RCVNX1 ;NO. TRY AGAIN
DEBUG(26)
JRST RCVXT1 ;YES. GIVE TIMED OUT ERROR RETURN
; HERE IF RECEIVED MESSAGE NUMBER DOES NOT AGREE WITH WHAT
; WAS EXPECTED.
BADMSN: DEBUG(27)
CAMN T1,LMNACK ;MESSAGE NO. SAME AS LAST ONE ACKED ?
JRST RLMNAR ;YES. COUNT IT, REACKNOWLEDGE, AND TRY AGAIN
AOS STATBL+NRESET ;NO. ASSUME A RESTART IN OTHER SYSTEM
MOVEM T1,MSN ;AND INITIALIZE MESSAGE NUMBER TO THE ONE RECEIVED
PUSHJ P,SACK ;SEND AN ACK OF THIS MESSAGE NUMBER
JRST RCVOK ;GO BACK TO MAIN STREAM
RLMNAR: AOS STATBL+NACKR ;RECEIVED LAST MESSAGE ACKED. COUNT IT
PUSHJ P,SACK ;SEND OUT AN ACK FOR IT
JRST RCVNXT ;THEN GO WAIT FOR THE RIGHT MESSAGE
;ROUTINE TO RECEIVE MESSAGES OR ACK/NAK'S
;CALLED BY: PUSHJ P,RCVMES
; ERROR RETURN ;NO CORRECT MESSAGE RECIEVED
; NORMAL RETURN
;ON RETURN:
; IF DATA MESSAGE MSNRCV CONTAINS RECEIVED MESSAGE NUMBER
; ACKCHR CONTAINS ZERO (0)
; IF ACKNOWLEDGEMENT MESSAGE ACKCHR CONTAINS ACKNOWLEDGE CHARACTER
; ACKMSN CONTAINS ACKNOWLEDGE MESSAGE NO.
RCVMES:
;CHECK FOR START OF HEADER.
RCVSOH: DEBUG(10)
SETZ CRC, ;INITIALIZE CRC
PUSHJ P,RCVCHR ;GET A BYTE
POPJ P, ;TIMED OUT
CAIN CHR,SOH ;IS IT SOH?
SOJG CNT,RCVMSN ;YES. CHECK MESS. NO.
BADCHR: DEBUG(11)
JRST RCVSOH ;GO WAIT FOR A SOH
;CHECK MESSAGE IDENTIFICATION. EXPECTED NUMBER IS MSN.
RCVMSN: DEBUG(12)
PUSHJ P,RCVCHR ;GET A BYTE
POPJ P, ;TIMED OUT
SETZM ACKCHR# ;INITIALIZE FLAG
TRNE CHR,360 ;IS THIS AN ACK OR A NAK?
JRST CHKMSI ;POSSIBLY
MOVEM CHR,MSNRCV# ;STORE MESSAGE NUMBER
SOJG CNT,RCVCC ;YES. CHECK CC
JRST BADCHR ;RECEIVED TOO MANY CHARACTERS
;FROM HERE ON, A DATA MESSAGE IS EXPECTED.
;CHECK CHARACTER COUNT (ODD PARITY, COUNT.LE.TXLMAX).
RCVCC: DEBUG(13)
PUSHJ P,RCVCHR ;GET A BYTE
POPJ P, ;TIMED OUT
IFN FTODCC,
< MOVE T1,CRCTAB(CHR) ;LOOK INTO TABLE
TRNN T1,1 ;WHETHER BYTE HAS
;ODD PARITY.
JRST BADCHR ;IT HASN'T.
ANDI CHR,177 ;GET CHAR COUNT
>
CAILE CHR,TXLMAX ;TOO MANY?
JRST BADCHR ;YES.
MOVEM CHR,CCRCV ;SAVE COUNT
MOVN T2,CHR ;FOR DATA POINTER
HRLI T2,TXTBUF ;SET UP TO SEND OUT TEXT
SOJG CNT,RCVSTX ;STILL GOT ROOM
JRST BADCHR ;NO, TOO MANY CHARACTERS RECEIVED
;CHECK START OF TEXT.
RCVSTX: DEBUG(14)
PUSHJ P,RCVCHR ;GET A BYTE
POPJ P, ;TIMED OUT
SOSLE CNT ;RECEIVED TOO MANY CHARS YET?
CAIE CHR,STX ;IS IT STX?
JRST BADCHR ;NO.
;READ IN TEXT AND STORE IN TXTBUF.
MOVSS T2 ;DATA POINTER IN CNT
RCVTXT: DEBUG(15)
PUSHJ P,RCVCHR ;GET A DATA ITEM
POPJ P, ;TIMED OUT
MOVEM CHR,(T2) ;STORE IT
SOSG CNT
POPJ P, ;RECEIVED TOO MANY CHARACTERS!
AOBJN T2,RCVTXT ;NEXT DATA ITEM
;CHECK FOR ETX
RCVETX: DEBUG(16)
PUSHJ P,RCVCHR ;GET A BYTE
POPJ P, ;TIMED OUT
SOSLE CNT ;MESSAGE TOO LONG?
CAIE CHR,ETX ;IS IT ETX?
POPJ P, ;NO.
;CHECK CRC. USE RCVBCC INSTEAD RCVCHR TO NOT INCLUDE
;BCC0 AND BCC1 IN CHECKSUM.
RCVBC0: DEBUG(17)
PUSHJ P,RCVBCC ;GET A BYTE
POPJ P, ;TIMED OUT
LSHC CRC,-10 ;GET HIGH ORDER PART OF CRC
SOSLE CNT
CAME CRC,CHR ;OK?
POPJ P, ;NO.
LSHC CRC,10 ;RESTORE CRC
ANDI CRC,377 ;GET LOW ORDER PART
DEBUG(20)
PUSHJ P,RCVBCC ;GET A BYTE
POPJ P, ;TIMED OUT
CAME CRC,CHR ;CRC OK?
POPJ P, ;NO
MOVE T1,MSNRCV ;GET MESSAGE NUMBER RECEIVED
SKIPGE MSN ;IS THE MESSAGE NUMBER FLOATING ?
MOVEM T1,MSN ;YES. INITIALIZE TO THE VALUE RECEIVED
JRST CPOPJ1 ;MESSAGE OK. GIVE SKIP RETURN
; COME HERE IF RECEIVED MESSAGE IDENTIFICATION CHARACTER
; (SECOND MESSAGE CHAR.) LOOKED LIKE IT MAY INDICATE AN
; ACKNOWLEDGEMENT MESSAGE.
CHKMSI: LDB T1,ANPTR ;GET ACK FIELD
MOVEM T1,ACKCHR ;STORE FOR LATER
DEBUG(35)
ANDI CHR,17 ;CLEAR ACK FIELD
MOVEM CHR,ACKMSN# ;STORE MSN NUMBER
SOJG CNT,CHKBCC ;GO GET CRC
JRST BADCHR ;TOO MANY CHARACTERS RECEIVED
CHKBCC: DEBUG(36)
PUSHJ P,RCVBCC ;GET CRC 1
POPJ P, ;NONE THERE GIVE ERROR RETURN
LSHC CRC,-10 ;SHIFT IT
SOSLE CNT ;CHECK COUNT
CAME CRC,CHR ;IS THIS CHARACTER CORRECT
JRST BADCHR ;NO
LSHC CRC,10 ;RESTORE ORIGINAL CRC
ANDI CRC,377 ;CLEAR LEFTMOST BITS
PUSHJ P,RCVBCC ;GET LOW ORDER CRC BITS
POPJ P, ;NONE THERE
CAME CRC,CHR ;IS THIS CHARACTER OK
JRST BADCHR ;NO
JRST CPOPJ1 ;YES, GIVE SKIP RETURN
SUBTTL SEND - TO SEND MESSAGES TO ANOTHER PROCESSOR
ENTR (SEND) ;ENTRY POINT TO SEND A MESSAGE
SAVE (HIAC) ;SAVE TEMP ACS
MOVEI T2,@(L) ;GET ARRAY ADDRESS (1ST ARGUMENT)
ARYREF (T2) ;GET CORRECT ARRAY ADDR. IF NECESSARY
MOVEM T2,ARYPTR ;STORE AS ARRAY POINTER
AOJ L, ;ADVANCE ARG POINTER
MOVE T1,@(L) ;GET NUMBER OF CHARACTERS TO SEND
MOVEM T1,NUMBER ;STORE IT
AOJ L, ;ADVANCE ARG POINTER
MOVEI T1,STDMR ;DATA MESSAGE BEEN RECEIVED BUT NO
TDNN T1,PRSTAT ; ACKNOWLEDGEMENT SENT ?
JRST SEND0 ;NO. JUST SEND THE MESSAGE
ANDCAM T1,PRSTAT ;YES. CLEAR THE FLAG
MOVE T1,MSNRCV ;GET MESSAGE NUMBER RECEIVED
IORI T1,NAK ;MAKE A NAK MESSAGE IDENTIFIER
PUSHJ P,SACK1 ;NAK THE DATA MESSAGE. MAYBE THE CALLER
; WILL GET THE IDEA EVENTUALLY AND CALL
; RECV TO GET THE MESSAGE BEFORE IT GETS LOST.
JRST SEND1 ;USE THE SAME MESSAGE NUMBER AGAIN
SEND0: AOS T1,MSN ;UPDATE MESS NO.
ANDI T1,17 ;TRUNCATE MSN TO 4 BITS
MOVEM T1,MSN ;SAVE TRUNCATED MSN
SEND1: SETZM FLAG ;ZERO NUMBER OF CHARS XMITTED
SETZM RESEND ;ZERO RESEND COUNT
; UPON ARRIVING HERE, T2 MUST CONTAIN THE ADDRESS OF THE FIRST
; CHARACTER IN THE ARRAY TO BE SENT (SEE SNDTXT-1).
SNDNXT: DEBUG(30)
MOVEI T1,TXLMAX ;TO SET UP CC
CAMLE T1,NUMBER ;MORE THAN TXLMAX CHAR'S LEFT?
MOVE T1,NUMBER ;NO. THIS IS LAST MESS.
MOVEM T1,CCSEND# ;SAVE CHAR COUNT
;SEND THE MESSAGE.
;SEND SOH:
SETZ CRC, ;INITIALIZE CRC
MOVEI CHR,SOH ;GET START OF HEADER CHARACTER
PUSHJ P,SNDCHR ;SEND IT OUT
;SEND MSN:
MOVE CHR,MSN ;GET MSN
PUSHJ P,SNDCHR ;SEND IT OUT
;SEND CC, ODD PARITY:
MOVE CHR,CCSEND ;GET CHARACTER COUNT
IFN FTODCC,
< MOVE T1,CRCTAB(CHR)
TRNN T1,1 ;HAS BYTE ODD PAR?
TRO CHR,200 ;NO. MAKE IT ODD
>
PUSHJ P,SNDCHR ;SEND OUT CHARACTER COUNT
;SEND STX:
MOVEI CHR,STX ;GET START OF TEXT
PUSHJ P,SNDCHR ;SEND STX OUT
;SEND THE TEXT (CC BYTES):
MOVN T1,CCSEND ;POINTER
HRL T2,T1 ;ARRAY ADDR IN T2
SNDTXT: MOVE CHR,(T2) ;GET NEXT CHARACTER TO SEND
PUSHJ P,SNDCHR ;SEND IT
AOBJN T2,SNDTXT ;LOOP BACK FOR MORE
;SEND ETX:
MOVEI CHR,ETX ;GET END OF TEXT CHARACTER
PUSHJ P,SNDCHR ;SEND OUT ETX
;SEND BCC0:
ROT CRC,-10 ;GET HIGH ORDER CRC BITS
MOVE CHR,CRC ;...
PUSHJ P,PUTCHR ;SEND OUT BCC1
;SEND BCC1:
ROT CRC,10 ;GET LOW ORDER CRC BITS
MOVE CHR,CRC ;...
PUSHJ P,PUTCHR ;SEND OUT BCC2
IFN FTCIBS,< ;CLEAR INPUT BEFORE SENDING MESSAGE
PUSHJ P,CLRINP## ;CLEAR THE TTY INPUT BUFFER
>
PUSHJ P,PUTOUT ;SEND OUT THE MESSAGE
;RECEIVE AN ACK OR NAK MESSAGE:
DEBUG(31)
MSTIME TIME, ;READ CURRENT TIME FOR TIMEOUT PURPOSES
RCVACK: MOVEI CNT,MSLMAX ;INITIALIZE COUNT TO MAX MESSAGE SIZE
SETZM NAKFLG ;INITIALIZE NAK FLAG
PUSHJ P,RCVMES ;GET ACK OR NAK
JRST NOACK ;NONE THERE
SKIPN T1,ACKCHR ;WAS THIS AN ACK/NAK
JRST GOTMES ;NO, IT WAS ANOTHER LEGAL MESSAGE
CAIN T1,ACK_-4 ;IS THIS AN ACK?
JRST CHKMSN ;YES
CAIE T1,NAK_-4 ;IS THIS A NAK?
JRST NOACK ;NO, THIS IS A BAD MESSAGE
SETOM NAKFLG ;MARK THAT A NAK WAS SEEN
CHKMSN: MOVE T1,ACKMSN ;GET MSN RECEIVED
CAMN T1,MSN ;IS THIS THE ONE WE EXPECT
SKIPE NAKFLG ;AND WAS THIS AN ACK
JRST BADACK ;NO, GO RESEND
;ACKNOWLEDGE RECEIVED. CHECK FOR MORE CHAR'S TO BE SENT.
SNDMOR: DEBUG(37)
MOVN T1,CCSEND ;GET CHARACTERS SENT COUNT
SUBM T1,FLAG ;COUNT CHARS SUCCESSFULLY RECEIVED
ADDM T1,NUMBER ;SUBTRACT FROM NUMBER LEFT
SKIPG NUMBER ;ANY MORE TO GO OUT
JRST SNDXIT ;NO, WE ARE THROUGH
SETZM RESEND ;YES, GO SEND OUT NEXT GROUP
MOVE T2,CCSEND ;GET CHARACTERS SENT COUNT
ADDB T2,ARYPTR ;UPDATE ARRAY POINTER
AOS T1,MSN ;UPDATE MSN
ANDI T1,17 ;TRUNCATE TO 4 BITS
MOVEM T1,MSN ;STORE TRUNCATED MSN
JRST SNDNXT ;GO SEND OUT NEXT MESSAGE
NOACK: DEBUG(40)
CAIGE CNT,MSLMAX ;ANY LEGAL CHARACTERS SEEN
JRST BADACK ;YES, GO RESEND
NOACK1: DEBUG(41)
MSTIME T1, ;GET TIME
SUB T1,TIME ;CALCULATE TIME WAITED
CAIG T1,HNGACK ;HAVE WE TIMED OUT
JRST RCVACK ;NO, GO WAIT SOME MORE
BADACK: DEBUG(42)
AOS T1,RESEND ;UPDATE COUNTER
CAIL T1,TRYMAX ;DID WE TRY ENOUGH?
JRST SNDXT1 ;YES. QUIT.
;NOT ACKNOWLEDGE RECEIVED. RETRANSMIT MESSAGE.
SNDAGN: DEBUG(43)
MOVE T2,ARYPTR ;NO
JRST SNDNXT ;GO RETRANSMIT THE MESSAGE
;HERE IF WAITING FOR ACK OR NAK BUT GOT A DATA MESSAGE
GOTMES: MOVE T1,MSNRCV ;GET MSN RECEIVED
CAMN T1,MSN ;IS IT WHAT WE ARE TRYING TO SEND ?
JRST SNDXT0 ;YES, GIVE ERROR RETURN. CALL RECV FOR A MSG
MOVEI T2,NIGNS ;ASSUME MESSAGE IS TO BE IGNORED
CAME T1,LMNACK ;IS MESSAGE NO. SAME AS THE LAST ONE ACKED?
JRST GOTMS2 ;NO. THEN COUNT AND IGNORE THIS MESSAGE
;YES, THEN SEND OUT AN ACK FOR THIS MSN
PUSHJ P,SACK ;THE OTHER PROGRAM PROBABLY LOST OUR ACK
MOVEI T2,NACKS ;POINT TO MESSAGE REACKNOWLEDGED BY SEND ENTRY
GOTMS2: AOS STATBL(T2) ;INCREMENT THE STATISTICS ENTRY
JRST NOACK1 ;NOW GO WAIT SOME MORE
; EXIT POINT FOR SEND ROUTINE
SNDXT0: MOVEI T2,STDMR ;DATA MESSAGE ALREADY RECEIVED (NO ACK SENT)
IORM T2,PRSTAT ;SAVE STATUS FOR RECV
MOVEI T2,1 ;SET ERROR FLAG TO 1 (FALSE)
JRST SNDXT2 ;HAVE RECEIVED A VAILD MESSAGE
SNDXT1: SKIPGE MSN ;MESSAGE NUMBER FLOATING ?
JRST SNDXT3 ;YES. DON'T TOUCH IT
SOS T2,MSN ;NO. MESSAGE NUMBER INCREMENTED AND NOT USED
ANDI T2,17 ;DECREMENT TO PRESERVE MESSAGE NUMBER
MOVEM T2,MSN ;SYNCHRONIZATION
SNDXT3: TDZA T2,T2 ;IERR = 0
SNDXIT: SETO T2, ;IERR = -1 OK RETURN
SNDXT2: MOVEM T2,@(L) ;STORE ERROR FLAG
AOJ L, ;INCREMENT ARG POINTER
MOVE T2,FLAG ;GET CHARACTER COUNT
MOVEM T2,@(L) ;STORE IT IN 4TH ARG (ITYPE)
JRST EXIT1 ;RETURN TO CALLER
SUBTTL STORAGE AREAS
ANPTR: POINT 4,CHR,31 ;TO DECODE MSI
ARYPTR: Z ;POINTS TO 1ST BYTE IN
;USER ARRAY TO BE SENT
BLTPTR: XWD TXTBUF,0 ;TO FILL USER'S ARRAY
FLAG: Z ;TO COUNT NO. OF ACTUALLY
;XMITTED BYTES AND TO INDICATE
;TIMEOUT
PRSTAT: Z ;PROTOCOL STAUS WORD
; BITS IN RIGHT HALF
STDMR= 1B35 ;DATA MESSAGE RECEIVED (BY SEND ROUTINE)
MSI: Z ;MESS. IDENTIFICATION
MSN: Z ;NO. OF CURRENT MESSAGE
NAKFLG: Z ;IF -1: LAST MESSAGE
;RECEIVED WAS NAK
NUMBER: Z ;FOR 2ND ARGUMENT
RESEND: Z ;NO. OF TRIES OF RETRANSMITS
LMNACK: Z ;LAST MSG NUMBER POSITIVELY ACKNOWLEDGED
STATBL: BLOCK STATLN ;TABLE FOR PERFORMANCE STATISTICS
;ENTRIES ARE DEFINED IN COMPRM.MAC
CRCTAB: BLOCK ^D256 ;TABLE FOR CRC
TXTBUF: BLOCK TXLMAX ;TO STORE TEXT
END ;END OF PROCOL