;Alto->8086 small-c compiler rev 2.0
C←CODE SEGMENT

$INCLUDE(8086LIB.D)

$INCLUDE(rpcpktstreams.DEC)

ASSUME CS:C←CODE, DS:C←DATA

; #include <Queue.h>

; extern struct ExportInstance exportTable[1];

; extern int used;	/* # current exports */

; extern struct PktConversationID *firstConversation;

; extern int GetConnectionState();

; extern int IdleReceive();

; extern struct Queue *myCtxQ;

; extern union Machine myHost;

; extern int *mySoc;

; extern int PktExchange();

; extern int rpct;

; extern int CallFailed;

; extern int CONT();

; extern int RejectUnbound;

; extern int RejectProtocol;

; extern SendPup();

; extern struct PBI *GetPBI();

; extern int DoubleEq();

; extern int MultEq();

; extern CurrentContext();

; extern Block();

; extern Enqueue();

; extern int *Unqueue();

; extern int DoubleComp();

; extern int DoubleDiff();

; extern int DoubleInc();

; extern Move2();

; extern int StringSize();

; extern int *GetFixed();

; extern MoveBlock();

; extern Zero();

; extern int apply();

; static int idlerAckCount;

; static int idlerRequeueCount;

; int MisusedConversation;

; struct ConnectionData {

;   struct ConnectionData *next;

;   struct ConnectionID id;

;   struct CallCount callCt;

;   struct ConversationObject *conv; };

; struct ConnectionData *connections[0];

; struct CalleeState {

;   struct CalleeState *next;

;   num callee;	/* PSB.PSBIndex */

;   struct Header *state; };

; struct Queue callees; /* pointer to CalleeState */

; int lastCallDest[0];	/* ARRAY {0..maxPSB;}; OF PSB */

; static RecordCallDest(header) struct Header *header;{ lastCallDest[header->destPSB] = header->srcePSB; };
←RecordCallDest:
PUSH BP
MOV BP,SP
PUSH BX

;	BX ← ←header
POP BX
PUSH BX
MOV CX,[BX+4]
MOV BX,←lastCallDest
SAL CX
ADD BX,CX

;	CX ← ←header
POP CX
PUSH CX
MOV DI,CX
MOV CX,[DI+6]
MOV [BX],CX
MOV SP,BP
POP BP
RET;

; StartCall(callPkt, interface, localConversation)
←StartCall:

; 	struct PBI *callPkt;

; 	struct ImportInstance *interface;

; 	struct Conversation *localConversation; {
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX

;   int myPSB;

;   struct Header *header;

;   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-6],CX

;   header = callPkt->pup;

;	BX ← ←callPkt
MOV BX,[BP+4]
MOV CX,[BX+6]

;	←header ← CX
MOV [BP-8],CX

;   header->destHost = interface->host;

;	BX ← ←header
MOV BX,[BP-8]

;	DI ← ←interface
MOV DI,[BP-2]
MOV CX,[DI]
MOV [BX+8],CX

;   header->destSoc.LS = rpcSocket;

;	BX ← ←header
MOV BX,[BP-8]
MOV BYTE PTR [BX+13],01EX

;   header->destPSB = lastCallDest[myPSB];

;	BX ← ←header
MOV BX,[BP-8]

;	CX ← ←myPSB
MOV CX,[BP-6]
MOV AX,←lastCallDest
SAL CX
ADD CX,AX
MOV DI,CX
MOV CX,[DI]
MOV [BX+4],CX

;   callPkt->convHandle = localConversation;

;	BX ← ←callPkt
MOV BX,[BP+4]

;	CX ← ←localConversation
MOV CX,[BP-4]
MOV [BX+4],CX

;   if (localConversation == unencrypted)

;	BX ← ←localConversation
MOV BX,[BP-4]
OR BX,BX
JNZ X1

;   	Move2(&header->conv, firstConversation);

;	BX ← ←header
MOV BX,[BP-8]
ADD BX,014X
PUSH BX
MOV BX,←firstConversation
POP CX
CALL ←Move2

;   else {
JR X2
X1:

;     Move2(&header->conv, &localConversation->id.count);

;	BX ← ←header
MOV BX,[BP-8]
ADD BX,014X

;	CX ← ←localConversation
MOV CX,[BP-4]
ADD CX,4
XCHG BX,CX
CALL ←Move2

;     if (localConversation->id.originator.w == myHost.w)

;	BX ← ←localConversation
MOV BX,[BP-4]
MOV CX,[BX+2]
MOV BX,WORD PTR ←myHost
CMP CX,BX
JNZ X3

;     	header->conv.fields &= notCalleeMask; /* header->conv.originator = caller */

;	BX ← ←header
MOV BX,[BP-8]
AND WORD PTR [BX+22],0FF7FX

;     else if (header->destHost.w == localConversation->id.originator.w)
JR X4
X3:

;	BX ← ←header
MOV BX,[BP-8]
MOV CX,[BX+8]

;	BX ← ←localConversation
MOV BX,[BP-4]
MOV AX,[BX+2]
CMP CX,AX
JNZ X5

;     	header->conv.fields |= calleeField; /* header->conv.originator = callee */

;	BX ← ←header
MOV BX,[BP-8]
OR WORD PTR [BX+22],080X

;     else ERROR(MisusedConversation); };
JR X6
X5:
X6:
X4:
X2:

;   header->pktID.activity = myPSB;

;	BX ← ←header
MOV BX,[BP-8]

;	CX ← ←myPSB
MOV CX,[BP-6]
MOV [BX+24],CX

;   header->pktID.pktSeq = 0; /* => new call -- */

;	BX ← ←header
MOV BX,[BP-8]
MOV WORD PTR [BX+30],0

;   MoveBlock(&header->callSpec.dispatcherDet, &interface->dispatcherDet, lenDispatcherDetails);

;	BX ← ←header
MOV BX,[BP-8]
ADD BX,020X
PUSH BX

