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

$INCLUDE(8086LIB.D)

$INCLUDE(pupimpl.DEC)

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

; #include <Env.h>

; extern int *GetFixed();

; extern Zero();

; extern MoveBlock();

; extern Enqueue();

; extern int *InitNContext();

; extern Block();

; extern int *Dequeue();

; extern Unqueue();

; extern InitQueue();

; extern EtherHost();

; extern InitEther();

; extern RequestRoute();

; extern CallSwat();

; extern Swab();

; extern MultEq();

; extern ReadTmr();

; extern Call1();

; static struct Queue pbiIQ[1];

; int lenPBI;

; int lenPup;

; int maxPupDataBytes;

; int localNet;  /* 0173: known only 1.5MB network, for now. */

; int localHost;

; int currentHost;

; int maxHops;

; static struct Queue pbiFreeQ[1];

; static int *pupLevel1Ctx;

; struct SocketEntry pupSockets[maxPupSockets+1];

; struct Route routingTable[maxNetworks];

; static int ageNet;

; static struct Route *ageRoute;

; static PupLevel1() {
←PupLevel1:
PUSH BP
MOV BP,SP

;   struct PBI *pbi;

;   for (;;) {
PUSH DX
X1:

;     if ((ReadTmr() & 3) == 0) {
CALL ←ReadTmr
AND BX,3
OR BX,BX
JNZ X3

;       if (ageNet < 0) ageNet = 0;
MOV BX,←ageNet
CMP BX,0
JGE X4
MOV ←ageNet,0
X4:

;       if (ageNet >= maxNetworks) ageNet = 0;
MOV BX,←ageNet
CMP BX,0100X
JL X5
MOV ←ageNet,0
X5:

;       ageRoute = &routingTable[ageNet];
MOV BX,←ageNet
LEA CX,←routingTable
ADD CX,BX
ADD CX,BX
ADD BX,CX
MOV ←ageRoute,BX

;       if (ageRoute->age & 0x0080) ageRoute->age = 0x00ff;
MOV BX,←ageRoute
MOV AL,[BX+2]
AND AL,080X
OR AL,AL
JZ X6
MOV BX,←ageRoute
MOV BYTE PTR [BX+2],0FFX

;       else ageRoute->age += 1;
JR X7
X6:
MOV BX,←ageRoute
INC BYTE PTR [BX+2]
X7:

;       ageNet += 1;
INC ←ageNet

;       };
X3:

;     Block();
CALL ←Block

;     pbi = (struct PBI *) Dequeue(pbiIQ);
LEA BX,←pbiIQ
CALL ←Dequeue

;	←pbi ← BX
POP DX
PUSH BX

;     if (pbi) {

;	BX ← ←pbi
POP BX
PUSH BX
OR BX,BX
JZ X8

;       if (CheckCheckSum(pbi->pup)) Call1(pbi->clientWord, pbi);

;	BX ← ←pbi
POP BX
PUSH BX
MOV CX,[BX+6]
MOV BX,CX
CALL ←CheckCheckSum
OR BX,BX
JZ X9

;	BX ← ←pbi
POP BX
PUSH BX
MOV CX,[BX+4]

;	BX ← ←pbi
POP BX
PUSH BX
CALL ←Call1

;       else ReleasePBI(pbi);
JR X10
X9:

;	BX ← ←pbi
POP BX
PUSH BX
CALL ←ReleasePBI
X10:

;       };
X8:

;     PokeWDTD();
CALL ←PokeWDTD

;     };
JMP X1
X2:

;   };
MOV SP,BP
POP BP
RET;

; SendPup(pbi)
←SendPup:

;   struct PBI *pbi;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   int pdh;

;   int *tmp;

;   struct Pup *pup;

;   struct EtherEncapsulation *enc;
ADD SP,0FFF8X

;   pup = pbi->pup;

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

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

;   pup->transport = 0;

;	BX ← ←pup
MOV BX,[BP-8]
MOV BYTE PTR [BX+2],0

