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

$INCLUDE(8086LIB.D)

$INCLUDE(dislc.DEC)

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

; #include <Lark.h>

; struct ccb {

;   char cmda;

;   char *addra;

;   char counta;

;   char stata;

;   };

; extern int DoubleEq();

; extern int ReadTmr();

; extern int currentHost;

; extern int localHost;

; extern int localNet;

; extern int lenPup;

; extern struct SocketEntry pupSockets[1 /*maxPupSockets*/];

; static struct SocketEntry *lastSocket;

; static struct ccb rccb[numRBp1];

; static struct PBI *rpbi[numRB];

; static int nextrx;

; static int lastrx;

; static struct ccb txccb;

; static struct PBI *txPBI;

; static int rBufCount;  /* byte count of receive buffers */

; static int txtmr[1];

; static int rxtmr[1];

; static struct Queue outQ[1];  /* ether output queue */

; static int etherStack[40];  /* stack space */

; static int slcri;     /* interrupt counters */

; static int slcti;

; static int slcrp;     /* packet counters */

; static int slctp;

; static int slrsmash;  /* SLC resets due to timeout */

; static int sltsmash;

; static int noBuffer;  /* lost packets due to buffer shortage */

; static int nonPup;    /* non Pup packets received (and discarded) */

; static EtherPr()
←EtherPr:
PUSH BP
MOV BP,SP

;   {

;   for (;;) {
X1:

;     Block();
CALL ←Block

;     if (TmrExp(rxtmr)) {
LEA BX,←rxtmr
CALL ←TmrExp
OR BX,BX
JZ X3

;       slrsmash += 1;
INC ←slrsmash

;       IWDC();
CALL ←IWDC

;       CSLCReset();  /* violent ! */
CALL ←CSLCReset

;       DWDC();
CALL ←DWDC

;       };
X3:

;     Block();
CALL ←Block

;     if (TmrExp(txtmr)) {
LEA BX,←txtmr
CALL ←TmrExp
OR BX,BX
JZ X4

;       IWDC();
CALL ←IWDC

;       if (txPBI && TmrExp(txtmr)) {
MOV BX,←txPBI
OR BX,BX
JZ X6
LEA BX,←txtmr
CALL ←TmrExp
OR BX,BX
X6:
JZ X5

;         sltsmash += 1;
INC ←sltsmash

;         CSLCReset();  /* violent ! */
CALL ←CSLCReset

;         };
X5:

;       DWDC();
CALL ←DWDC

;       };
X4:

;     };
JR X1
X2:

;   };
MOV SP,BP
POP BP
RET;

; static int *teei;

; static mySLTInt()
←mySLTInt:
PUSH BP
MOV BP,SP

;   {

;   OutByte(0x0024, 0x000e);
MOV BX,0EX
MOV CX,024X
CALL ←OutByte

;   if (txPBI) {
MOV BX,←txPBI
OR BX,BX
JZ X7

;     if (txccb.stata & 0x80) {   /* why? */
MOV AX,WORD PTR ←txccb+4
AND AL,080X
OR AL,AL
JZ X8

;       teei = ((int *) txPBI->pup) - 1;  /* encap->type */
MOV BX,←txPBI
MOV CX,[BX+6]
DEC CX
DEC CX
MOV ←teei,CX

;       *teei = ReadTmr();  /* tx timestamp */
CALL ←ReadTmr
MOV CX,BX
MOV BX,←teei
MOV [BX],CX

;       Enqueue(txPBI->queue, txPBI);
MOV BX,←txPBI
MOV CX,[BX+2]
MOV BX,←txPBI
CALL ←Enqueue

;       txPBI = 0;
MOV WORD PTR ←txPBI,0

;       Txpkt();
CALL ←Txpkt

;       };
X8:

;     };
X7:

;   slcti += 1;
INC ←slcti

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

;   };

; static struct ccb *rxccb;

; static struct PBI *ripbi;

; static struct Pup *riPup;

; static struct EtherEncapsulation *ee;

; static mySLRInt()
←mySLRInt:
PUSH BP
MOV BP,SP