;	BX ← ←interface
MOV BX,[BP-2]
ADD BX,4
PUSH BX
MOV BX,4
POP CX
CALL ←MoveBlock
POP DX

;   Block(); };
CALL ←Block
MOV SP,BP
POP BP
RET;

; int/* returnLength: */

; Call(pkt, callLength, maxReturnLength)
←Call:

; 	struct PBI *pkt; int callLength, maxReturnLength; {
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX

;   int returnLength;

;   struct Header *recvdHeader;
ADD SP,0FFFCX

;   recvdHeader = pkt->pup;

;	BX ← ←pkt
MOV BX,[BP+4]
MOV CX,[BX+6]

;	←recvdHeader ← CX
POP DX
PUSH CX

;   returnLength = PktExchange(pkt, callLength, maxReturnLength, calling);

;	BX ← ←pkt
MOV BX,[BP+4]
PUSH BX

;	BX ← ←callLength
MOV BX,[BP-2]
PUSH BX
MOV BX,2

;	CX ← ←maxReturnLength
MOV CX,[BP-4]
CALL ←PktExchange
ADD SP,4

;	←returnLength ← BX
MOV [BP-6],BX

;   RecordCallDest(recvdHeader);

;	BX ← ←recvdHeader
POP BX
PUSH BX
CALL ←RecordCallDest

;   switch (recvdHeader->callSpec.outcome) {

;	BX ← ←recvdHeader
POP BX
PUSH BX
MOV CX,[BX+32]
JR X7

;     case unbound: SIGNAL(CallFailed, unbound);
X9:
MOV BX,1
MOV CX,←CallFailed
CALL ←SIGNAL

;     case result: break;
X10:
JR X8

;     case protocol: SIGNAL(CallFailed, runtimeProtocol);
X11:
MOV BX,0FX
MOV CX,←CallFailed
CALL ←SIGNAL

;     default: SIGNAL(CallFailed, runtimeProtocol); }; /* call failed, somehow, maybe a signal */
X12:
MOV BX,0FX
MOV CX,←CallFailed
CALL ←SIGNAL
JR X8
X7:
MOV AL,CH
OR AL,AL
JNZ X12
MOV AL,CL
CMP AL,1
JZ X9
CMP AL,0
JZ X10
CMP AL,4
JZ X11
JR X12
X8:

;   SetupResponse(recvdHeader);

;	BX ← ←recvdHeader
POP BX
PUSH BX
CALL ←SetupResponse

;   if ((recvdHeader->type.fields)&eomField)  SIGNAL(CallFailed, runtimeProtocol);

;	BX ← ←recvdHeader
POP BX
PUSH BX
MOV AL,[BX+3]
AND AL,010X
OR AL,AL
JZ X13
MOV BX,0FX
MOV CX,←CallFailed
CALL ←SIGNAL
X13:

;   return returnLength; };

;	BX ← ←returnLength
MOV BX,[BP-6]
MOV SP,BP
POP BP
RET;

; GenerateIdlerResponse(recvd) struct PBI *recvd; { /* Ack */
←GenerateIdlerResponse:
PUSH BP
MOV BP,SP
PUSH BX

;   struct PBI *ackPkt;

;   struct Header *header;

;   struct Header *recvdHeader;

;   num workerPSB;
ADD SP,0FFF8X

;   ackPkt = GetPBI(mySoc);
MOV BX,←mySoc
CALL ←GetPBI

;	←ackPkt ← BX
MOV [BP-4],BX

;   header = ackPkt->pup;

;	BX ← ←ackPkt
MOV BX,[BP-4]
MOV CX,[BX+6]

;	←header ← CX
MOV [BP-6],CX

;   recvdHeader = recvd->pup;

;	BX ← ←recvd
MOV BX,[BP-2]
MOV CX,[BX+6]

;	←recvdHeader ← CX
MOV [BP-8],CX

;   workerPSB = recvdHeader->destPSB; /* as adjusted by FindCallee */

;	BX ← ←recvdHeader
MOV BX,[BP-8]
MOV CX,[BX+4]

;	←workerPSB ← CX
POP DX
PUSH CX

;   ++idlerAckCount;
INC ←idlerAckCount

;   SetupResponse(recvdHeader);

;	BX ← ←recvdHeader
MOV BX,[BP-8]
CALL ←SetupResponse

;   MoveBlock(header, recvdHeader, lenHeader);

;	BX ← ←header
MOV BX,[BP-6]
PUSH BX
MOV BX,014X

;	CX ← ←recvdHeader
MOV CX,[BP-8]
CALL ←MoveBlock
POP DX

;   header->type.fields = typeAck;

;	BX ← ←header
MOV BX,[BP-6]
MOV BYTE PTR [BX+3],062X

;   header->srceHost.w = myHost.w;

;	BX ← ←header
MOV BX,[BP-6]
MOV CX,WORD PTR ←myHost
MOV [BX+14],CX

;   header->srceSoc.LS = rpcSocket;

;	BX ← ←header
MOV BX,[BP-6]
MOV BYTE PTR [BX+19],01EX

;   header->srcePSB = workerPSB;

;	BX ← ←header
MOV BX,[BP-6]

;	CX ← ←workerPSB
POP CX
PUSH CX
MOV [BX+6],CX

;   SendPup(ackPkt); Block(); }; /* hit it hard, and wish it well. */

;	BX ← ←ackPkt
MOV BX,[BP-4]
CALL ←SendPup
CALL ←Block
MOV SP,BP
POP BP
RET;