;   pup->data.words[(Swab(pup->length)-pupOvBytes+1)>>1] = -1;

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

;	DI ← ←pup
MOV DI,[BP-8]
MOV BX,[DI]
CALL ←Swab
ADD BX,0FFEAX
INC BX
SHR BX
POP CX
SAL BX
ADD BX,CX
MOV WORD PTR [BX],0FFFFX

;   if ((pdh = RoutePup(pup)) < 0) Enqueue(pbi->queue, pbi);

;	BX ← ←pup
MOV BX,[BP-8]
CALL ←RoutePup

;	←pdh ← BX
MOV [BP-4],BX
CMP BX,0
JGE X11

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

;	BX ← ←pbi
MOV BX,[BP-2]
CALL ←Enqueue

;   else {
JR X12
X11:

;     tmp = ((int *) pup) - lenEtherEncapsulation;

;	BX ← ←pup
MOV BX,[BP-8]
ADD BX,0FFFCX

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

;     enc = (struct EtherEncapsulation *) tmp;

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

;	←enc ← BX
POP DX
PUSH BX

;     enc->src = localHost;

;	BX ← ←enc
POP BX
PUSH BX
MOV AX,←localHost
MOV [BX+1],AL

;     enc->dst = pdh;

;	BX ← ←enc
POP BX
PUSH BX

;	AL ← ←pdh
MOV AL,[BP-4]
MOV [BX],AL

;     enc->type = typePup;

;	BX ← ←enc
POP BX
PUSH BX
MOV WORD PTR [BX+2],2

;     TransmitPacket(pbi);

;	BX ← ←pbi
MOV BX,[BP-2]
CALL ←TransmitPacket

;     };
X12:

;   };
MOV SP,BP
POP BP
RET;

; int WaitUntilSent(pbi)
←WaitUntilSent:

;   struct PBI *pbi;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   int i;
PUSH DX

;   i = ReadTmr();
CALL ←ReadTmr

;	←i ← BX
POP DX
PUSH BX

;   while (Unqueue(pbi->queue, pbi) == 0) {
X13:

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

;	BX ← ←pbi
MOV BX,[BP-2]
CALL ←Unqueue
OR BX,BX
JNZ X14

;     Block();
CALL ←Block

;     };
JR X13
X14:

;   return(ReadTmr()-i);
CALL ←ReadTmr

;	CX ← ←i
POP CX
PUSH CX
SUB BX,CX
MOV SP,BP
POP BP
RET;

;   };

; static int RoutePup(pup)
←RoutePup:

;   struct Pup *pup;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   int net;

;   struct Route *route;

;   if ((net = pup->dPort.net) == localNet) return pup->dPort.host;
ADD SP,0FFFCX

;	BX ← ←pup
MOV BX,[BP-2]
MOV AL,[BX+8]
XOR AH,AH

;	←net ← AX
MOV [BP-4],AX
MOV BX,←localNet
CMP AX,BX
JNZ X15

;	BX ← ←pup
MOV BX,[BP-2]
MOV AL,[BX+9]
XOR AH,AH
MOV BX,AX
MOV SP,BP
POP BP
RET;
X15:

;   route = &routingTable[net & 0x00ff];

;	BX ← ←net
MOV BX,[BP-4]
AND BX,0FFX
LEA CX,←routingTable
ADD CX,BX
ADD CX,BX
ADD BX,CX

;	←route ← BX
POP DX
PUSH BX

;   if (route->hops < 100) return(route->host);

;	BX ← ←route
POP BX
PUSH BX
MOV AL,[BX+1]
CMP AL,064X
JGE X16

;	DI ← ←route
POP DI
PUSH DI
MOV AL,[DI]
XOR AH,AH
MOV BX,AX
MOV SP,BP
POP BP
RET;
X16:

;   RequestRoute(net);

;	BX ← ←net
MOV BX,[BP-4]
CALL ←RequestRoute