;   {

;   OutByte(0x0020, 0x0009);  /* clear MM interrupt */
MOV BX,9
MOV CX,020X
CALL ←OutByte

;   for (;;) {
X9:

;     rxccb = &rccb[nextrx];
MOV BX,←nextrx
LEA CX,←rccb
MOV DX,BX
SAL BX
SAL BX
ADD BX,DX
ADD BX,CX
MOV ←rxccb,BX

;     if ((rxccb->stata & 0x80) == 0) break;
MOV BX,←rxccb
MOV AL,[BX+4]
AND AL,080X
OR AL,AL
JNZ X11
JR X10
X11:

;     ripbi = rpbi[nextrx];
MOV BX,←nextrx
LEA CX,←rpbi
SAL BX
ADD BX,CX
MOV CX,[BX]
MOV ←ripbi,CX

;     riPup = ripbi->pup;
MOV BX,←ripbi
MOV CX,[BX+6]
MOV ←riPup,CX

;     if (rxccb->stata == 0x88) {
MOV BX,←rxccb
MOV AL,[BX+4]
CMP AL,088X
JNZ X12

;       ee = (struct EtherEncapsulation *) (((int) riPup) - 4);
MOV BX,←riPup
ADD BX,0FFFCX
MOV ←ee,BX

;       if (ee->type == typePup) {
MOV BX,←ee
MOV CX,[BX+2]
MOV BX,CX
CMP BX,2
JNZ X13

;         ee->type = ReadTmr(); /* arrival timestamp */
MOV BX,←ee
PUSH BX
CALL ←ReadTmr
MOV CX,BX
POP BX
MOV [BX+2],CX

;         IntLev1(); /* may change ripbi, invalidates riPup */
CALL ←IntLev1

;         rpbi[nextrx] = ripbi;
MOV BX,←nextrx
LEA CX,←rpbi
SAL BX
ADD BX,CX
MOV CX,←ripbi
MOV [BX],CX

;         };

;       else nonPup += 1;
JR X14
X13:
INC ←nonPup
X14:

;       };
X12:

;     rxccb->cmda = 0;
MOV BX,←rxccb
MOV BYTE PTR [BX],0

;     rxccb->stata = 0;
JR $+5
X10:
JMP X15
MOV BX,←rxccb
MOV BYTE PTR [BX+4],0

;     rxccb->counta = rBufCount;
MOV BX,←rxccb
MOV AX,←rBufCount
MOV [BX+3],AL

;     rxccb->addra = ((char *) ripbi->pup) - 4
MOV BX,←rxccb
MOV CX,←ripbi
MOV DI,CX
MOV CX,[DI+6]
ADD CX,0FFFCX
MOV [BX+1],CX

;     rccb[lastrx].cmda = 4;
MOV BX,←lastrx
LEA CX,←rccb
MOV DX,BX
SAL BX
SAL BX
ADD BX,DX
ADD BX,CX
MOV BYTE PTR [BX],4

;     lastrx = nextrx;
MOV BX,←nextrx
MOV ←lastrx,BX

;     nextrx += 1;
INC ←nextrx

;     if (nextrx == numRB) nextrx = 0;
MOV BX,←nextrx
CMP BX,3
JNZ X16
MOV ←nextrx,0
X16:

;     };
JMP X9
X15:

;   SetTmr(16000, rxtmr);
LEA BX,←rxtmr
MOV CX,03E80X
CALL ←SetTmr

;   if ((slrstat() & 0x000c) == 0) SLRReset();
CALL ←slrstat
AND BX,0CX
OR BX,BX
JNZ X17
CALL ←SLRReset
X17:

;   slcri += 1;
INC ←slcri

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

;   };

; static struct PBI *npbi;

; static int il1temp, il1i;

; static int dNet, dHost;

; static struct PupSocket *dSocket;

; static struct SocketEntry *socketI;

; IntLev1()
←IntLev1:
PUSH BP
MOV BP,SP