; static EnqueueForNewPSB(recvd) struct PBI *recvd; {
←EnqueueForNewPSB:
PUSH BP
MOV BP,SP
PUSH BX

; 	struct PBI *pupPkt;

; 	struct Header *header, *recvdHeader;
ADD SP,0FFFAX

; 	pupPkt = GetPBI(mySoc);
MOV BX,←mySoc
CALL ←GetPBI

;	←pupPkt ← BX
MOV [BP-4],BX

; 	header = pupPkt->pup;

;	BX ← ←pupPkt
MOV BX,[BP-4]
MOV CX,[BX+6]

;	←header ← CX
MOV [BP-6],CX

;    recvdHeader = recvd->pup;

;	BX ← ←recvd
MOV BX,[BP-2]
MOV CX,[BX+6]

;	←recvdHeader ← CX
POP DX
PUSH CX

;    ++idlerRequeueCount;
INC ←idlerRequeueCount

;    MoveBlock(header, recvdHeader, (Swab(recvdHeader->length)>>1));

;	BX ← ←header
MOV BX,[BP-6]
PUSH BX

;	DI ← ←recvdHeader
MOV DI,[BP-8]
MOV BX,[DI]
CALL ←Swab
SHR BX

;	CX ← ←recvdHeader
MOV CX,[BP-8]
CALL ←MoveBlock
POP DX

;    EnqueueAgain(pupPkt); };

;	BX ← ←pupPkt
MOV BX,[BP-4]
CALL ←EnqueueAgain
MOV SP,BP
POP BP
RET;

; static AddCallee(stateBlock) struct CalleeState *stateBlock; { Enqueue(&callees, stateBlock); };
←AddCallee:
PUSH BP
MOV BP,SP
PUSH BX

;	BX ← ←stateBlock
POP BX
PUSH BX
LEA CX,←callees
CALL ←Enqueue
MOV SP,BP
POP BP
RET;

;  static RemoveCallee(stateBlock) struct CalleeState *stateBlock; {
←RemoveCallee:
PUSH BP
MOV BP,SP
PUSH BX

;  	if (Unqueue(&callees, stateBlock)==0) SIGNAL(ERROR, 0); Block(); };

;	BX ← ←stateBlock
POP BX
PUSH BX
LEA CX,←callees
CALL ←Unqueue
OR BX,BX
JNZ X14
XOR BX,BX
MOV CX,2
CALL ←SIGNAL
X14:
CALL ←Block
MOV SP,BP
POP BP
RET;

; static int /* BOOLEAN */

; FindCallee(given) struct Header *given; {
←FindCallee:
PUSH BP
MOV BP,SP
PUSH BX

;   struct CalleeState *p;

;   struct Header *stateHeader;
ADD SP,0FFFCX

;   p = (struct CalleeState *) callees.head;
MOV BX,WORD PTR ←callees

;	←p ← BX
MOV [BP-4],BX

;   while (p) {
X15:

;	BX ← ←p
MOV BX,[BP-4]
OR BX,BX
JZ X16

;     stateHeader = p->state;

;	BX ← ←p
MOV BX,[BP-4]
MOV CX,[BX+4]

;	←stateHeader ← CX
POP DX
PUSH CX

;     if (MultEq(&stateHeader->conv, /* works because callCt follows ConvCt */

;     	      &given->conv, lenPktConversationID+1+lenCallCount))  {

;	BX ← ←stateHeader
POP BX
PUSH BX
ADD BX,014X
PUSH BX

;	BX ← ←given
MOV BX,[BP-2]
ADD BX,014X
PUSH BX
MOV BX,5
POP CX
CALL ←MultEq
POP DX
OR BX,BX
JZ X17

; 	  given->destPSB = p->callee;

;	BX ← ←given
MOV BX,[BP-2]

;	CX ← ←p
MOV CX,[BP-4]
MOV DI,CX
MOV CX,[DI+2]
MOV [BX+4],CX

; 	  Block();
CALL ←Block

; 	  return true; };
MOV BX,0FFFFX
MOV SP,BP
POP BP
RET;
X17:

;     p = p->next; };

;	DI ← ←p
MOV DI,[BP-4]
MOV BX,[DI]

;	←p ← BX
MOV [BP-4],BX
JR X15
X16:

;   Block();
CALL ←Block

;   return false; };
XOR BX,BX
MOV SP,BP
POP BP
RET;

; ForgetConnections() {
←ForgetConnections:
PUSH BP
MOV BP,SP

; 	int i;

; 	struct ConnectionData *connection;

; 	struct ConnectionData *next;

; 	for (i=0; i<128; ++i) {
ADD SP,0FFFAX
MOV WORD PTR [BP-2],0
X20:

;	BX ← ←i
MOV BX,[BP-2]
CMP BX,080X
JGE X19
JR X18
X21:
INC WORD PTR [BP-2]
JR X20
X18:

; 		connection = connections[i];

;	BX ← ←i
MOV BX,[BP-2]
MOV CX,←connections
SAL BX
ADD BX,CX
MOV CX,[BX]

;	←connection ← CX
MOV [BP-4],CX

; 		while (connection) {
X22:

;	BX ← ←connection
MOV BX,[BP-4]
OR BX,BX
JZ X23

; 			next = connection->next;

;	DI ← ←connection
MOV DI,[BP-4]
MOV BX,[DI]

;	←next ← BX
POP DX
PUSH BX

; 			connection = next; };

;	BX ← ←next
POP BX
PUSH BX

;	←connection ← BX
MOV [BP-4],BX
JR X22
X23:

; 		connections[i]=0; }; };

;	BX ← ←i
MOV BX,[BP-2]
MOV CX,←connections
SAL BX
ADD BX,CX
MOV WORD PTR [BX],0
JR X21
X19:
MOV SP,BP
POP BP
RET;

; static int RemC(nil1, nil2, seal)
←RemC:

; 	int nil1, nil2; struct Seal1 *seal; { RemoveCallee(seal->data[0]); return CONTINUE; };
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX

;	BX ← ←seal
POP BX
PUSH BX
ADD BX,4
MOV CX,[BX]
MOV BX,CX
CALL ←RemoveCallee
MOV BX,4
MOV SP,BP
POP BP
RET;