;   return(-1);
MOV BX,0FFFFX
MOV SP,BP
POP BP
RET;

;   };

; struct Route *LookupNet(net)
←LookupNet:

;   int net;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   struct Route *route;
PUSH DX

;   route = &routingTable[net & 0x00ff];

;	BX ← ←net
MOV BX,[BP-2]
AND BX,0FFX
LEA CX,←routingTable
ADD CX,BX
ADD CX,BX
ADD BX,CX

;	←route ← BX
POP DX
PUSH BX

;   if (route->hops < 100) return(route);

;	BX ← ←route
POP BX
PUSH BX
MOV AL,[BX+1]
CMP AL,064X
JGE X17

;	BX ← ←route
POP BX
PUSH BX
MOV SP,BP
POP BP
RET;

;   else return(0);
X17:
XOR BX,BX
MOV SP,BP
POP BP
RET;

;   };

; struct WhereAmI {

;   int hops, index;

;   };

; GenerateNets(handle)
←GenerateNets:

;   struct WhereAmI *handle;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   handle->index = -1;

;	BX ← ←handle
POP BX
PUSH BX
MOV WORD PTR [BX+2],0FFFFX

;   handle->hops = 0;

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

;   };
MOV SP,BP
POP BP
RET;

; int NextNet(handle)
←NextNet:

;   struct WhereAmI *handle;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   if (handle->hops == 0) {

;	DI ← ←handle
POP DI
PUSH DI
MOV BX,[DI]
OR BX,BX
JNZ X18

;     handle->index = -1;

;	BX ← ←handle
POP BX
PUSH BX
MOV WORD PTR [BX+2],0FFFFX

;     handle->hops = 1;

;	BX ← ←handle
POP BX
PUSH BX
MOV WORD PTR [BX],1

;     return(localNet);
MOV BX,←localNet
MOV SP,BP
POP BP
RET;

;     };
X18:

;   for (;;) {
X19:

;     handle->index += 1;

;	BX ← ←handle
POP BX
PUSH BX
INC WORD PTR [BX+2]

;     if (handle->index >= maxNetworks) {

;	BX ← ←handle
POP BX
PUSH BX
MOV CX,[BX+2]
MOV BX,CX
CMP BX,0100X
JL X21

;       handle->index = 0;

;	BX ← ←handle
POP BX
PUSH BX
MOV WORD PTR [BX+2],0

;       handle->hops += 1;

;	BX ← ←handle
POP BX
PUSH BX
INC WORD PTR [BX]

;       if (handle->hops >= maxHops) return(0);

;	DI ← ←handle
POP DI
PUSH DI
MOV BX,[DI]
MOV CX,←maxHops
CMP BX,CX
JL X22
XOR BX,BX
MOV SP,BP
POP BP
RET;
X22:

;       };
X21:

;     if (routingTable[handle->index].hops == handle->hops) return(handle->index);

;	BX ← ←handle
POP BX
PUSH BX
MOV CX,[BX+2]
LEA BX,←routingTable
ADD BX,CX
ADD BX,CX
ADD BX,CX
MOV AL,[BX+1]

;	DI ← ←handle
POP DI
PUSH DI
MOV BX,[DI]
XOR AH,AH
CMP AX,BX
JNZ X23

;	BX ← ←handle
POP BX
PUSH BX
MOV CX,[BX+2]
MOV BX,CX
MOV SP,BP
POP BP
RET;
X23:

;     };
JR X19
X20:

;   };
MOV SP,BP
POP BP
RET;

; struct PBI *GetPBI(soc)
←GetPBI:

;   int soc;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   int pbiTimer;

;   struct PBI *pbi;
ADD SP,0FFFCX

;   pbi = (struct PBI *) MaybeGetPBI(soc);

;	BX ← ←soc
MOV BX,[BP-2]
CALL ←MaybeGetPBI

;	←pbi ← BX
POP DX
PUSH BX

