;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 <Context.h>
; 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)