;   {

;   slcrp += 1;
INC ←slcrp

;   if (riPup->sPort.host == 0) goto BcastSource;
MOV BX,←riPup
MOV AL,[BX+15]
OR AL,AL
JNZ X18
JMP ←BcastSource
X18:

;   if ((dNet = riPup->dPort.net) == 0) goto ZeroDNet;
MOV BX,←riPup
MOV AL,[BX+8]
XOR AH,AH
MOV ←dNet,AX
OR AX,AX
JNZ X19
JMP ←ZeroDNet
X19:

;   if (dNet != localNet) {
MOV BX,←localNet
MOV CX,←dNet
CMP CX,BX
JZ X20

;     if (!localNet) SetLocalNet(dNet);
MOV BX,←localNet
OR BX,BX
JNZ X21
MOV BX,←dNet
CALL ←SetLocalNet

;     else goto Misaddressed;
JR X22
X21:
JMP ←Misaddressed
X22:

;     };
X20:

;   if ((dHost = riPup->dPort.host) == currentHost) goto DHostOK;
MOV BX,←riPup
MOV AL,[BX+9]
XOR AH,AH
MOV ←dHost,AX
MOV BX,←currentHost
CMP AX,BX
JNZ X23
JMP ←DHostOK
X23:

;   if (dHost == localHost) goto DHostOK;
MOV BX,←localHost
MOV CX,←dHost
CMP CX,BX
JNZ X24
JMP ←DHostOK
X24:

;   if (dHost == 0) goto DHostOK;
MOV BX,←dHost
OR BX,BX
JNZ X25
JMP ←DHostOK
X25:

;   goto BadHost;
JMP ←BadHost
←DHostOK:

;   DHostOK:

;   dSocket = &riPup->dPort.socket;
MOV BX,←riPup
ADD BX,0AX
MOV ←dSocket,BX

;   for (socketI = pupSockets; socketI <= lastSocket; socketI += 1) {
LEA BX,←pupSockets
MOV ←socketI,BX
X28:
MOV BX,←lastSocket
MOV CX,←socketI
CMP CX,BX
JA X27
JR X26
X29:
ADD ←socketI,0AX
JR X28
X26:

;     if (DoubleEq(&socketI->port.socket, dSocket)) {
MOV BX,←socketI
INC BX
INC BX
PUSH BX
MOV BX,←dSocket
POP CX
CALL ←DoubleEq
OR BX,BX
JZ X30

;       il1temp = (int) socketI->PortProc;
MOV BX,←socketI
MOV CX,[BX+6]
MOV ←il1temp,CX

;       ripbi->clientWord = il1temp;
MOV BX,←ripbi
MOV CX,←il1temp
MOV [BX+4],CX

;       if ((npbi = MaybeGetPBI(0)) != 0) {
XOR BX,BX
CALL ←MaybeGetPBI
MOV ←npbi,BX
OR BX,BX
JZ X31

;         Enqueue(socketI->q, ripbi)
MOV BX,←socketI
MOV CX,[BX+8]
MOV BX,←ripbi
CALL ←Enqueue

;         ripbi = npbi;
MOV BX,←npbi
MOV ←ripbi,BX

;         };

;       else noBuffer += 1;
JR X32
X31:
INC ←noBuffer
X32:

;       goto FoundIt;
JMP ←FoundIt

;       };
X30:

;     };
JR X29
X27:
←Misaddressed:

;   Misaddressed:
←BcastSource:

;   BcastSource:
←ZeroDNet:

;   ZeroDNet:
←BadHost:

;   BadHost:
←FoundIt:

;   FoundIt:

;   };
MOV SP,BP
POP BP
RET;

; InitEther(ctxQ, x)
←InitEther:

;   struct Queue *ctxQ;

;   int x;
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX

;   {

;   int myc;
PUSH DX

;   txPBI = 0;
MOV WORD PTR ←txPBI,0

;   nonPup = noBuffer = slcri = slcti = slrsmash = sltsmash = 0;
MOV ←sltsmash,0
MOV ←slrsmash,0
MOV ←slcti,0
MOV ←slcri,0
MOV ←noBuffer,0
MOV ←nonPup,0

;   lastSocket = pupSockets + maxPupSockets;
LEA BX,←pupSockets+064X
MOV ←lastSocket,BX

;   rBufCount = (lenPup + lenEtherEncapsulation) << 1;
MOV BX,←lenPup
INC BX
INC BX
SAL BX
MOV ←rBufCount,BX

;   if (rBufCount > 256) CallSwat(ecPup1 + 19);
MOV BX,←rBufCount
CMP BX,0100X
JLE X33
MOV BX,04013X
CALL ←CallSwat
X33:

;   rBufCount = (-rBufCount) & 0x00ff;
MOV BX,←rBufCount
NEG BX
AND BX,0FFX
MOV ←rBufCount,BX

;   myc = InitNContext("EtherPr", etherStack, 50, &EtherPr);
MOV BX,"EtherPr"
PUSH BX
LEA BX,←etherStack
PUSH BX
MOV BX,OFFSET ←EtherPr
MOV CX,032X
CALL ←InitNContext
ADD SP,4

;	←myc ← BX
POP DX
PUSH BX

;   Enqueue(ctxQ, myc);

;	BX ← ←myc
POP BX
PUSH BX

;	CX ← ←ctxQ
MOV CX,[BP-2]
CALL ←Enqueue

;   InitQueue(outQ);
LEA BX,←outQ
CALL ←InitQueue

;   IWDC();
CALL ←IWDC

;   CSLCReset();
CALL ←CSLCReset

;   DWDC();
CALL ←DWDC

;   EnableInt(&mySLTInt, SLTTyp);
MOV BX,1
MOV CX,OFFSET ←mySLTInt
CALL ←EnableInt

;   EnableInt(&mySLRInt, SLRTyp);
XOR BX,BX
MOV CX,OFFSET ←mySLRInt
CALL ←EnableInt

;   };
MOV SP,BP
POP BP
RET;