;   if (pbi != 0) goto gotOne;

;	BX ← ←pbi
POP BX
PUSH BX
OR BX,BX
JZ X24
JMP ←gotOne
X24:

;   SetTmr(2000, &pbiTimer);
;&←pbiTimer
LEA BX,[BP-4]
MOV CX,07D0X
CALL ←SetTmr

;   for (;;) {
X25:

;     Block();
CALL ←Block

;     pbi = (struct PBI *) MaybeGetPBI(soc);

;	BX ← ←soc
MOV BX,[BP-2]
CALL ←MaybeGetPBI

;	←pbi ← BX
POP DX
PUSH BX

;     if (pbi != 0) goto gotOne;

;	BX ← ←pbi
POP BX
PUSH BX
OR BX,BX
JZ X27
JMP ←gotOne
X27:

;     if (TmrExp(&pbiTimer)) CallSwat(ecPup1+1); 
;&←pbiTimer
LEA BX,[BP-4]
CALL ←TmrExp
OR BX,BX
JZ X28
MOV BX,04001X
CALL ←CallSwat
X28:

;     };
JR X25
X26:
←gotOne:

;   gotOne:

;   pbi->clientWord = ReturnLoc(MyFrame());

;	BX ← ←pbi
POP BX
PUSH BX
PUSH BX
CALL ←MyFrame
CALL ←ReturnLoc
MOV CX,BX
POP BX
MOV [BX+4],CX

;   return (pbi);

;	BX ← ←pbi
POP BX
PUSH BX
MOV SP,BP
POP BP
RET;

;   };

; struct PBI *MaybeGetPBI(soc)
←MaybeGetPBI:

;   int soc;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   struct PBI *pbi;
PUSH DX

;   pbi = (struct PBI *) Dequeue(pbiFreeQ);
LEA BX,←pbiFreeQ
CALL ←Dequeue

;	←pbi ← BX
POP DX
PUSH BX

;   if (pbi != 0) { 

;	BX ← ←pbi
POP BX
PUSH BX
OR BX,BX
JZ X29

;     pbi->queue = pbiFreeQ;

;	BX ← ←pbi
POP BX
PUSH BX
LEA CX,←pbiFreeQ
MOV [BX+2],CX

;     Zero(pbi->pup, 10);

;	BX ← ←pbi
POP BX
PUSH BX
MOV CX,[BX+6]
MOV BX,0AX
CALL ←Zero

;     };
X29:

;   return (pbi);

;	BX ← ←pbi
POP BX
PUSH BX
MOV SP,BP
POP BP
RET;

;   };

; ReleasePBI(pbi)
←ReleasePBI:

;   struct PBI *pbi;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   Enqueue(pbiFreeQ, pbi);

;	BX ← ←pbi
POP BX
PUSH BX
LEA CX,←pbiFreeQ
CALL ←Enqueue

;   };
MOV SP,BP
POP BP
RET;

; AppendStringToPup(pbi, firstByte, string)
←AppendStringToPup:

;   struct PBI *pbi;

;   int firstByte;

;   struct ShortSTRING *string;
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX

;   {

;   int i;

;   struct Pup *pup;
ADD SP,0FFFCX

;   pup = pbi->pup;

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

;	←pup ← CX
POP DX
PUSH CX

;   for (i = 0;i < string->length; ++i) pup->data.bytes[firstByte+i] = string->text[i];
MOV WORD PTR [BP-6],0
X32:

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

;	CX ← ←i
MOV CX,[BP-6]
CMP CX,BX
JGE X31
JR X30
X33:
INC WORD PTR [BP-6]
JR X32
X30:

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

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

;	AX ← ←firstByte
MOV AX,[BP-2]
ADD AX,CX
ADD BX,AX

;	CX ← ←string
MOV CX,[BP-4]
ADD CX,4

;	AX ← ←i
MOV AX,[BP-6]
ADD AX,CX
MOV DI,AX
MOV AL,[DI]
MOV [BX],AL
JR X33
X31:

;   pup->length = Swab(pupOvBytes + firstByte + string->length);

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

;	CX ← ←firstByte
MOV CX,[BP-2]
ADD CX,BX
ADD CX,016X
MOV BX,CX
CALL ←Swab
MOV CX,BX

;	BX ← ←pup
POP BX
PUSH BX
MOV [BX],CX

;   };
MOV SP,BP
POP BP
RET;

