;Alto->8086 small-c compiler rev 2.0 C_CODE SEGMENT $INCLUDE(8086LIB.D) $INCLUDE(rpcpktio.DEC) ASSUME CS:C_CODE, DS:C_DATA ; #include ; extern int /*BOOL*/ ReplyToRFA(); ; extern SignalInitialize(); ; extern int CallFailed; ; extern SendPup(); ; extern WaitUntilSent(); ; extern struct PBI *GetPBI(); ; extern int GetPupHost(); /* returns machine, but can't declare that */ ; extern InitPupLevel1(); ; extern OpenLevel1Socket(/*lclPort, PortProc, queue*/); ; extern RequestRoute(/*net*/); ; extern InitCalendar(/*retries*/); ; extern int Min(); ; extern int/*BOOL*/ MultEq(); ; extern int/*BOOL*/ DoubleEq(); ; extern ReleasePBI(); ; extern int *Dequeue(); ; extern Enqueue(); ; extern InitQueue(); ; extern SetTmr(); ; extern int /*BOOL*/ TmrExp(); ; extern Block(); ; extern CurrentContext(); ; extern int DoubleComp(); ; extern int DoubleInc(); ; extern Move2(); ; extern StartNProcess(); ; extern int *CallersFrame(); ; extern MoveBlock(); ; extern Zero(); ; union Machine myHost; /* net,,host */ ; struct Queue *myCtxQ; ; int *mySoc; ; static struct CallCount callSequence; /* pointer to CallCount generator */ ; static int sent; /* statistics */ ; static int recvd; ; static int retransmitted; ; static int ReceivePktTooLong; /* SIGNAL */ ; static int listenerRunning; /* set false to abort listener */ ; static int signalTimeout; /* debugging: false to avoid transmission timeouts */ ; static int maxTransmissions /* Normally a large constant; reduced during broadcasts. */ ; struct Queue idlerQ; ; static int idlers; /* CARDINAL; -- number idle servers */ ; static int wanting[maxPSBp1]; /* ARRAY PSB.PsbIndex OF BOOLEAN */ ; static struct PBI *waiterPkts[maxPSBp1]; /* ARRAY PSB.PsbIndex OF BufferDefs.PupBuffer */ ; static struct RPCCtx *contexts[maxPSBp1]; /* contexts corresp. to wanting, for debugging. */ ; int broadcastRetransmissions; ; static int minRetransmitPulses; /* Must be set up in initialization code */ ; static int minPingPulses; /* to above values in some reasonable tick */ ; static int maxPingPulses; /* units. */ ; int rpct; ; static Cl(sig, code, sl) _Cl: ; int sig, code, *sl; PUSH BP MOV BP,SP PUSH CX PUSH BX ; { ; CleanUp(sl); ; BX _ _sl POP BX PUSH BX CALL _CleanUp ; }; MOV SP,BP POP BP RET; ; int /* newLength: */ ; PktExchange(inPkt, length, maxLength, state) _PktExchange: ; struct PBI *inPkt; ; int length, maxLength, state; PUSH BP MOV BP,SP PUSH CX PUSH BX ; { ; struct PBI *reply; ; struct Seal1 s1, *sl; ; struct Queue myQ; ; int myPSB, acked, pingPulses; ; struct RPCCtx *CtxRunning; ; struct Header *header, *recvdHeader; ; struct PktID thisPktID; ; int newLength, pktLength; ; int transmissions, retransmitPulses, pLen; ; int /* BOOL */ isConv; ; struct PBI *rp; ADD SP,0FFD0X ; sl = &s1; s1.data[0] = (int) &reply; reply=0; ;&_s1 LEA BX,[BP-12] ; _sl _ BX MOV [BP-14],BX ;&_reply LEA BX,[BP-6] ; _s1+4 _ BX MOV [BP-8],BX MOV WORD PTR [BP-6],0 ; DISABLE(sl); ; BX _ _sl MOV BX,[BP-14] CALL _DISABLE ; CtxRunning = CurrentContext(); CALL _CurrentContext ; _CtxRunning _ BX MOV [BP-26],BX ; myPSB = CtxRunning->user.myPSB; ; BX _ _CtxRunning MOV BX,[BP-26] MOV CX,[BX+26] ; _myPSB _ CX MOV [BP-20],CX ; header = inPkt->pup; ; BX _ _inPkt MOV BX,[BP+6] MOV CX,[BX+6] ; _header _ CX MOV [BP-28],CX ; myQ.head = 0; MOV WORD PTR [BP-18],0 ; inPkt->queue = &myQ; ; BX _ _inPkt MOV BX,[BP+6] ;&_myQ LEA CX,[BP-18] MOV [BX+2],CX ; InitQueue(&myQ); ;&_myQ LEA BX,[BP-18] CALL _InitQueue ; Enqueue(&myQ, inPkt); ; BX _ _inPkt MOV BX,[BP+6] ;&_myQ LEA CX,[BP-18] CALL _Enqueue ; pingPulses = minPingPulses; MOV BX,_minPingPulses ; _pingPulses _ BX MOV [BP-24],BX ; header->srceHost.w = myHost.w; ; BX _ _header MOV BX,[BP-28] MOV CX,WORD PTR _myHost MOV [BX+14],CX ; header->srceSoc.LS = rpcSocket; ; BX _ _header MOV BX,[BP-28] MOV BYTE PTR [BX+19],01EX ; header->srcePSB = myPSB; ; BX _ _header MOV BX,[BP-28] ; CX _ _myPSB MOV CX,[BP-20] MOV [BX+6],CX ; maxTransmissions = defaultMaxTransmissions; MOV _maxTransmissions,5 ; if (header->destHost.b.host == 0) { ; BX _ _header MOV BX,[BP-28] MOV AL,[BX+9] OR AL,AL JNZ X1 ; maxTransmissions = broadcastRetransmissions; MOV BX,_broadcastRetransmissions MOV _maxTransmissions,BX ; header->destSoc.LS = rpcBcstSocket; ; BX _ _header MOV BX,[BP-28] MOV BYTE PTR [BX+13],025X ; }; X1: ; if (header->pktID.pktSeq == 0) { ; BX _ _header MOV BX,[BP-28] MOV CX,[BX+30] OR CX,CX JNZ X2 ; switch (state) { ; BX _ _state MOV BX,[BP-4] JR X3 ; case calling: header->type.fields = typeCall; break; X5: ; BX _ _header MOV BX,[BP-28] MOV BYTE PTR [BX+3],060X JR X4 ; case authReq: header->type.fields = typeRFA; break; X6: ; BX _ _header MOV BX,[BP-28] MOV BYTE PTR [BX+3],064X JR X4 ; default: SIGNAL(ERROR, 0); X7: XOR BX,BX MOV CX,2 CALL _SIGNAL ; }; /* endCall */ JR X4 X3: MOV AL,BH OR AL,AL JNZ X7 MOV AL,BL CMP AL,2 JZ X5 CMP AL,4 JZ X6 JR X7 X4: ; NewCallNumber(&header->pktID.callCt); ; BX _ _header MOV BX,[BP-28] ADD BX,01AX CALL _NewCallNumber ; header->pktID.pktSeq=swapped1; ; BX _ _header MOV BX,[BP-28] MOV WORD PTR [BX+30],0100X ; }; ; else { JR X8 X2: ; switch (state) { ; BX _ _state MOV BX,[BP-4] JR X9 ; case endCall: header->type.fields = typeData; break; X11: ; BX _ _header MOV BX,[BP-28] MOV BYTE PTR [BX+3],061X JR X10 ; case calling: /* Subsequent call packets -- we don't do it. */ X12: ; default: SIGNAL(ERROR, 0); X13: XOR BX,BX MOV CX,2 CALL _SIGNAL ; }; /* authReq */ JR X10 X9: MOV AL,BH OR AL,AL JNZ X13 MOV AL,BL CMP AL,3 JZ X11 CMP AL,2 JZ X12 JR X13 X10: ; header->pktID.pktSeq += swapped1; ; BX _ _header MOV BX,[BP-28] ADD WORD PTR [BX+30],0100X ; }; X8: ; acked=false; MOV WORD PTR [BP-22],0 ; MoveBlock(&thisPktID, &header->pktID, lenPktID); ;&_thisPktID LEA BX,[BP-38] PUSH BX ; BX _ _header MOV BX,[BP-28] ADD BX,018X PUSH BX MOV BX,4 POP CX CALL _MoveBlock POP DX ; ENABLE(UNWIND, &Cl, sl); MOV BX,1 PUSH BX ; BX _ _sl MOV BX,[BP-14] MOV CX,OFFSET _Cl CALL _ENABLE POP DX ; for (;;) { /* loop for Pings */ X14: ; transmissions = 0; MOV WORD PTR [BP-44],0 ; retransmitPulses=minRetransmitPulses; MOV BX,_minRetransmitPulses ; _retransmitPulses _ BX MOV [BP-46],BX ; if (inPkt->convHandle != unencrypted) ; BX _ _inPkt MOV BX,[BP+6] MOV CX,[BX+4] OR CX,CX JZ X16 ; pLen = EncryptPkt(inPkt, length); ; BX _ _length MOV BX,[BP+4] ; CX _ _inPkt MOV CX,[BP+6] CALL _EncryptPkt ; _pLen _ BX MOV [BP-48],BX ; else pLen = (length + pktLengthOverhead); JR X17 X16: ; BX _ _length MOV BX,[BP+4] ADD BX,015X ; _pLen _ BX MOV [BP-48],BX X17: ; header->length = swab(pLen<< 1); ; BX _ _pLen MOV BX,[BP-48] SAL BX CALL _swab MOV CX,BX ; BX _ _header MOV BX,[BP-28] MOV [BX],CX ; for (;;) { /* loop for ReTransmissions */ X18: ; SetWanting(myPSB); ; BX _ _myPSB MOV BX,[BP-20] CALL _SetWanting ; WaitUntilSent(inPkt); /* make sure transmission's complete??? */ ; BX _ _inPkt MOV BX,[BP+6] CALL _WaitUntilSent ; SendPup(inPkt); ; BX _ _inPkt MOV BX,[BP+6] CALL _SendPup ; sent += 1; INC _sent ; for (;;) { /* loop for Receiving each incoming packet (including garbage) */ X20: ; SetWanting(myPSB); ; BX _ _myPSB MOV BX,[BP-20] CALL _SetWanting ; reply = MyReceive(myPSB, ((acked)? pingPulses: retransmitPulses)); ; BX _ _acked MOV BX,[BP-22] OR BX,BX JZ X22 ; BX _ _pingPulses MOV BX,[BP-24] JR X23 X22: ; BX _ _retransmitPulses MOV BX,[BP-46] X23: ; CX _ _myPSB MOV CX,[BP-20] CALL _MyReceive ; _reply _ BX MOV [BP-6],BX ; if (reply == 0) ; BX _ _reply MOV BX,[BP-6] OR BX,BX JNZ X24 ; if (acked) goto Ping; ; BX _ _acked MOV BX,[BP-22] OR BX,BX JZ X25 JMP _Ping ; else { header->type.fields |= ackField; goto Retransmit; }; X25: ; BX _ _header MOV BX,[BP-28] OR BYTE PTR [BX+3],8 JMP _Retransmit X24: ; recvdHeader = reply->pup; ; BX _ _reply MOV BX,[BP-6] MOV CX,[BX+6] ; _recvdHeader _ CX MOV [BP-30],CX ; if ((recvdHeader->type.fields&classField) == rfa) { ; BX _ _recvdHeader MOV BX,[BP-30] MOV AL,[BX+3] AND AL,7 CMP AL,4 JNZ X26 ; rp=reply; ; BX _ _reply MOV BX,[BP-6] ; _rp _ BX POP DX PUSH BX ; reply=0; MOV WORD PTR [BP-6],0 ; if (ReplyToRFA(rp, header /*encrypted*/, ; &thisPktID /*clear*/, inPkt->convHandle)) acked=acked; ; BX _ _rp POP BX PUSH BX PUSH BX ; BX _ _header MOV BX,[BP-28] PUSH BX ; BX _ _inPkt MOV BX,[BP+6] MOV CX,[BX+4] MOV BX,CX ;&_thisPktID LEA CX,[BP-38] CALL _ReplyToRFA ADD SP,4 OR BX,BX JZ X27 ; BX _ _acked MOV BX,[BP-22] ; _acked _ BX MOV [BP-22],BX X27: ; continue; }; JR X20 X26: ; isConv = swab(recvdHeader->srceHost.w ^ header->destHost.w); /* comparison results */ ; BX _ _recvdHeader MOV BX,[BP-30] MOV CX,[BX+14] ; BX _ _header MOV BX,[BP-28] MOV AX,[BX+8] XOR CX,AX MOV BX,CX CALL _swab ; _isConv _ BX MOV [BP-50],BX ; isConv = (isConv==0 || isConv==recvdHeader->srceHost.b.host); /* equal or near-equal */ ; BX _ _isConv MOV BX,[BP-50] OR BX,BX JZ X29 ; BX _ _recvdHeader MOV BX,[BP-30] MOV AL,[BX+15] XOR AH,AH ; BX _ _isConv MOV BX,[BP-50] CMP BX,AX X29: X28: JNZ X30 MOV BX,1 JR X31 X30: XOR BX,BX X31: ; _isConv _ BX MOV [BP-50],BX ; isConv = (DoubleEq(&recvdHeader->conv,&header->conv) && isConv); /*our conv*/ ; BX _ _recvdHeader MOV BX,[BP-30] ADD BX,014X ; CX _ _header MOV CX,[BP-28] ADD CX,014X XCHG BX,CX CALL _DoubleEq OR BX,BX JZ X32 ; BX _ _isConv MOV BX,[BP-50] OR BX,BX X32: JZ X33 MOV BX,1 JR X34 X33: XOR BX,BX X34: ; _isConv _ BX MOV [BP-50],BX ; if ((inPkt->convHandle != unencrypted) && isConv) { ; BX _ _inPkt MOV BX,[BP+6] MOV CX,[BX+4] OR CX,CX JZ X36 ; BX _ _isConv MOV BX,[BP-50] OR BX,BX X36: JZ X35 ; DecryptPkt(recvdHeader, inPkt->convHandle, &newLength); ; BX _ _recvdHeader MOV BX,[BP-30] PUSH BX ; BX _ _inPkt MOV BX,[BP+6] MOV CX,[BX+4] ;&_newLength LEA BX,[BP-40] CALL _DecryptPkt POP DX ; pktLength = newLength + pktLengthOverhead; } ; BX _ _newLength MOV BX,[BP-40] ADD BX,015X ; _pktLength _ BX MOV [BP-42],BX ; else { JR X37 X35: ; pktLength = (swab(recvdHeader->length)) >> 1; ; DI _ _recvdHeader MOV DI,[BP-30] MOV BX,[DI] CALL _swab SHR BX ; _pktLength _ BX MOV [BP-42],BX ; newLength = pktLength - pktLengthOverhead; }; ; BX _ _pktLength MOV BX,[BP-42] ADD BX,0FFEBX ; _newLength _ BX MOV [BP-40],BX X37: ; if (isConv && (recvdHeader->pktID.activity == thisPktID.activity)) ; BX _ _isConv MOV BX,[BP-50] OR BX,BX JZ X39 ; BX _ _recvdHeader MOV BX,[BP-30] MOV CX,[BX+24] ; BX _ _thisPktID MOV BX,[BP-38] CMP CX,BX JNZ X39 MOV AL,1 JR X40 X39: XOR AL,AL X40: OR AL,AL JZ X38 ; if (DoubleEq(&recvdHeader->pktID.callCt, &thisPktID.callCt)) ; BX _ _recvdHeader MOV BX,[BP-30] ADD BX,01AX PUSH BX ;&_thisPktID LEA BX,[BP-36] POP CX CALL _DoubleEq OR BX,BX JZ X41 ; if (recvdHeader->pktID.pktSeq == swapped1+thisPktID.pktSeq) { ; BX _ _recvdHeader MOV BX,[BP-30] MOV CX,[BX+30] ; BX _ _thisPktID+6 MOV BX,[BP-32] ADD BX,0100X CMP CX,BX JNZ X42 ; if (state == endCall) /* he's not allowed to generate that pktSeq! */ ; BX _ _state MOV BX,[BP-4] CMP BX,3 JNZ X43 ; SIGNAL(CallFailed, runtimeProtocol); MOV BX,0FX MOV CX,_CallFailed CALL _SIGNAL X43: ; switch (recvdHeader->type.fields&classField) { ; BX _ _recvdHeader MOV BX,[BP-30] MOV AL,[BX+3] AND AL,7 JR X44 ; case xtraData: break; X46: JR X45 ; case ack: { X47: ; acked = true; MOV WORD PTR [BP-22],0FFFFX ; CleanUp(sl); ; BX _ _sl MOV BX,[BP-14] CALL _CleanUp ; continue; }; JMP X20 ; default: SIGNAL(CallFailed, runtimeProtocol); }; /* call, rfa */ X48: MOV BX,0FX MOV CX,_CallFailed CALL _SIGNAL JR X45 X44: CMP AL,1 JZ X46 CMP AL,2 JZ X47 JR X48 X45: ; goto Done; }; JMP _Done ; else if (recvdHeader->pktID.pktSeq == thisPktID.pktSeq) { X42: ; BX _ _recvdHeader MOV BX,[BP-30] MOV CX,[BX+30] ; BX _ _thisPktID+6 MOV BX,[BP-32] CMP CX,BX JR $+5 X38: JMP X50 JNZ X49 ; switch (recvdHeader->type.fields&classField) { ; BX _ _recvdHeader MOV BX,[BP-30] MOV AL,[BX+3] AND AL,7 JR X51 ; case ack: { /* acknowledgement of our packet -- */ X53: ; if ((header->type.fields&classField) == call) header->destPSB = recvdHeader->srcePSB; ; BX _ _header MOV BX,[BP-28] JR $+5 X41: JMP X55 MOV AL,[BX+3] AND AL,7 OR AL,AL JNZ X54 ; BX _ _header MOV BX,[BP-28] ; CX _ _recvdHeader MOV CX,[BP-30] MOV DI,CX MOV CX,[DI+6] MOV [BX+4],CX X54: ; acked = true; MOV WORD PTR [BP-22],0FFFFX ; if (state == endCall) { CleanUp(sl); goto Done; }; ; BX _ _state MOV BX,[BP-4] CMP BX,3 JNZ X56 ; BX _ _sl MOV BX,[BP-14] CALL _CleanUp JMP _Done ; else /* state = calling or authReq -- */ X56: ; CleanUp(sl); ; BX _ _sl MOV BX,[BP-14] CALL _CleanUp ; break; }; JR X52 ; case xtraData: case call: /* retransmission of his packet; X57: X58: ; default: SIGNAL(CallFailed, runtimeProtocol); }; X59: MOV BX,0FX MOV CX,_CallFailed CALL _SIGNAL JR X52 X51: CMP AL,2 JZ X53 CMP AL,1 JZ X57 CMP AL,0 JZ X58 JR X59 X52: ; }; ; else if (recvdHeader->pktID.pktSeq < thisPktID.pktSeq) CleanUp(sl); /* no need to ack it */ JR X60 X49: ; BX _ _recvdHeader MOV BX,[BP-30] MOV CX,[BX+30] ; BX _ _thisPktID+6 MOV BX,[BP-32] CMP CX,BX JGE X61 ; BX _ _sl MOV BX,[BP-14] CALL _CleanUp ; else SIGNAL(CallFailed, runtimeProtocol); JR X62 X61: MOV BX,0FX MOV CX,_CallFailed CALL _SIGNAL X62: X60: ; else JR X63 X55: ; if (((DoubleComp(&recvdHeader->pktID.callCt, &thisPktID.callCt)+1) > 1) && ; (state == endCall)) { ; BX _ _recvdHeader MOV BX,[BP-30] ADD BX,01AX PUSH BX ;&_thisPktID LEA BX,[BP-36] POP CX CALL _DoubleComp INC BX CMP BX,1 JLE X65 ; BX _ _state MOV BX,[BP-4] CMP BX,3 JNZ X65 MOV AL,1 JR X66 X65: XOR AL,AL X66: OR AL,AL JZ X64 ; if ((recvdHeader->type.fields&classField) != call) SIGNAL(CallFailed, runtimeProtocol); ; BX _ _recvdHeader MOV BX,[BP-30] MOV AL,[BX+3] AND AL,7 OR AL,AL JZ X67 MOV BX,0FX MOV CX,_CallFailed CALL _SIGNAL X67: ; goto Done; }; JMP _Done ; else { /* wrong call; let someone else do it -- */ X64: ; recvdHeader->destPSB = nullPSB; EnqueueAgain(reply); reply=0; }; ; BX _ _recvdHeader MOV BX,[BP-30] MOV WORD PTR [BX+4],0 ; BX _ _reply MOV BX,[BP-6] CALL _EnqueueAgain MOV WORD PTR [BP-6],0 X63: ; else { recvdHeader->destPSB = nullPSB; EnqueueAgain(reply); reply=0; }; JR X68 X50: ; BX _ _recvdHeader MOV BX,[BP-30] MOV WORD PTR [BX+4],0 ; BX _ _reply MOV BX,[BP-6] CALL _EnqueueAgain MOV WORD PTR [BP-6],0 X68: ; }; /* endloop for each incoming packet */ JMP X20 X21: _Retransmit: ; Retransmit: ; transmissions += 1; INC WORD PTR [BP-44] ; if ((transmissions == maxTransmissions) || state == authReq) { MOV BX,_maxTransmissions ; CX _ _transmissions MOV CX,[BP-44] CMP CX,BX JZ X71 ; BX _ _state MOV BX,[BP-4] CMP BX,4 X71: X70: JNZ X69 ; if (signalTimeout) SIGNAL(CallFailed, timeout); MOV BX,_signalTimeout OR BX,BX JZ X72 MOV BX,0DX MOV CX,_CallFailed CALL _SIGNAL X72: ; transmissions = 0; retransmitPulses = minRetransmitPulses*maxTransmissions; MOV WORD PTR [BP-44],0 MOV AX,_minRetransmitPulses MOV BX,_maxTransmissions IMUL AX,BX ; _retransmitPulses _ AX MOV [BP-46],AX ; }; X69: ; retransmitted += 1; INC _retransmitted ; retransmitPulses += minRetransmitPulses; MOV BX,_minRetransmitPulses ADD [BP-46],BX ; Block(); CALL _Block ; continue; JMP X18 ; }; /* end loop for retransmissions */ X19: _Ping: ; Ping: ; header->type.fields = typePing; ; BX _ _header MOV BX,[BP-28] MOV BYTE PTR [BX+3],06AX ; length=0; MOV WORD PTR [BP+4],0 ; MoveBlock(&header->pktID, &thisPktID, lenPktID); ; BX _ _header MOV BX,[BP-28] ADD BX,018X PUSH BX MOV BX,4 ;&_thisPktID LEA CX,[BP-38] CALL _MoveBlock POP DX ; acked=false; MOV WORD PTR [BP-22],0 ; pingPulses = pingPulses*2; ; BX _ _pingPulses MOV BX,[BP-24] SAL BX ; _pingPulses _ BX MOV [BP-24],BX ; if ( (pingPulses<0) || (pingPulses>maxPingPulses) ) pingPulses = maxPingPulses; ; BX _ _pingPulses MOV BX,[BP-24] CMP BX,0 JL X75 MOV BX,_maxPingPulses ; CX _ _pingPulses MOV CX,[BP-24] CMP CX,BX JLE X74 X75: MOV AL,1 JR X76 X74: XOR AL,AL X76: OR AL,AL JZ X73 MOV BX,_maxPingPulses ; _pingPulses _ BX MOV [BP-24],BX X73: ; Block(); CALL _Block ; }; /* end loop for pings -- */ JMP X14 X15: _Done: ; Done: { ; ClearWanting(myPSB); ; BX _ _myPSB MOV BX,[BP-20] CALL _ClearWanting ; if (reply == 0) { ; BX _ _reply MOV BX,[BP-6] OR BX,BX JNZ X77 ; MoveBlock(&header->pktID, &thisPktID, lenPktID); ; BX _ _header MOV BX,[BP-28] ADD BX,018X PUSH BX MOV BX,4 ;&_thisPktID LEA CX,[BP-38] CALL _MoveBlock POP DX ; return -1; MOV BX,0FFFFX MOV SP,BP POP BP RET; ; }; X77: ; if ((recvdHeader->callSpec.outcome == signal) || ; (newLength > maxLength)) SIGNAL(CallFailed, runtimeProtocol); ; BX _ _recvdHeader MOV BX,[BP-30] MOV CX,[BX+32] MOV BX,CX CMP BX,2 JZ X80 ; BX _ _maxLength MOV BX,[BP-2] ; CX _ _newLength MOV CX,[BP-40] CMP CX,BX JLE X79 X80: MOV AL,1 JR X81 X79: XOR AL,AL X81: OR AL,AL JZ X78 MOV BX,0FX MOV CX,_CallFailed CALL _SIGNAL X78: ; MoveBlock(header, recvdHeader, pktLength); ; BX _ _header MOV BX,[BP-28] PUSH BX ; BX _ _pktLength MOV BX,[BP-42] ; CX _ _recvdHeader MOV CX,[BP-30] CALL _MoveBlock POP DX ; CleanUp(sl); ; BX _ _sl MOV BX,[BP-14] CALL _CleanUp ; Block(); CALL _Block ; return newLength; ; BX _ _newLength MOV BX,[BP-40] MOV SP,BP POP BP RET; ; }; ; SIGNAL(ERROR, 0); XOR BX,BX MOV CX,2 CALL _SIGNAL ; }; MOV SP,BP POP BP RET; ; static CleanUp(sl) _CleanUp: ; struct Seal1 *sl; PUSH BP MOV BP,SP PUSH BX ; { /* UNWIND proc */ ; int myPSB, *lvReply; ; struct RPCCtx *CtxRunning; ADD SP,0FFFAX ; CtxRunning = CurrentContext(); CALL _CurrentContext ; _CtxRunning _ BX POP DX PUSH BX ; myPSB = CtxRunning->user.myPSB; ; BX _ _CtxRunning POP BX PUSH BX MOV CX,[BX+26] ; _myPSB _ CX MOV [BP-4],CX ; ClearWanting(myPSB); ; BX _ _myPSB MOV BX,[BP-4] CALL _ClearWanting ; lvReply = (int *) sl->data[0]; ; BX _ _sl MOV BX,[BP-2] ADD BX,4 MOV CX,[BX] ; _lvReply _ CX MOV [BP-6],CX ; if (*lvReply != 0) ReleasePBI(*lvReply); ; DI _ _lvReply MOV DI,[BP-6] MOV BX,[DI] OR BX,BX JZ X82 ; DI _ _lvReply MOV DI,[BP-6] MOV BX,[DI] CALL _ReleasePBI X82: ; *lvReply=0; ; BX _ _lvReply MOV BX,[BP-6] MOV WORD PTR [BX],0 ; }; MOV SP,BP POP BP RET; ; static int NewCallNumber(lvResult) _NewCallNumber: ; struct CallCount *lvResult; PUSH BP MOV BP,SP PUSH BX ; { ; DoubleInc(&callSequence, 1); MOV BX,1 LEA CX,_callSequence CALL _DoubleInc ; Move2(lvResult, &callSequence); LEA BX,_callSequence ; CX _ _lvResult POP CX PUSH CX CALL _Move2 ; }; MOV SP,BP POP BP RET; ; static SetWanting(myPSB) _SetWanting: ; int myPSB; PUSH BP MOV BP,SP PUSH BX ; { ; wanting[myPSB]=true; ; BX _ _myPSB POP BX PUSH BX LEA CX,_wanting SAL BX ADD BX,CX MOV WORD PTR [BX],0FFFFX ; }; MOV SP,BP POP BP RET; ; static ClearWanting(myPSB) _ClearWanting: ; int myPSB; PUSH BP MOV BP,SP PUSH BX ; { ; wanting[myPSB]=false; ; BX _ _myPSB POP BX PUSH BX LEA CX,_wanting SAL BX ADD BX,CX MOV WORD PTR [BX],0 ; if (waiterPkts[myPSB]) { ; BX _ _myPSB POP BX PUSH BX LEA CX,_waiterPkts SAL BX ADD BX,CX MOV CX,[BX] OR CX,CX JZ X83 ; ReleasePBI(waiterPkts[myPSB]); ; BX _ _myPSB POP BX PUSH BX LEA CX,_waiterPkts SAL BX ADD BX,CX MOV CX,[BX] MOV BX,CX CALL _ReleasePBI ; waiterPkts[myPSB] = 0; ; BX _ _myPSB POP BX PUSH BX LEA CX,_waiterPkts SAL BX ADD BX,CX MOV WORD PTR [BX],0 ; }; X83: ; }; MOV SP,BP POP BP RET; ; static struct PBI *MyReceive(myPSB, waitTime) _MyReceive: ; int myPSB, waitTime; PUSH BP MOV BP,SP PUSH CX PUSH BX ; { ; int timer; ; struct PBI *recvd; ADD SP,0FFFCX ; timer=0; MOV WORD PTR [BP-6],0 ; SetTmr(waitTime, &timer); /* sentTime is implicit, if SetTimer called quickly enuf. */ ;&_timer LEA BX,[BP-6] ; CX _ _waitTime MOV CX,[BP-4] CALL _SetTmr ; for (;;) { X84: ; recvd = waiterPkts[myPSB]; ; BX _ _myPSB MOV BX,[BP-2] LEA CX,_waiterPkts SAL BX ADD BX,CX MOV CX,[BX] ; _recvd _ CX POP DX PUSH CX ; if (recvd) { ; BX _ _recvd POP BX PUSH BX OR BX,BX JZ X86 ; waiterPkts[myPSB] = 0; ; BX _ _myPSB MOV BX,[BP-2] LEA CX,_waiterPkts SAL BX ADD BX,CX MOV WORD PTR [BX],0 ; return recvd; ; BX _ _recvd POP BX PUSH BX MOV SP,BP POP BP RET; ; }; X86: ; if (TmrExp(&timer)) return 0; ;&_timer LEA BX,[BP-6] CALL _TmrExp OR BX,BX JZ X87 XOR BX,BX MOV SP,BP POP BP RET; X87: ; Block(); CALL _Block ; }; JR X84 X85: ; }; MOV SP,BP POP BP RET; ; IdleReceive(pkt, maxLength) _IdleReceive: ; struct PBI *pkt; ; int maxLength; PUSH BP MOV BP,SP PUSH CX PUSH BX ; { ; struct PBI *b; ; struct Header *recvdHeader; ; int pktLength; ADD SP,0FFFAX ; idlers += 1; INC _idlers ; while (idlerQ.head == 0) Block(); /* WAIT idlerCond */ X88: MOV BX,WORD PTR _idlerQ OR BX,BX JNZ X89 CALL _Block JR X88 X89: ; b = (struct PBI *) Dequeue(&idlerQ); LEA BX,_idlerQ CALL _Dequeue ; _b _ BX MOV [BP-6],BX ; recvdHeader = b->pup; ; BX _ _b MOV BX,[BP-6] MOV CX,[BX+6] ; _recvdHeader _ CX MOV [BP-8],CX ; pktLength = (swab(recvdHeader->length)) >> 1; ; DI _ _recvdHeader MOV DI,[BP-8] MOV BX,[DI] CALL _swab SHR BX ; _pktLength _ BX POP DX PUSH BX ; if (pktLength <= maxLength) MoveBlock(pkt->pup, recvdHeader, pktLength); ; BX _ _maxLength MOV BX,[BP-4] ; CX _ _pktLength POP CX PUSH CX CMP CX,BX JG X90 ; BX _ _pkt MOV BX,[BP-2] MOV CX,[BX+6] PUSH CX ; BX _ _pktLength MOV BX,[BP-10] ; CX _ _recvdHeader MOV CX,[BP-8] CALL _MoveBlock POP DX X90: ; if (rpct) PutChar('i'); MOV BX,_rpct OR BX,BX JZ X91 MOV BX,069X CALL _PutChar X91: ; ReleasePBI(b); ; BX _ _b MOV BX,[BP-6] CALL _ReleasePBI ; if (pktLength > maxLength) SIGNAL(ReceivePktTooLong, 0); ; BX _ _maxLength MOV BX,[BP-4] ; CX _ _pktLength POP CX PUSH CX CMP CX,BX JLE X92 XOR BX,BX MOV CX,_ReceivePktTooLong CALL _SIGNAL X92: ; }; MOV SP,BP POP BP RET; ; int /*BOOL*/ ; EnqueueRecvd(b) _EnqueueRecvd: ; struct PBI *b; PUSH BP MOV BP,SP PUSH BX ; { /* the main scheduler. */ ; struct Header *header; ; int destPSB; ADD SP,0FFFCX ; header = b->pup; ; BX _ _b MOV BX,[BP-2] MOV CX,[BX+6] ; _header _ CX MOV [BP-4],CX ; if (header->destHost.w != myHost.w) return false; ; BX _ _header MOV BX,[BP-4] MOV CX,[BX+8] MOV BX,WORD PTR _myHost CMP CX,BX JZ X93 XOR BX,BX MOV SP,BP POP BP RET; X93: ; if ((header->type.fields&subtypeField) != rpc) return false; ; BX _ _header MOV BX,[BP-4] MOV AL,[BX+3] AND AL,0E0X CMP AL,060X JZ X94 XOR BX,BX MOV SP,BP POP BP RET; X94: ; if (((header->type.fields&classField)==call) && ; ((header->type.fields&ackField)!=0)) b=b; ; BX _ _header MOV BX,[BP-4] MOV AL,[BX+3] AND AL,7 OR AL,AL JNZ X96 ; BX _ _header MOV BX,[BP-4] MOV AL,[BX+3] AND AL,8 OR AL,AL JZ X96 MOV AL,1 JR X97 X96: XOR AL,AL X97: OR AL,AL JZ X95 ; BX _ _b MOV BX,[BP-2] ; _b _ BX MOV [BP-2],BX X95: ; destPSB = header->destPSB; ; BX _ _header MOV BX,[BP-4] MOV CX,[BX+4] ; _destPSB _ CX POP DX PUSH CX ; recvd += 1; INC _recvd ; if ((destPSB <= 0) || (destPSB > maxPSB) || (wanting[destPSB] == false)) { ; BX _ _destPSB POP BX PUSH BX CMP BX,0 JLE X100 ; BX _ _destPSB POP BX PUSH BX CMP BX,0FX JG X102 ; BX _ _destPSB POP BX PUSH BX LEA CX,_wanting SAL BX ADD BX,CX MOV CX,[BX] OR CX,CX JNZ X101 X102: MOV AL,1 JR X103 X101: XOR AL,AL X103: OR AL,AL JZ X99 X100: MOV AL,1 JR X104 X99: XOR AL,AL X104: OR AL,AL JZ X98 ; if (idlers == 0) return false; /* server too busy, throw away */ MOV BX,_idlers OR BX,BX JNZ X105 XOR BX,BX MOV SP,BP POP BP RET; X105: ; Enqueue(&idlerQ, b); ; BX _ _b MOV BX,[BP-2] LEA CX,_idlerQ CALL _Enqueue ; if (rpct) PutChar('e'); MOV BX,_rpct OR BX,BX JZ X106 MOV BX,065X CALL _PutChar X106: ; idlers -= 1; DEC _idlers ; }; ; else { /* someone wants this packet: give them it -- */ JR X107 X98: ; if (waiterPkts[destPSB]) return false; /* two packets to same process! */ ; BX _ _destPSB POP BX PUSH BX LEA CX,_waiterPkts SAL BX ADD BX,CX MOV CX,[BX] OR CX,CX JZ X108 XOR BX,BX MOV SP,BP POP BP RET; X108: ; waiterPkts[destPSB]=b; ; BX _ _destPSB POP BX PUSH BX LEA CX,_waiterPkts SAL BX ADD BX,CX ; CX _ _b MOV CX,[BP-2] MOV [BX],CX ; if (rpct) PutChar('w'); MOV BX,_rpct OR BX,BX JZ X109 MOV BX,077X CALL _PutChar X109: ; }; X107: ; return true; MOV BX,0FFFFX MOV SP,BP POP BP RET; ; }; ; EnqueueAgain(b) _EnqueueAgain: ; struct PBI *b; PUSH BP MOV BP,SP PUSH BX ; { ; if (EnqueueRecvd(b) == false) { ; BX _ _b POP BX PUSH BX CALL _EnqueueRecvd OR BX,BX JNZ X110 ; ReleasePBI(b); ; BX _ _b POP BX PUSH BX CALL _ReleasePBI ; if (rpct) PutChar('d'); MOV BX,_rpct OR BX,BX JZ X111 MOV BX,064X CALL _PutChar X111: ; }; X110: ; }; MOV SP,BP POP BP RET; ; EnqueueBcst(b) _EnqueueBcst: ; struct PBI *b; PUSH BP MOV BP,SP PUSH BX ; { /* Incoming broadcast dispatcher. */ ; struct Header *header; ; int destPSB; ADD SP,0FFFCX ; header = b->pup; ; BX _ _b MOV BX,[BP-2] MOV CX,[BX+6] ; _header _ CX MOV [BP-4],CX ; header->destHost.b.host = myHost.b.host; ; BX _ _header MOV BX,[BP-4] MOV AX,WORD PTR _myHost+1 MOV [BX+9],AL ; header->destSoc.LS = rpcSocket; ; BX _ _header MOV BX,[BP-4] MOV BYTE PTR [BX+13],01EX ; EnqueueAgain(b); ; BX _ _b MOV BX,[BP-2] CALL _EnqueueAgain ; }; MOV SP,BP POP BP RET; ; static int generator; ; int NewPSB(context) _NewPSB: ; struct RPCCtx *context; PUSH BP MOV BP,SP PUSH BX ; { /* generates non-null PSB unique to this epoch. */ ; if (++generator > maxPSB) SIGNAL(ERROR, 0); INC _generator MOV BX,_generator CMP BX,0FX JLE X112 XOR BX,BX MOV CX,2 CALL _SIGNAL X112: ; contexts[generator] = context; MOV BX,_generator LEA CX,_contexts SAL BX ADD BX,CX ; CX _ _context POP CX PUSH CX MOV [BX],CX ; return generator; MOV BX,_generator MOV SP,BP POP BP RET; ; }; ; RPCInitialize(pCtxQ) _RPCInitialize: ; struct Queue *pCtxQ PUSH BP MOV BP,SP PUSH BX ; { ; listenerRunning = (signalTimeout = true); MOV _signalTimeout,0FFFFX MOV _listenerRunning,0FFFFX ; minRetransmitPulses = minRetransmitMsecs; MOV _minRetransmitPulses,0FAX ; minPingPulses = minPingMsecs; MOV _minPingPulses,01388X ; maxPingPulses = maxPingSecs*1000; MOV _maxPingPulses,07530X ; broadcastRetransmissions = 5; MOV _broadcastRetransmissions,5 ; myCtxQ=pCtxQ; ; BX _ _pCtxQ POP BX PUSH BX MOV _myCtxQ,BX ; SignalInitialize(); CALL _SignalInitialize ; Zero(waiterPkts, maxPSB + 1); MOV BX,010X LEA CX,_waiterPkts CALL _Zero ; Zero(wanting, maxPSB + 1); MOV BX,010X LEA CX,_wanting CALL _Zero ; Zero(contexts, maxPSB + 1); MOV BX,010X LEA CX,_contexts CALL _Zero ; ReceivePktTooLong = CODE(); CALL _CODE MOV _ReceivePktTooLong,BX ; }; MOV SP,BP POP BP RET; ; Externals Declared Here PUBLIC _myHost PUBLIC _myCtxQ PUBLIC _mySoc PUBLIC _idlerQ PUBLIC _broadcastRetransmissions PUBLIC _rpct PUBLIC _PktExchange PUBLIC _EnqueueAgain PUBLIC _IdleReceive PUBLIC _EnqueueRecvd PUBLIC _EnqueueBcst PUBLIC _NewPSB PUBLIC _RPCInitialize C_CODE ENDS ; Number of Bytes of Code = 08A9X, (2217)