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 ;S N D C H R ;CALLED BY MOVE 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