; int GetPupHost()
←GetPupHost:
PUSH BP
MOV BP,SP

;   {

;   return ((EtherHost()<<8) + localNet);
CALL ←EtherHost
MOV CX,8
SAL BX,CX
MOV CX,←localNet
ADD BX,CX
MOV SP,BP
POP BP
RET;

;   };

; InitPupLevel1(pctxQ, numPBI, pupDataBytes) 
←InitPupLevel1:

;   struct Queue *pctxQ;

;   int numPBI, pupDataBytes;
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX

;   {

;   int i, pbiAlloc;

;   int len;

;   struct PBI *pbi;

;   struct EtherEncapsulation *enc;

;   struct Pup *pup;
ADD SP,0FFF4X

;   maxHops = 2;
MOV ←maxHops,2

;   if (pupDataBytes==0) pupDataBytes = defaultPupDataBytes;

;	BX ← ←pupDataBytes
MOV BX,[BP-4]
OR BX,BX
JNZ X34
MOV WORD PTR [BP-4],0E6X
X34:

;   maxPupDataBytes = pupDataBytes;

;	BX ← ←pupDataBytes
MOV BX,[BP-4]
MOV ←maxPupDataBytes,BX

;   lenPup = (pupOvBytes+pupDataBytes)/2;

;	BX ← ←pupDataBytes
MOV BX,[BP-4]
ADD BX,016X
SAR BX
MOV ←lenPup,BX

;   lenPBI = lenPBIOverhead;
MOV ←lenPBI,4

;   InitQueue(pbiIQ);  /* level 1 raw pup input queue */
LEA BX,←pbiIQ
CALL ←InitQueue

;   InitQueue(pbiFreeQ);  /* empty pbi queue */
LEA BX,←pbiFreeQ
CALL ←InitQueue

;   Zero(pupSockets, ((maxPupSockets+1)*lenSocketEntry));
MOV BX,037X
LEA CX,←pupSockets
CALL ←Zero

;   len = lenPup + lenEtherEncapsulation;
MOV BX,←lenPup
INC BX
INC BX

;	←len ← BX
MOV [BP-10],BX

;   for (i = 1; i <= numPBI; ++i) {
MOV WORD PTR [BP-6],1
X37:

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

;	CX ← ←i
MOV CX,[BP-6]
CMP CX,BX
JG X36
JR X35
X38:
INC WORD PTR [BP-6]
JR X37
X35:

;     enc = (struct EtherEncapsulation *) GetFixed(len);

;	BX ← ←len
MOV BX,[BP-10]
CALL ←GetFixed

;	←enc ← BX
MOV [BP-14],BX

;     Zero(enc, len);

;	BX ← ←len
MOV BX,[BP-10]

;	CX ← ←enc
MOV CX,[BP-14]
CALL ←Zero

;     enc->type = typePup;

;	BX ← ←enc
MOV BX,[BP-14]
MOV WORD PTR [BX+2],2

;     pbi = (struct PBI *) GetFixed(lenPBI);
MOV BX,←lenPBI
CALL ←GetFixed

;	←pbi ← BX
MOV [BP-12],BX

;     Zero(pbi, lenPBI);
MOV BX,←lenPBI

;	CX ← ←pbi
MOV CX,[BP-12]
CALL ←Zero

;     pbi->pup = &enc->pup;

;	BX ← ←pbi
MOV BX,[BP-12]

;	CX ← ←enc
MOV CX,[BP-14]
ADD CX,4
MOV [BX+6],CX

;     ReleasePBI(pbi);

;	BX ← ←pbi
MOV BX,[BP-12]
CALL ←ReleasePBI

;     };
JR X38
X36:

;   ageNet = 0;
MOV ←ageNet,0

;   localNet = 0; /* Router will fill in proper value */
MOV ←localNet,0

;   localHost = currentHost = EtherHost();
CALL ←EtherHost
MOV ←currentHost,BX
MOV ←localHost,BX

;   InitEther(pctxQ, 0);
XOR BX,BX

;	CX ← ←pctxQ
MOV CX,[BP+4]
CALL ←InitEther

;   pupLevel1Ctx = InitNContext("PupLevel1", GetFixed(175), 175, &PupLevel1);
MOV BX,"PupLevel1"
PUSH BX
MOV BX,0AFX
CALL ←GetFixed
PUSH BX
MOV BX,OFFSET ←PupLevel1
MOV CX,0AFX
CALL ←InitNContext
ADD SP,4
MOV ←pupLevel1Ctx,BX

;   Enqueue(pctxQ, pupLevel1Ctx);
MOV BX,←pupLevel1Ctx

;	CX ← ←pctxQ
MOV CX,[BP+4]
CALL ←Enqueue

;   for (i = 0; i < maxNetworks; i += 1) {
MOV WORD PTR [BP-6],0
X41:

;	BX ← ←i
MOV BX,[BP-6]
CMP BX,0100X
JGE X40
JR X39
X42:
INC WORD PTR [BP-6]
JR X41
X39:

;     routingTable[i].host = 0;

;	BX ← ←i
MOV BX,[BP-6]
LEA CX,←routingTable
ADD CX,BX
ADD CX,BX
ADD BX,CX
MOV BYTE PTR [BX],0

;     routingTable[i].hops = 100;

;	BX ← ←i
MOV BX,[BP-6]
LEA CX,←routingTable
ADD CX,BX
ADD CX,BX
ADD BX,CX
MOV BYTE PTR [BX+1],064X

;     routingTable[i].age = 0x00ff;

;	BX ← ←i
MOV BX,[BP-6]
LEA CX,←routingTable
ADD CX,BX
ADD CX,BX
ADD BX,CX
MOV BYTE PTR [BX+2],0FFX

;     };
JR X42
X40:

;   };
MOV SP,BP
POP BP
RET;

