.TITLE DSPPRM - Dispatch/SPP Primitive calls .INSERT MOSCNF-1.SML .INSERT MOSMAC.SML .INSERT MOSTBL.SML .INSERT DSPTBL.SML .INSERT DSPMAC.SML .LIST ME $CNFIG ; SYSTEM CONFIGURATION $DFMDB ; MATCH DESCRIPTOR BLOCK $DFPKD ; PACKET DESCRIPTOR .PAGE $DFDOF ; DISPATCH OPTION FLAGS $DFDSC ; DISPATCH STATUS CODES $DFDCN ; DEFINE DISPATCH CONSTANTS .PAGE $DFCCB ; CONNECTION CONTROL BLOCK .PAGE $DFDOP ; DISPATCH/LABLER OP-CODES $DFDST ; DEFINE DISPATCH STATES .NLIST ME .LIST MEB .ENABLE ISD .PAGE ; ; GLOBALS ; .GLOBL $CVTBL,$NSCON,$LBLID,$DSPID .GLOBL $PROPN,$PRRCV,$PRSND,$PRCLS .GLOBL FRMHDR,SNDPKT,DEQPKT,RTNACK .GLOBL HNDOFF,RCVCLN,RLSCCB,CVCON .GLOBL $DPMTP,$DPMBT,$TIUID .SBTTL $PROPN - Packet Radio Open Connection Primitive ; ; CALLED WITH: R0 (LO) - OPEN SIGNAL OPCODE ; R0 (HI) - CONNECTION TYPE FLAGS ; R1 - ADDRESS OF DESCRIPTOR MATCH BLOCK ; ; RETURNS WITH: R0 (LO) - CONNECTION ID ; R0 (HI) - RETURN CODE $DPMTP: $PROPN: $PUSH R1,R2,R3,R4,R5 MOV #-2,R3 ; R3 = TALLY FOR MD LCL AND FGN WORDS SUB #MDBLEN,SP ; ALLOCATE AN MDB ON THE STACK MOV SP,R4 ; R4 = A(MDB) 1$: MOV (R1)+,(R4) ; COPY WORD SWAB (R4)+ ; SWAB WORD TO MATCH INCOMING PKTS $LOOP R3,1$ ; LOOP BIT #DF.DFC*400,R0 ; SHOULD DEFAULT CONTROL WORD BE USED? BEQ 2$ ; NO ==> SKIP BIT #DF.TRN*400,R0 ; TRANSPARENT? BEQ 3$ ; NO ==> SPP MOV #DFTRNM,(R4)+ ; SET DEFAULT MASK MOV #DFTRNC,(R4) ; SET DEFAULT COMPARE VALUE BR 4$ 3$: MOV #DFSPPM,(R4)+ ; SET DEFAULT MASK MOV #DFSPPC,(R4) ; SET DEFAULT COMPARE VALUE BR 4$ ; CONTINUE 2$: MOV (R1)+,(R4)+ ; COPY CONTROL MASK MOV (R1)+,(R4) ; COPY CONTROL COMPARE VALUE 4$: MOV SP,R1 ; R1 = A(MDB) TSTB MDLCLM+1(R1) ; CK HI BYTE OF (SWAPED) LOC MASK BEQ 10$ ; BR IF TIUID NOT LOOKED AT TSTB MDLCLC+1(R1) ; CK HI BYTE OF (SWAPED) LOC ID BNE 10$ ; BR IF TIUID SUPPLIED MOVB $TIUID,MDLCLC+1(R1) ; INSERT TIUID IN LOC ID 10$: COM MDLCLM(R1) ; CHANGE MASK TO BIC FORM COM MDFGNM(R1) ; MOV #$CVTBL,R4 ; R4 = A(CONN VECTOR TABLE) MOV (R4)+,R3 ; R3 = TALLY OF MAX. CONN'S ALLOWED MTCHLP: MOV (R4)+,R2 ; R2 = A(POSSIBLE CONNECTION TABLE) BEQ NXTENT ; NO CCB ==> NEXT ENTRY JSR PC,MTCHDS ; MATCH DESCRIPTORS FOR DUPLICATION ; RETURN R2=0 IF A MATCH TST R2 ; MATCH? BEQ CAROPN ; MATCH ==> CONN. OPEN ERROR NXTENT: $LOOP R3,MTCHLP ; ==> MATCH LOOP MOV #$CVTBL,R4 ; R4 = A(CONN VECTOR TABLE) MOV (R4)+,R2 ; R2 = NO. OF ENTRIES MOV #1,R3 ; INIT CONNID COUNT TO ONE SLOTLP: TST (R4)+ ; SLOT OPEN BEQ SLOTOP ; YES ==> SLOT OPEN INC R3 ; BUMP CONNID COUNT $LOOP R2,SLOTLP ; ==> SLOT LOOP BR NOSLOT ; ==> NO SLOT ERROR SLOTOP: MOV R0,R5 ; R5 = FLAGS AND OP-CODE $AVS #CCBLEN ; ALLOCATE CCB TST R2 ; any storage? BEQ NOSTOR ; No ==> No strage error INC $NSCON ; Bump connection no. MOV R5,R0 ; R0 = FLAGS AND OP-CODE MOV R2,R5 ; R5 = A(ccb) MOV R5,-(R4) ; Set vector table $PUSH R4 ; Save pointer to vector table MOV #CCBLEN/2,R4 ; R4 = Length of CCB in words CLRLP: CLR (R2)+ ; Clear word $LOOP R4,CLRLP ; ==> Clear loop MOVB R3,CONNID(R5) ; Save CONNID $POP CVTPTR(R5) ; Save vector table pointer MOVB R0,CUROPC(R5) ; Save Op-code SWAB R0 ; LSB R0 = Option flags MOVB R0,COPFLG(R5) ; Save option flags $GAPID ; R0 = PID MOVB R0,CURPID(R5) ; Save caller's PID MOV R5,R2 ; R2 = A(CCB) MOV #MDBLEN/2,R0 ; R0 = Length of match descriptor MTCHTL: MOV (R1)+,(R2)+ ; Transfer in to CCB $LOOP R0,MTCHTL ; ==> Match des. transfer loop $GETOD ; R1 = LSW of TOD MOV R0,COPTIM(R5) ; SAVE TIME CONNECTION OPENED MOV R1,COPTIM+2(R5) ; BIC #HS.RCF,R1 ; CLEAR RETRANSMIT COUNT FIELD MOV R1,CSEQNO(R5) ; Init SEQNO ADD #HS.RCF+1,R1 ; R1 = SEQNO + 1 MOV R1,CSDLWE(R5) ; INIT SEND LWE MOV R5,R4 ; R4 = A(CCB) ADD #CSNDQH,R4 ; R4 = A(SEND QUEUE HEAD) MOV R4,CSNDQT(R5) ; INIT SEND QUEUE TAIL PNTR ADD #CRCVQH-CSNDQH,R4 ; R4 = A( RECEIVE QUEUE HEAD) MOV R4,CRCVQT(R5) ; INIT RECEIVE QUEUE TAIL ADD #CRTXQH-CRCVQH-PDRTX,R4 ; R4 = A( RETRANSMIT QUEUE HEAD - PDRTX) MOV R4,CRTXQT(R5) ; INIT RETRANSMIT QUEUE HEAD BITB #DF.NTP,COPFLG(R5) ; NO TOP PROCESSING REQUESTED? BNE NOTOPS ; YES ==> NO TOP'S $SGNLI $LBLID,#SG.TOP,R1 ; Signal Labeler to send out TOP NOTOPS: BITB #DF.TRN,COPFLG(R5) ; Transparent connection? BNE TRNSC ; YES ==> Transparent connection BIS #HF.SPP,CCTLMK(R5) ; MAKE SURE CONNECTION WILL BE SPP BIS #HF.SPP,CCTLWD(R5) ; BITB #DF.LSN,COPFLG(R5) ; Listen connection? BNE LSNCON ; yes ==> Listen connection $SGNLI $DSPID,#SG.OPN,R5 ; Signal DSP to send open packet BR OPRTN ; ==> Open return TRNSC: MOV CURPID(R5),R0 ; Get PID & OPCODE to signal caller CLR R1 ; Indicate success $SGNLI R0,R0,R1 ; Signal caller OPRTN: LSNCON: CLR R0 BISB CONNID(R5),R0 ; LSB R0 = CONNID BR PROPRT ; ==> PR Open return NOSLOT: NOSTOR: CLR R0 BIS #SC.NST*400,R0 ; No storage BR PROPRT CAROPN: CLR R0 BIS #SC.COP*400,R0 ; Connection already open PROPRT: COM CCTLMK(R5) ; NOW PUT MASK INTO BIC FORM ADD #MDBLEN,SP ; DEALLOCATE MDB FROM STACK $POP R5,R4,R3,R2,R1 RTT ; ; CALLED WITH: R1 = A(MATCH DESCRIPTOR) ; R0 = A(CCB) ; ; RETURN WITH: R2 = ZERO IF A MATCH EXISTS ; MTCHDS: $PUSH R0,R1 MOV #MDBLEN/2-2,R0 ; R0 = NO. OF WORDS FOR FGN AND LCL FIELDS 1$: CMP (R1)+,(R2)+ ; COMPARE MATCH DES. WITH CCB WORD BNE 2$ ; NOT EQUAL ==> RETURN $LOOP R0,1$ CLR R2 ; INDICATE A MATCH EXISTS 2$: $POP R1,R0 RTS PC .PAGE .SBTTL $PRSND - SEND PACKET ; ; CALLED WITH: LSB R0 = CONNID ; R1 = A(PKT) ; ; RETURNS WITH: MSB R0 = STATUS AS DEFINED BY $DFSCD ; LSB R0 = CONNID ; $PRSND: $PUSH R1,R2,R3,R5 BIC #377*400,R0 ; CLEAR HIGH BYTE $PUSH R0 ; SAVE CONNID JSR PC,CVCON ; RETURN R5 = A(CCB) ; RETURN R5 = 0 IF NX CONN TST R5 ; CONNECTION EXIST? BEQ SNXCON ; NO ==> NON-EXISTENT CONN MOV R1,R0 ; R0 = A(PKT) MOV PDADDR(R0),R2 ; R2 = A(HDR) BITB #DF.TRN,COPFLG(R5) ; TRANSPARENT CONNECTION? BEQ SNDSPP ; NO ==> SEND SPP PACKET BITB #DF.HSP,COPFLG(R5) ; IS HEADER SUPPLIED? BNE 1$ ; YES ==> HEADER ALREADY SET MOV CCTLWD(R5),R3 ; R3 = CONTROL WORD BITB #DF.ARQ,COPFLG(R5) ; ETE ACK REQUESTED? BEQ 2$ ; NO ==> SKIP BIS #HC.ARQ,R3 ; SET ARQ INC CSARQS(R5) ; BUMP "PKT SENT WITH ARQ" COUNT 2$: JSR PC,FRMHDR ; FORMAT HEADER 1$: JSR PC,SNDPKT ; SEND PKT $POP R0 ; R0 = 0,CONNID BR SDRTN SNDSPP: BIT #ST.OPA,CSTATE(R5) ; CONNECTION OPEN? BEQ SCONOP ; NO ==> CONNECTION NOT OPEN BIT #ST.CLS,CSTATE(R5) ; IS CONN CLOSED? BNE SCBCLD ; YES ==> CONNECTION BEING CLOSED BIT #ST.RCR,CSTATE(R5) ; REMOTE CLOSE BEEN RECEIVED? BNE SCONOP ; YES ==> CONN NOT OPEN CLR (R1) ; CLEAR LINK MOV R1,@CSNDQT(R5) ; LINK OLD TAIL TO NEW TAIL MOV R1,CSNDQT(R5) ; UPDATE TAIL PNTR $SGNLI $DSPID,#SG.SND,R5 ; SIGNAL DSP $POP R0 ; R0 = 0,CONNID BR SDRTN ; ==> SEND RETURN SCBCLD: $POP R0 ; R0 = 0, CONNID BIS #SC.CLD*400,R0 ; CONNECTION BEING CLOSED BR SDRTN SNXCON: $POP R0 ; R0 = 0, CONNID BIS #SC.NXC*400,R0 ; NON-EXISTENT CONNID BR SDRTN SCONOP: $POP R0 ; R0 = 0, CONNID BIS #SC.CNO*400,R0 ; CONNECTION NOT OPEN SDRTN: $POP R5,R3,R2,R1 RTT .PAGE .SBTTL $PRRCV - REQUEST RECPTION OF PACKET ; ; CALLED WITH: LSB R0 = CONNID ; MSB R0 = RECEIVE SIGNAL OP-CODE ; ; RETURNS WITH: MSB R0 = STATUS ; LSB R0 = CONNID ; $PRRCV: $PUSH R1,R2,R5 JSR PC,CVCON ; RETURN R5 = A(CCB) ; RETURN R5 = 0 IF NX CONNECTION TST R5 ; CONNECTION EXIST? BEQ RNXCON ; R5 = 0 ==> rcv non-existent conn SWAB R0 ; LSB R0 = RCV OP-CODE MOVB R0,CRCVOP(R5) ; SAVE RECEIVE OPCODE CLRB R0 ; CLEAR OUT OP-CODE CMP CRCVCT(R5),#RCVMAX ; IS THE RECEIVE COUNT = TO MAXIMUM BEQ RMXRCV ; YES ==> MAX. RCV REACHED BITB #DF.TRN,COPFLG(R5) ; TRANSPARENT? BEQ RCVSPP ; NO ==> RCV SPP INC CRCVCT(R5) ; BUMP RCV COUNT (I.E. RWE) BGT RCVRT2 ; NO PKTS ==> RCV RETURN MOV #CRCVQH,R2 ; R2 = OFFSET TO RCV QUEUE HEAD JSR PC,DEQPKT ; RETURN R0 = A(PKT) JSR PC,RTNACK ; RETURN ACK IF REQUESTED MOV R0,R1 ; R1 = A(PKT) $SGNLI CURPID(R5),CRCVOP(R5),R1; SGNAL CALLER WITH PKT BR RCVRT1 RCVSPP: BIT #ST.CLS,CSTATE(R5) ; CONNECTION BEING CLOSED? BNE RCVCLD ; YES ==> CONNECTION BEING CLOSED BIT #ST.RCR,CSTATE(R5) ; RECEIVE CLOSED? BNE RCVCLR ; YES ==> RCV BEEN CLOSED REMOTELY INC CRCVCT(R5) ; BUMP RECEIVE RWE JSR PC,HNDOFF ; HAND OFF ANY PKTS TO CALLER RCVRT1: CLR R0 BISB CONNID(R5),R0 ; LSB RO = CONNID BR RCVRTN RNXCON: BIC #177400,R0 ; CLEAR OP-CODE BIS #SC.NXC*400,R0 ; NON-EXISTENT CONNECTION BR RCVRTN RMXRCV: BIS #SC.MXR,R0 ; MAXIMUM RECEIVES EXCEEDED BR RCVRT2 RCVCLD: BIS #SC.CLD,R0 ; CONNECTION BEING CLOSED BR RCVRT2 RCVCLR: BIS #SC.CLR,R0 ; CONNECTION CLOSED REMOTELY RCVRT2: SWAB R0 ; MSB R0 = STATUS, LSB R0 = CONNID RCVRTN: $POP R5,R2,R1 RTT .PAGE .SBTTL $PRCLS - CLOSE CONNECTION ; ; CALLED WITH: LSB R0 = CONNID ; MSB R0 = CLOSE SIGNAL OP-CODE ; ; RETURNS WITH: MSB R0 = STATUS ; LSB R0 = CONNID ; $PRCLS: $PUSH R1,R5 JSR PC,CVCON ; RETURN R5 = A(CCB), R5 = 0 IF ; NON-EXISTENT CONNECTION TST R5 ; CONNECTION EXIST? BEQ CNXCON ; NO ==> NX CONNECTION SWAB R0 ; LSB R0 = OP-CODE MOVB R0,CUROPC(R5) ; SAVE OP-CODE CLRB R0 ; CLEAR OP-CODE BITB #DF.TRN,COPFLG(R5) ; TRANSPARENT? BEQ CLSSPP ; NO ==> CLOSE SPP MOV CURPID(R5),R0 ; R0 = PID, OP-CODE $SGNLI R0,R0,#0 ; SIGNAL CONNECTION CLOSED JSR PC,RCVCLN ; CLEAN RECEIVE QUEUE JSR PC,RLSCCB ; RELEASE CCB CLR R0 ; NO ERRORS BR CLSRT1 CLSSPP: BIT #ST.OPA,CSTATE(R5) ; CONNECTION OPENED? BEQ CONOPN ; NO => CONNECTION NOT OPEN BIT #ST.CLS,CSTATE(R5) ; CONNECTION BEING CLOSED? BNE CLSARD ; YES => BEEN CLOSED ALREADY BIS #ST.CLS,CSTATE(R5) ; INDICATE CONNECTION BEING CLOSED $SGNLI $DSPID,#SG.CLS,R5 ; SIGNAL DSP TO CLOSE CONNECTION CLR R0 BIS CONNID(R5),R0 ; LSB R0 = CONNID BR CLSRT2 CNXCON: BIC #177400,R0 ; CLEAR HIGH BYTE FOR STATUS BIS #SC.NXC*400,R0 ; NON-EXISTENT CONNECTION BR CLSRT2 CONOPN: BIS #SC.CNO,R0 ; CONNECTION NOT OPEN BR CLSRT1 CLSARD: BIS #SC.CLD,R0 ; CONNECTION ALREADY BEING CLOSED CLSRT1: SWAB R0 ; MSB R0 = STATUS, LSB R0 = CONNID CLSRT2: $POP R5,R1 RTT .PAGE $DPMBT: .DSABL ISD .END