; ServerMain() {
←ServerMain:
PUSH BP
MOV BP,SP

;   int myPSB;

;   struct PBI *myPkt;

;   struct Header *recvdHeader;

;   struct CalleeState *myStateBlock;

;   struct Seal1 s1;

;   struct Seal s2;

;   struct Seal s4;

;   struct Seal1 s3;

;   int /* BOOL */ decrypted, newPkt;

;   int newLength;

;   int ackLen;

;   struct ConnectionData *connection;

;   struct ConnectionID id;

;   int /*BOOL*/ ok;

;   struct DispatcherDetails *target;

;   struct ExportInstance *instance;

;   int resultLength, *rout, hint;

;   int argv[4];

;   struct CallCount aCall;

;   struct Conversation *conv;

;   struct RPCCtx *CtxRunning;

;   int lll; /* Some sort of length */

;   int oldDest; /* PsbIndex */

;   int /*BOOL*/ knownCallee;
ADD SP,0FFB0X

;   CtxRunning = CurrentContext();
CALL ←CurrentContext

;	←CtxRunning ← BX
MOV [BP-74],BX

;   myPSB = CtxRunning->user.myPSB;

;	BX ← ←CtxRunning
MOV BX,[BP-74]
MOV CX,[BX+26]

;	←myPSB ← CX
MOV [BP-2],CX

;   myPkt = GetPBI(mySoc)
MOV BX,←mySoc
CALL ←GetPBI

;	←myPkt ← BX
MOV [BP-4],BX

;   recvdHeader = myPkt->pup;

;	BX ← ←myPkt
MOV BX,[BP-4]
MOV CX,[BX+6]

;	←recvdHeader ← CX
MOV [BP-6],CX

;   myStateBlock = (struct CalleeState *) GetFixed(lenCalleeState);
MOV BX,3
CALL ←GetFixed

;	←myStateBlock ← BX
MOV [BP-8],BX

;   myStateBlock->callee = myPSB;

;	BX ← ←myStateBlock
MOV BX,[BP-8]

;	CX ← ←myPSB
MOV CX,[BP-2]
MOV [BX+2],CX

;   myStateBlock->state = recvdHeader;

;	BX ← ←myStateBlock
MOV BX,[BP-8]

;	CX ← ←recvdHeader
MOV CX,[BP-6]
MOV [BX+4],CX

;   newPkt = (decrypted = (newLength = 0));
MOV WORD PTR [BP-34],0
MOV WORD PTR [BP-30],0
MOV WORD PTR [BP-32],0

;   myStateBlock->next = 0;

;	BX ← ←myStateBlock
MOV BX,[BP-8]
MOV WORD PTR [BX],0

;   connection = 0;
MOV WORD PTR [BP-38],0

;   s1.data[0] = (s3.data[0] = (int) myStateBlock);

;	BX ← ←myStateBlock
MOV BX,[BP-8]

;	←s3+4 ← BX
MOV [BP-24],BX

;	←s1+4 ← BX
MOV [BP-10],BX

; while (true) {
X24:

;   DISABLE(&s1); DISABLE(&s2); DISABLE(&s3); DISABLE(&s4);
;&←s1
LEA BX,[BP-14]
CALL ←DISABLE
;&←s2
LEA BX,[BP-18]
CALL ←DISABLE
;&←s3
LEA BX,[BP-28]
CALL ←DISABLE
;&←s4
LEA BX,[BP-22]
CALL ←DISABLE

;   if (newPkt == 0)  {

;	BX ← ←newPkt
MOV BX,[BP-32]
OR BX,BX
JNZ X26

;   	IdleReceive(myPkt, maxPupWords);
MOV BX,065X

;	CX ← ←myPkt
MOV CX,[BP-4]
CALL ←IdleReceive

;   	newPkt = true; decrypted = false;
MOV WORD PTR [BP-32],0FFFFX
MOV WORD PTR [BP-30],0

; 	if ((recvdHeader->type.fields&classField) == call

; 		&& ((recvdHeader->type.fields&ackField) !=0))  newPkt = newPkt; };

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV AL,[BX+3]
AND AL,7
OR AL,AL
JNZ X28

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV AL,[BX+3]
AND AL,8
OR AL,AL
JZ X28
MOV AL,1
JR X29
X28:
XOR AL,AL
X29:
OR AL,AL
JZ X27

;	BX ← ←newPkt
MOV BX,[BP-32]

;	←newPkt ← BX
MOV [BP-32],BX
X27:
X26:

;   Move2(&id.conv, &recvdHeader->conv);

;	BX ← ←recvdHeader
MOV BX,[BP-6]
ADD BX,014X
;&←id
LEA CX,[BP-46]
CALL ←Move2

;   id.caller = recvdHeader->srceHost;

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV CX,[BX+14]

;	←id+4 ← CX
MOV [BP-42],CX

;   id.activity = recvdHeader->srcePSB;

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV CX,[BX+6]

;	←id+6 ← CX
MOV [BP-40],CX

;   Block();
CALL ←Block

;   connection = connections[(Swab(id.caller.w ↑ id.activity)) & 127];

;	BX ← ←id+6
MOV BX,[BP-40]

;	CX ← ←id+4
MOV CX,[BP-42]
XOR CX,BX
MOV BX,CX
CALL ←Swab
AND BX,07FX
MOV CX,←connections
SAL BX
ADD BX,CX
MOV CX,[BX]

;	←connection ← CX
MOV [BP-38],CX

;   while (connection)  {
X30:

;	BX ← ←connection
MOV BX,[BP-38]
OR BX,BX
JZ X31

;     if (MultEq(&id.conv, &connection->id.conv, lenPktConversationID+1) &&

;     recvdHeader->srcePSB == connection->id.activity)  {
;&←id
LEA BX,[BP-46]
PUSH BX

;	BX ← ←connection
MOV BX,[BP-38]
INC BX
INC BX
PUSH BX
MOV BX,3
POP CX
CALL ←MultEq
POP DX
OR BX,BX
JZ X33

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV CX,[BX+6]

;	BX ← ←connection
MOV BX,[BP-38]
MOV AX,[BX+8]
CMP CX,AX
JNZ X33
MOV AL,1
JR X34
X33:
XOR AL,AL
X34:
OR AL,AL
JZ X32

;       myPkt->convHandle = connection->conv;

;	BX ← ←myPkt
MOV BX,[BP-4]

;	CX ← ←connection
MOV CX,[BP-38]
MOV DI,CX
MOV CX,[DI+14]
MOV [BX+4],CX

;       if (decrypted == false) {

;	BX ← ←decrypted
MOV BX,[BP-30]
OR BX,BX
JNZ X35

;       	if (connection->conv != unencrypted) {

;	BX ← ←connection
MOV BX,[BP-38]
MOV CX,[BX+14]
OR CX,CX
JZ X36

;       		ok = DecryptPkt(recvdHeader, myPkt->convHandle, &newLength);

;	BX ← ←recvdHeader
MOV BX,[BP-6]
PUSH BX

;	BX ← ←myPkt
MOV BX,[BP-4]
MOV CX,[BX+4]
;&←newLength
LEA BX,[BP-34]
CALL ←DecryptPkt
POP DX

;	←ok ← BX
MOV [BP-48],BX

;       		decrypted=true;
MOV WORD PTR [BP-30],0FFFFX

;       		if (ok==false) goto CallerPhoney; };

;	BX ← ←ok
MOV BX,[BP-48]
OR BX,BX
JNZ X37
JMP ←CallerPhoney
X37:

;       	else { newLength = (Swab(recvdHeader->length) >>1) - pktLengthOverhead;
JR X38
X36:

;	DI ← ←recvdHeader
JR $+5
X31:
JMP X39
MOV DI,[BP-6]
MOV BX,[DI]
CALL ←Swab
SHR BX
ADD BX,0FFEBX

;	←newLength ← BX
MOV [BP-34],BX

;       			decrypted=true; }; };
MOV WORD PTR [BP-30],0FFFFX
X38:
X35:

;       if (recvdHeader->pktID.activity != recvdHeader->srcePSB)  goto CallerPhoney;

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV CX,[BX+24]

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV AX,[BX+6]
CMP CX,AX
JZ X40
JMP ←CallerPhoney
X40:

;       if ((recvdHeader->type.fields&classField) != call)  goto CallerOld;

;	BX ← ←recvdHeader
MOV BX,[BP-6]
JR $+5
X32:
JMP X42
MOV AL,[BX+3]
AND AL,7
OR AL,AL
JZ X41
JMP ←CallerOld
X41:

;       if (DoubleComp(&recvdHeader->pktID.callCt, &connection->callCt)>0)  {

;	BX ← ←recvdHeader
MOV BX,[BP-6]
ADD BX,01AX

;	CX ← ←connection
MOV CX,[BP-38]
ADD CX,0AX
XCHG BX,CX
CALL ←DoubleComp
CMP BX,0
JLE X43

;         if (recvdHeader->pktID.pktSeq != swapped1)  goto CallerPhoney;

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV CX,[BX+30]
MOV BX,CX
CMP BX,0100X
JZ X44
JMP ←CallerPhoney
X44:

; 		Move2(&connection->callCt, &recvdHeader->pktID.callCt);

;	BX ← ←connection
MOV BX,[BP-38]
ADD BX,0AX

;	CX ← ←recvdHeader
MOV CX,[BP-6]
ADD CX,01AX
XCHG BX,CX
CALL ←Move2

; 		AddCallee(myStateBlock);

;	BX ← ←myStateBlock
MOV BX,[BP-8]
CALL ←AddCallee

; 		goto CallerNew; };
JMP ←CallerNew

;       else goto CallerOld; };
X43:
JMP ←CallerOld
X42:

;       connection = connection->next; };

;	DI ← ←connection
MOV DI,[BP-38]
MOV BX,[DI]

;	←connection ← BX
MOV [BP-38],BX
JMP X30
X39:

;   if ((recvdHeader->type.fields&classField) == call) goto CallerUnknown; else goto CallerOld;

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV AL,[BX+3]
AND AL,7
OR AL,AL
JNZ X45
JMP ←CallerUnknown
X45:
JMP ←CallerOld

;   SIGNAL(ERROR, 0); /* no where to go! */
XOR BX,BX
MOV CX,2
CALL ←SIGNAL
←CallerNew:

;       CallerNew: {

; 		Block();
CALL ←Block

; 		target = &recvdHeader->callSpec.dispatcherDet;

;	BX ← ←recvdHeader
MOV BX,[BP-6]
ADD BX,020X

;	←target ← BX
MOV [BP-50],BX

; 		SetupResponse(recvdHeader);

;	BX ← ←recvdHeader
MOV BX,[BP-6]
CALL ←SetupResponse

; 		if (((hint=Swab(target->dispatcherHint)) >= used) ||

; 		   ((instance = &exportTable[hint]) != instance) ||

; 		   (!DoubleEq(&target->dispatcherID, &instance->id))) {

;	BX ← ←target
MOV BX,[BP-50]
MOV CX,[BX+6]
MOV BX,CX
CALL ←Swab

;	←hint ← BX
MOV [BP-58],BX
MOV CX,←used
CMP BX,CX
JGE X48

;	BX ← ←hint
MOV BX,[BP-58]
LEA CX,←exportTable
MOV AX,012X
IMUL AX,BX
ADD AX,CX

;	←instance ← AX
MOV [BP-52],AX

;	BX ← ←instance
MOV BX,[BP-52]
CMP AX,BX
JNZ X50

;	BX ← ←target
MOV BX,[BP-50]
INC BX
INC BX

;	CX ← ←instance
MOV CX,[BP-52]
INC CX
INC CX
XCHG BX,CX
CALL ←DoubleEq
OR BX,BX
JNZ X49
X50:
MOV AL,1
JR X51
X49:
XOR AL,AL
X51:
OR AL,AL
JZ X47
X48:
MOV AL,1
JR X52
X47:
XOR AL,AL
X52:
OR AL,AL
JZ X46

; 			recvdHeader->callSpec.outcome = unbound; resultLength = 0; };

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV WORD PTR [BX+32],1
MOV WORD PTR [BP-54],0

; 		else {
JR X53
X46:

; 			rout = instance->dispatcher;

;	BX ← ←instance
MOV BX,[BP-52]
MOV CX,[BX+6]

;	←rout ← CX
MOV [BP-56],CX

; 			ENABLE(UNWIND, &RemC, &s3);
MOV BX,1
PUSH BX
;&←s3
LEA BX,[BP-28]
MOV CX,OFFSET ←RemC
CALL ←ENABLE
POP DX

; 			if (ENABLE(RejectUnbound, &CONT, &s4))  {
MOV BX,←RejectUnbound
PUSH BX
;&←s4
LEA BX,[BP-22]
MOV CX,OFFSET ←CONT
CALL ←ENABLE
POP DX
OR BX,BX
JZ X54

; 				recvdHeader->callSpec.outcome = unbound; resultLength = 0; };

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV WORD PTR [BX+32],1
MOV WORD PTR [BP-54],0

; 			else if (ENABLE(RejectProtocol, &CONT, &s2)) {
JR X55
X54:
MOV BX,←RejectProtocol
PUSH BX
;&←s2
LEA BX,[BP-18]
MOV CX,OFFSET ←CONT
CALL ←ENABLE
POP DX
OR BX,BX
JZ X56

; 				recvdHeader->callSpec.outcome = protocol; resultLength = 0; };

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV WORD PTR [BX+32],4
MOV WORD PTR [BP-54],0

; 			else if (ENABLE(CallFailed, &RemC, &s1))  { newPkt=false; continue; };
JR X57
X56:
MOV BX,←CallFailed
PUSH BX
;&←s1
LEA BX,[BP-14]
MOV CX,OFFSET ←RemC
CALL ←ENABLE
POP DX
OR BX,BX
JZ X58
MOV WORD PTR [BP-32],0
JMP X24

;     		else {
X58:

; 			argv[0] = (int) myPkt;

;	BX ← ←myPkt
MOV BX,[BP-4]

;	←argv ← BX
JR $+5
X53:
JMP X59
MOV [BP-66],BX

; 			argv[1] = newLength;

;	BX ← ←newLength
MOV BX,[BP-34]

;	←argv+2 ← BX
MOV [BP-64],BX

; 			argv[2] = (int) connection->conv;

;	BX ← ←connection
MOV BX,[BP-38]
MOV CX,[BX+14]

;	←argv+4 ← CX
MOV [BP-62],CX

; 			argv[3] = (int) instance->dispatcherArgs;

;	BX ← ←instance
MOV BX,[BP-52]
MOV CX,[BX+8]

;	←argv+6 ← CX
MOV [BP-60],CX

; 			resultLength= apply(argv, rout, 4); };
;&←argv
LEA BX,[BP-66]
PUSH BX
MOV BX,4

;	CX ← ←rout
MOV CX,[BP-56]
CALL ←apply
POP DX

;	←resultLength ← BX
MOV [BP-54],BX
X57:
X55:

; 			DISABLE(&s2); DISABLE(&s3); DISABLE(&s4);
;&←s2
LEA BX,[BP-18]
CALL ←DISABLE
;&←s3
LEA BX,[BP-28]
CALL ←DISABLE
;&←s4
LEA BX,[BP-22]
CALL ←DISABLE

; 			};
X59:

; 		RemoveCallee(myStateBlock);

;	BX ← ←myStateBlock
MOV BX,[BP-8]
CALL ←RemoveCallee

;         if (ENABLE(CallFailed, &CONT, &s1))  newPkt=false;
MOV BX,←CallFailed
PUSH BX
;&←s1
LEA BX,[BP-14]
MOV CX,OFFSET ←CONT
CALL ←ENABLE
POP DX
OR BX,BX
JZ X60
MOV WORD PTR [BP-32],0

; 		else {
JR X61
X60:

; 	   		newLength = PktExchange(myPkt, resultLength, serverDataLength, endCall);

;	BX ← ←myPkt
MOV BX,[BP-4]
PUSH BX

;	BX ← ←resultLength
MOV BX,[BP-54]
PUSH BX
MOV BX,3
MOV CX,076X
CALL ←PktExchange
ADD SP,4

;	←newLength ← BX
MOV [BP-34],BX

; 	   		newPkt = (newLength >= 0); };

;	BX ← ←newLength
MOV BX,[BP-34]
CMP BX,0
JL X62
MOV BX,1
JR X63
X62:
XOR BX,BX
X63:

;	←newPkt ← BX
MOV [BP-32],BX
X61:

; 	   	if (newPkt) decrypted = true;

;	BX ← ←newPkt
MOV BX,[BP-32]
OR BX,BX
JZ X64
MOV WORD PTR [BP-30],0FFFFX
X64:

; 		continue;};
JMP X24
←CallerUnknown:

;     CallerUnknown: {

;     	Block();
CALL ←Block

; 		ok = (ENABLE(CallFailed, &CONT, &s1) == false && 

; 	        GetConnectionState(decrypted, myPkt, &id, &aCall, &conv, &lll) == true);
MOV BX,←CallFailed
PUSH BX
;&←s1
LEA BX,[BP-14]
MOV CX,OFFSET ←CONT
CALL ←ENABLE
POP DX
OR BX,BX
JNZ X65

;	BX ← ←decrypted
MOV BX,[BP-30]
PUSH BX

;	BX ← ←myPkt
MOV BX,[BP-4]
PUSH BX
;&←id
LEA BX,[BP-46]
PUSH BX
;&←aCall
LEA BX,[BP-70]
PUSH BX
;&←lll
LEA BX,[BP-76]
;&←conv
LEA CX,[BP-72]
CALL ←GetConnectionState
ADD SP,8
CMP BX,0FFFFX
X65:
JNZ X66
MOV BX,1
JR X67
X66:
XOR BX,BX
X67:

;	←ok ← BX
MOV [BP-48],BX

; 		if (ok) {

;	BX ← ←ok
MOV BX,[BP-48]
OR BX,BX
JZ X68

; 			if (newPkt == false) SIGNAL(ERROR, 0);

;	BX ← ←newPkt
MOV BX,[BP-32]
OR BX,BX
JNZ X69
XOR BX,BX
MOV CX,2
CALL ←SIGNAL
X69:

; 			if (decrypted == false) { decrypted = true; newLength = lll; };

;	BX ← ←decrypted
MOV BX,[BP-30]
OR BX,BX
JNZ X70
MOV WORD PTR [BP-30],0FFFFX

;	BX ← ←lll
MOV BX,[BP-76]

;	←newLength ← BX
MOV [BP-34],BX
X70:

; 			NoteConnection(&id, &aCall, conv); };
;&←id
LEA BX,[BP-46]
PUSH BX

;	BX ← ←conv
MOV BX,[BP-72]
;&←aCall
LEA CX,[BP-70]
CALL ←NoteConnection
POP DX

; 		else newPkt = false;
JR X71
X68:
MOV WORD PTR [BP-32],0
X71:

; 		continue ; };
JMP X24
←CallerPhoney:

;     CallerPhoney: /* ignorable packet */

; 		newPkt = false; continue;
MOV WORD PTR [BP-32],0
JMP X24
←CallerOld:

;     CallerOld: {

;     	Block();
CALL ←Block

;     	oldDest = recvdHeader->destPSB;

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV CX,[BX+4]

;	←oldDest ← CX
MOV [BP-78],CX

;     	knownCallee = ((decrypted == true) && (FindCallee(recvdHeader) != 0));

;	BX ← ←decrypted
MOV BX,[BP-30]
CMP BX,0FFFFX
JNZ X72

;	BX ← ←recvdHeader
MOV BX,[BP-6]
CALL ←FindCallee
OR BX,BX
JZ X72
MOV AL,1
JR X73
X72:
XOR AL,AL
X73:
XOR AH,AH

;	←knownCallee ← AX
POP DX
PUSH AX

;     	if ((knownCallee==true) && (recvdHeader->destPSB != oldDest)) {

;	BX ← ←knownCallee
POP BX
PUSH BX
CMP BX,0FFFFX
JNZ X75

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV CX,[BX+4]

;	BX ← ←oldDest
MOV BX,[BP-78]
CMP CX,BX
JZ X75
MOV AL,1
JR X76
X75:
XOR AL,AL
X76:
OR AL,AL
JZ X74

;     		if (decrypted) {

;	BX ← ←decrypted
MOV BX,[BP-30]
OR BX,BX
JZ X77

;     			if (myPkt->convHandle == unencrypted)

;	BX ← ←myPkt
MOV BX,[BP-4]
MOV CX,[BX+4]
OR CX,CX
JNZ X78

;     				ackLen = pktLengthOverhead + newLength;

;	BX ← ←newLength
MOV BX,[BP-34]
ADD BX,015X

;	←ackLen ← BX
MOV [BP-36],BX

;     			else ackLen = EncryptPkt(myPkt, newLength);
JR X79
X78:

;	BX ← ←newLength
MOV BX,[BP-34]

;	CX ← ←myPkt
MOV CX,[BP-4]
CALL ←EncryptPkt

;	←ackLen ← BX
MOV [BP-36],BX
X79:

;     			recvdHeader->length = Swab(ackLen << 1); };

;	BX ← ←ackLen
MOV BX,[BP-36]
SAL BX
CALL ←Swab
MOV CX,BX

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV [BX],CX
X77:

;     		EnqueueForNewPSB(myPkt); };

;	BX ← ←myPkt
MOV BX,[BP-4]
CALL ←EnqueueForNewPSB

;     	else {
JR X80
X74:

;     		if ((recvdHeader->type.fields&ackField) &&

;     			((recvdHeader->type.fields&eomField) == 0) &&

;     			(((recvdHeader->type.fields&classField) == xtraData) || (knownCallee==true))) {

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV AL,[BX+3]
AND AL,8
OR AL,AL
JZ X82

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV AL,[BX+3]
AND AL,010X
OR AL,AL
JNZ X83

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV AL,[BX+3]
AND AL,7
CMP AL,1
JZ X85

;	BX ← ←knownCallee
POP BX
PUSH BX
CMP BX,0FFFFX
X85:
X84:
X83:
JNZ X82
MOV AL,1
JR X86
X82:
XOR AL,AL
X86:
OR AL,AL
JZ X81

;     				if ((!decrypted) || (myPkt->convHandle == unencrypted))

;	BX ← ←decrypted
MOV BX,[BP-30]
OR BX,BX
JZ X89

;	BX ← ←myPkt
MOV BX,[BP-4]
MOV CX,[BX+4]
OR CX,CX
X89:
X88:
JNZ X87

;     					ackLen = pktLengthOverhead;
MOV WORD PTR [BP-36],015X

;     				else ackLen = EncryptPkt(myPkt, 0);
JR X90
X87:
XOR BX,BX

;	CX ← ←myPkt
MOV CX,[BP-4]
CALL ←EncryptPkt

;	←ackLen ← BX
MOV [BP-36],BX
X90:

;     				recvdHeader->length = Swab(ackLen << 1);

;	BX ← ←ackLen
MOV BX,[BP-36]
SAL BX
CALL ←Swab
MOV CX,BX

;	BX ← ←recvdHeader
MOV BX,[BP-6]
MOV [BX],CX

;     				GenerateIdlerResponse(myPkt); }; };

;	BX ← ←myPkt
MOV BX,[BP-4]
CALL ←GenerateIdlerResponse
X81:
X80:

;        		newPkt=false;
MOV WORD PTR [BP-32],0

; 		continue; }; }; /* endloop */ };
JMP X24
X25:
MOV SP,BP
POP BP
RET;