; int /*BOOL*/ OpenLevel1Socket(lclPort, PortProc, Q)
←OpenLevel1Socket:

;   struct Port *lclPort;

;   int *PortProc /* PROC[pbi: ->PBI] */;

;   struct Queue *Q;  /* if true, PortProc is a queue pointer */
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX

;   {

;   int i;   

;   struct SocketEntry *entry;

;   if (lclPort->net == 0) lclPort->net = localNet;
ADD SP,0FFFCX

;	DI ← ←lclPort
MOV DI,[BP+4]
MOV AL,[DI]
OR AL,AL
JNZ X43

;	BX ← ←lclPort
MOV BX,[BP+4]
MOV AX,←localNet
MOV [BX],AL
X43:

;   if (lclPort->host == 0) lclPort->host = localHost;

;	BX ← ←lclPort
MOV BX,[BP+4]
MOV AL,[BX+1]
OR AL,AL
JNZ X44

;	BX ← ←lclPort
MOV BX,[BP+4]
MOV AX,←localHost
MOV [BX+1],AL
X44:

;   for (i = 1; i <= maxPupSockets; i += 1) {
MOV WORD PTR [BP-6],1
X47:

;	BX ← ←i
MOV BX,[BP-6]
CMP BX,0AX
JG X46
JR X45
X48:
INC WORD PTR [BP-6]
JR X47
X45:

;     entry = &pupSockets[i];

;	BX ← ←i
MOV BX,[BP-6]
LEA CX,←pupSockets
MOV AX,0AX
IMUL AX,BX
ADD AX,CX

;	←entry ← AX
POP DX
PUSH AX

;     if (MultEq(lclPort, &entry->port, lenPort)) CallSwat(ecPup1+10);

;	BX ← ←lclPort
MOV BX,[BP+4]
PUSH BX
MOV BX,3

;	CX ← ←entry
MOV CX,[BP-8]
CALL ←MultEq
POP DX
OR BX,BX
JZ X49
MOV BX,0400AX
CALL ←CallSwat
X49:

;     if (entry->q == 0) {

;	BX ← ←entry
POP BX
PUSH BX
MOV CX,[BX+8]
OR CX,CX
JNZ X50

;       MoveBlock(&entry->port, lclPort, lenPort);

;	BX ← ←entry
POP BX
PUSH BX
PUSH BX
MOV BX,3

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

;       entry->PortProc = PortProc;

;	BX ← ←entry
POP BX
PUSH BX

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

;       if (Q == 0) Q = pbiIQ;

;	BX ← ←Q
MOV BX,[BP-4]
OR BX,BX
JNZ X51
LEA BX,←pbiIQ

;	←Q ← BX
MOV [BP-4],BX
X51:

;       entry->q = Q;

;	BX ← ←entry
POP BX
PUSH BX

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

;       return(i);

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

;       };
X50:

;     };
JR X48
X46:

;   CallSwat(ecPup1+11);
MOV BX,0400BX
CALL ←CallSwat

;   return(false); /* Table full! */
XOR BX,BX
MOV SP,BP
POP BP
RET;

;   };