; NewHost()
←NewHost:
PUSH BP
MOV BP,SP

;   {

;   IWDC();
CALL ←IWDC

;   CSLCReset();
CALL ←CSLCReset

;   DWDC();
CALL ←DWDC

;   };
MOV SP,BP
POP BP
RET;

; static CSLCReset()
←CSLCReset:
PUSH BP
MOV BP,SP

;   {

;   SLCInit(currentHost);
MOV BX,←currentHost
CALL ←SLCInit

;   SLRPBISetup();
CALL ←SLRPBISetup

;   SLRReset();
CALL ←SLRReset

;   OutByte(0x0024, 0x0088);	/* enable SLT IO interrupts */
MOV BX,088X
MOV CX,024X
CALL ←OutByte

;   if (txPBI) {
MOV BX,←txPBI
OR BX,BX
JZ X34

;     Enqueue(txPBI->queue, txPBI);
MOV BX,←txPBI
MOV CX,[BX+2]
MOV BX,←txPBI
CALL ←Enqueue

;     txPBI = 0;
MOV WORD PTR ←txPBI,0

;     IWDC();
CALL ←IWDC

;     Txpkt();
CALL ←Txpkt

;     DWDC();
CALL ←DWDC

;     };
X34:

;   };
MOV SP,BP
POP BP
RET;

; static SLRPBISetup()
←SLRPBISetup:
PUSH BP
MOV BP,SP

;   {

;   int i;

;   for (i=0; i<numRB; i+=1) {
PUSH DX
MOV WORD PTR [BP-2],0
X37:

;	BX ← ←i
POP BX
PUSH BX
CMP BX,3
JGE X36
JR X35
X38:
INC WORD PTR [BP-2]
JR X37
X35:

;     if (rpbi[i] == 0) rpbi[i] = GetPBI(0);

;	BX ← ←i
POP BX
PUSH BX
LEA CX,←rpbi
SAL BX
ADD BX,CX
MOV CX,[BX]
OR CX,CX
JNZ X39

;	BX ← ←i
POP BX
PUSH BX
LEA CX,←rpbi
SAL BX
ADD BX,CX
PUSH BX
XOR BX,BX
CALL ←GetPBI
MOV CX,BX
POP BX
MOV [BX],CX
X39:

;     };
JR X38
X36:

;   };
MOV SP,BP
POP BP
RET;

; static SLRReset()
←SLRReset:
PUSH BP
MOV BP,SP