; static int one[2];	

; static NoteConnection(id, callCt, conv) 
←NoteConnection:

; 	struct ConnectionID *id;

; 	struct CallCount *callCt;

; 	struct Conversation *conv; {
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX

;   struct ConnectionData *dataPtr;

;   struct ConnectionData *connection;
ADD SP,0FFFCX

;   dataPtr =

; 	(struct ConnectionData *) &connections[(Swab(id->caller.w ↑ id->activity)) & 127];

;	BX ← ←id
MOV BX,[BP+4]
MOV CX,[BX+4]

;	BX ← ←id
MOV BX,[BP+4]
MOV AX,[BX+6]
XOR CX,AX
MOV BX,CX
CALL ←Swab
AND BX,07FX
MOV CX,←connections
SAL BX
ADD BX,CX

;	←dataPtr ← BX
MOV [BP-6],BX

;   connection = dataPtr->next;

;	DI ← ←dataPtr
MOV DI,[BP-6]
MOV BX,[DI]

;	←connection ← BX
POP DX
PUSH BX

;   while (connection)   { /* SELECT TRUE FROM .. */
X91:

;	BX ← ←connection
POP BX
PUSH BX
OR BX,BX
JZ X92

;     if (MultEq(id, &connection->id, lenConnectionID))  return; /* Already there!? -- */

;	BX ← ←id
MOV BX,[BP+4]
PUSH BX

;	BX ← ←connection
MOV BX,[BP-8]
INC BX
INC BX
PUSH BX
MOV BX,4
POP CX
CALL ←MultEq
POP DX
OR BX,BX
JZ X93
MOV SP,BP
POP BP
RET;
X93:

;     dataPtr = connection;

;	BX ← ←connection
POP BX
PUSH BX

;	←dataPtr ← BX
MOV [BP-6],BX

;     connection = dataPtr->next; }; /* endloop */

;	DI ← ←dataPtr
MOV DI,[BP-6]
MOV BX,[DI]

;	←connection ← BX
POP DX
PUSH BX
JR X91
X92:

;   connection = (struct ConnectionData *) GetFixed(lenConnectionData);
MOV BX,8
CALL ←GetFixed

;	←connection ← BX
POP DX
PUSH BX

;   connection->next = 0;

;	BX ← ←connection
POP BX
PUSH BX
MOV WORD PTR [BX],0

;   MoveBlock(&connection->id, id, lenConnectionID);

;	BX ← ←connection
POP BX
PUSH BX
INC BX
INC BX
PUSH BX
MOV BX,4

;	CX ← ←id
MOV CX,[BP+4]
CALL ←MoveBlock
POP DX

;   Move2(&connection->callCt, callCt);

;	BX ← ←connection
POP BX
PUSH BX
ADD BX,0AX
PUSH BX

;	BX ← ←callCt
MOV BX,[BP-2]
POP CX
CALL ←Move2

;   DoubleDiff(&connection->callCt, one);

;	BX ← ←connection
POP BX
PUSH BX
ADD BX,0AX
PUSH BX
LEA BX,←one
POP CX
CALL ←DoubleDiff

;   connection->conv = conv;

;	BX ← ←connection
POP BX
PUSH BX

;	CX ← ←conv
MOV CX,[BP-4]
MOV [BX+14],CX

;   dataPtr->next = connection;  Block(); };