; SetLocalNet(net) 
←SetLocalNet:

;   int net;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   int i;
PUSH DX

;   localNet = net;

;	BX ← ←net
MOV BX,[BP-2]
MOV ←localNet,BX

;   for (i = 1; i <= maxPupSockets; ++i) {
MOV WORD PTR [BP-4],1
X54:

;	BX ← ←i
POP BX
PUSH BX
CMP BX,0AX
JG X53
JR X52
X55:
INC WORD PTR [BP-4]
JR X54
X52:

;       pupSockets[i].port.net = net;

;	BX ← ←i
POP BX
PUSH BX
LEA CX,←pupSockets
MOV AX,0AX
IMUL AX,BX
ADD AX,CX
MOV BX,AX

;	AL ← ←net
MOV AL,[BP-2]
MOV [BX],AL

;     };
JR X55
X53:

;   };
MOV SP,BP
POP BP
RET;

; CloseLevel1Socket(soc)
←CloseLevel1Socket:

;   int soc;
PUSH BP
MOV BP,SP
PUSH BX

;   {

;   Zero(&pupSockets[soc], lenSocketEntry);

;	BX ← ←soc
POP BX
PUSH BX
LEA CX,←pupSockets
MOV AX,0AX
IMUL AX,BX
ADD AX,CX
MOV BX,5
MOV CX,AX
CALL ←Zero

;   };
MOV SP,BP
POP BP
RET;

; Externals Declared Here
PUBLIC ←lenPBI
PUBLIC ←lenPup
PUBLIC ←maxPupDataBytes
PUBLIC ←localNet
PUBLIC ←localHost
PUBLIC ←currentHost
PUBLIC ←maxHops
PUBLIC ←pupSockets
PUBLIC ←routingTable
PUBLIC ←ReleasePBI
PUBLIC ←SendPup
PUBLIC ←WaitUntilSent
PUBLIC ←LookupNet
PUBLIC ←GenerateNets
PUBLIC ←NextNet
PUBLIC ←GetPBI
PUBLIC ←MaybeGetPBI
PUBLIC ←AppendStringToPup
PUBLIC ←GetPupHost
PUBLIC ←InitPupLevel1
PUBLIC ←OpenLevel1Socket
PUBLIC ←SetLocalNet
PUBLIC ←CloseLevel1Socket

C←CODE ENDS

; Number of Bytes of Code = 05AEX, (1454)