;   {

;   int i;

;   struct ccb *mccb;
ADD SP,0FFFCX

;   OutByte(0x0020, 0x0048);	/* enable SLR MM interrupts */
MOV BX,048X
MOV CX,020X
CALL ←OutByte

;   mccb = rccb;
LEA BX,←rccb

;	←mccb ← BX
POP DX
PUSH BX

;   for (i=0; i<numRB; i+=1) {
MOV WORD PTR [BP-2],0
X42:

;	BX ← ←i
MOV BX,[BP-2]
CMP BX,3
JGE X41
JR X40
X43:
INC WORD PTR [BP-2]
JR X42
X40:

;     if (rpbi[i] == 0) return;    /* very bad event! */

;	BX ← ←i
MOV BX,[BP-2]
LEA CX,←rpbi
SAL BX
ADD BX,CX
MOV CX,[BX]
OR CX,CX
JNZ X44
MOV SP,BP
POP BP
RET;
X44:

;     mccb->cmda = 0x04;   /* chain */

;	BX ← ←mccb
POP BX
PUSH BX
MOV BYTE PTR [BX],4

;     mccb->addra = rpbi[i]->pup;

;	BX ← ←mccb
POP BX
PUSH BX

;	CX ← ←i
MOV CX,[BP-2]
LEA AX,←rpbi
SAL CX
ADD CX,AX
MOV DI,CX
MOV CX,[DI]
MOV DI,CX
MOV CX,[DI+6]
MOV [BX+1],CX

;     mccb->addra = mccb->addra - 4;

;	BX ← ←mccb
POP BX
PUSH BX

;	CX ← ←mccb
POP CX
PUSH CX
MOV DI,CX
MOV CX,[DI+1]
ADD CX,0FFFCX
MOV [BX+1],CX

;     mccb->counta = rBufCount;

;	BX ← ←mccb
POP BX
PUSH BX
MOV AX,←rBufCount
MOV [BX+3],AL

;     mccb->stata = 0;

;	BX ← ←mccb
POP BX
PUSH BX
MOV BYTE PTR [BX+4],0

;     mccb += 1;
ADD WORD PTR [BP-4],5

;     };
JR X43
X41:

;   mccb->cmda = 0x00f1;   /* nop plus indirect */

;	BX ← ←mccb
POP BX
PUSH BX
MOV BYTE PTR [BX],0F1X

;   mccb->addra = rccb;

;	BX ← ←mccb
POP BX
PUSH BX
LEA CX,←rccb
MOV [BX+1],CX

;   mccb->counta = rBufCount;

;	BX ← ←mccb
POP BX
PUSH BX
MOV AX,←rBufCount
MOV [BX+3],AL

;   mccb->stata = 0;

;	BX ← ←mccb
POP BX
PUSH BX
MOV BYTE PTR [BX+4],0

;   rccb[numRB-1].cmda = 0;  /* not chained! */
MOV ←rccb+0AX,0

;   nextrx = 0;
MOV ←nextrx,0

;   lastrx = numRB-1;
MOV ←lastrx,2

;   SetTmr(20000, rxtmr);
LEA BX,←rxtmr
MOV CX,04E20X
CALL ←SetTmr

;   SLRStart(rccb);
LEA BX,←rccb
CALL ←SLRStart

;   };
MOV SP,BP
POP BP
RET;

; TransmitPacket(tpbi)
←TransmitPacket:

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

;   {

;   Enqueue(outQ, tpbi);

;	BX ← ←tpbi
POP BX
PUSH BX
LEA CX,←outQ
CALL ←Enqueue

;   IWDC();
CALL ←IWDC

;   Txpkt();
CALL ←Txpkt

;   DWDC();
CALL ←DWDC

;   };
MOV SP,BP
POP BP
RET;

; static Txpkt()
←Txpkt:
PUSH BP
MOV BP,SP

;   {

;   int len;

;   if (txPBI) return;
PUSH DX
MOV BX,←txPBI
OR BX,BX
JZ X45
MOV SP,BP
POP BP
RET;
X45:

;   SetTmr(60, txtmr);
LEA BX,←txtmr
MOV CX,03CX
CALL ←SetTmr

;   txPBI = Dequeue(outQ);
LEA BX,←outQ
CALL ←Dequeue
MOV ←txPBI,BX

;   if (txPBI == 0) return;
MOV BX,←txPBI
OR BX,BX
JNZ X46
MOV SP,BP
POP BP
RET;
X46:

;   len = Swab(txPBI->pup->length);
MOV BX,←txPBI
MOV CX,[BX+6]
MOV DI,CX
MOV BX,[DI]
CALL ←Swab

;	←len ← BX
POP DX
PUSH BX

;   len = (len + 5) & 0x0fffe;

;	BX ← ←len
POP BX
ADD BX,5
AND BX,0FFFEX

;	←len ← BX
PUSH BX

;   if (len >= 256) CallSwat(ecPup1+20);

;	BX ← ←len
POP BX
PUSH BX
CMP BX,0100X
JL X47
MOV BX,04014X
CALL ←CallSwat
X47:

;   txccb.cmda = 0x52;
MOV ←txccb,052X

;   txccb.addra = txPBI->pup;
MOV BX,←txPBI
MOV CX,[BX+6]
MOV WORD PTR ←txccb+1,CX

;   txccb.addra = txccb.addra - 4;
MOV BX,WORD PTR ←txccb+1
ADD BX,0FFFCX
MOV WORD PTR ←txccb+1,BX

;   txccb.counta = len & 0x00ff;

;	BX ← ←len
POP BX
PUSH BX
AND BX,0FFX
MOV ←txccb+3,BL

;   txccb.stata = 0;
MOV ←txccb+4,0

;   SLTStart(&txccb);
LEA BX,←txccb
CALL ←SLTStart

;   slctp += 1;
INC ←slctp

;   };
MOV SP,BP
POP BP
RET;

; Externals Declared Here
PUBLIC ←IntLev1
PUBLIC ←InitEther
PUBLIC ←NewHost
PUBLIC ←TransmitPacket

C←CODE ENDS

; Number of Bytes of Code = 0557X, (1367)