;	BX ← ←dataPtr
MOV BX,[BP-6]

;	CX ← ←connection
POP CX
PUSH CX
MOV [BX],CX
CALL ←Block
MOV SP,BP
POP BP
RET;

;  SetupResponse(header) struct Header *header; {
←SetupResponse:
PUSH BP
MOV BP,SP
PUSH BX

;   header->destHost = header->srceHost;

;	BX ← ←header
POP BX
PUSH BX

;	CX ← ←header
POP CX
PUSH CX
MOV DI,CX
MOV CX,[DI+14]
MOV [BX+8],CX

;   header->destSoc.LS = rpcSocket;

;	BX ← ←header
POP BX
PUSH BX
MOV BYTE PTR [BX+13],01EX

;   header->destPSB = header->srcePSB;

;	BX ← ←header
POP BX
PUSH BX

;	CX ← ←header
POP CX
PUSH CX
MOV DI,CX
MOV CX,[DI+6]
MOV [BX+4],CX

;   header->callSpec.outcome = result; Block(); };

;	BX ← ←header
POP BX
PUSH BX
MOV WORD PTR [BX+32],0
CALL ←Block
MOV SP,BP
POP BP
RET;

; StreamInitialize() {
←StreamInitialize:
PUSH BP
MOV BP,SP

;   one[0] = swapped1;
MOV ←one,0100X

;   lastCallDest = GetFixed(maxPSB+1);
MOV BX,010X
CALL ←GetFixed
MOV ←lastCallDest,BX

;   connections = (struct ConnectionData **) GetFixed(128);
MOV BX,080X
CALL ←GetFixed
MOV ←connections,BX

;   MisusedConversation = CODE(); };
CALL ←CODE
MOV ←MisusedConversation,BX
MOV SP,BP
POP BP
RET;

; StreamRestart() {ForgetConnections()};
←StreamRestart:
PUSH BP
MOV BP,SP
CALL ←ForgetConnections
MOV SP,BP
POP BP
RET;

; Externals Declared Here
PUBLIC ←MisusedConversation
PUBLIC ←connections
PUBLIC ←callees
PUBLIC ←lastCallDest
PUBLIC ←StartCall
PUBLIC ←Call
PUBLIC ←SetupResponse
PUBLIC ←GenerateIdlerResponse
PUBLIC ←ForgetConnections
PUBLIC ←ServerMain
PUBLIC ←StreamInitialize
PUBLIC ←StreamRestart

C←CODE ENDS

; Number of Bytes of Code = 096EX, (2414)