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

$INCLUDE(8086LIB.D)

$INCLUDE(dslc.DEC)

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

; #include <Lark.h>

; struct ccb {

;   char cmda;

;   char *addra;

;   char counta;

;   char stata;

;   };

; extern InByte();

; extern Swab();

; extern CallSwat();

; extern InitNContext();

; extern Block();

; extern Enqueue();

; extern Dequeue();

; extern InitQueue();

; extern int DoubleEq();

; extern SetTmr();

; extern TmrExp();

; extern SLCInit();

; extern SLTStart();

; extern SLRStart();

; extern GetPBI();

; extern MaybeGetPBI();

; extern SetLocalNet();

; extern int currentHost;

; extern int localHost;

; extern int localNet;

; extern int lenPup;

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

; static struct ccb rxccb;

; static struct PBI *rxPBI;

; static struct ccb txccb;

; static struct PBI *txPBI;

; static int rBufCount;

; static int txtmr[1];

; static int rxtmr[1];

; static struct Queue outQ[1];

; static int etherStack[200];

; 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 EtherPr()
←EtherPr:
 CALL StkChk
PUSH BP
MOV BP,SP

;   {

;   struct EtherEncapsulation *ee;

;   int temp;

;   for (;;) {
ADD SP,0FFFCX
X1:

;     Block();
CALL ←Block

;     if (rxccb.stata & 0x80) {
MOV AX,WORD PTR ←rxccb+4
AND AL,080X
OR AL,AL
JZ X3

;       if (rxccb.stata == 0x88) {
MOV AX,WORD PTR ←rxccb+4
CMP AL,088X
JNZ X4

;         temp = (int) rxPBI->pup;
MOV BX,←rxPBI
MOV CX,[BX+6]

;	←temp ← CX
POP DX
PUSH CX

;         temp = temp - 4;

;	BX ← ←temp
POP BX
ADD BX,0FFFCX

;	←temp ← BX
PUSH BX

;         ee = (struct EtherEncapsulation *) temp;

;	BX ← ←temp
POP BX
PUSH BX

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

;         if (ee->type == 2) {  /* Swabbed typePup */

;	BX ← ←ee
MOV BX,[BP-2]
MOV CX,[BX+2]
MOV BX,CX
CMP BX,2
JNZ X5

;           rxPBI = IntLev1(rxPBI);
MOV BX,←rxPBI
CALL ←IntLev1
MOV ←rxPBI,BX

;           };
X5:

;         };
X4:

;       StartRx();
CALL ←StartRx

;       };
X3:

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

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

;       slrsmash += 1;
INC ←slrsmash

;       };
X6:

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

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

;       sltsmash += 1;
INC ←sltsmash

;       };
X7:

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

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

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

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

;         if (txPBI) Txpkt(txPBI);
MOV BX,←txPBI
OR BX,BX
JZ X11
MOV BX,←txPBI
CALL ←Txpkt
X11:

;         };
X10:

;       };
X9:

;     };
JMP X1
X2:

;   };
MOV SP,BP
POP BP
RET;

; struct PBI *IntLev1(pbi)
←IntLev1:

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

;   {

;   struct Pup *pup;

;   struct PBI *npbi;

;   int dNet, dHost, i, temp;
ADD SP,0FFF4X

;   slcrp += 1;
INC ←slcrp

;   pup = pbi->pup;

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

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

;   if (pup->sPort.host == 0) goto BcastSource;

;	BX ← ←pup
MOV BX,[BP-4]
MOV AL,[BX+15]
OR AL,AL
JNZ X12
JMP ←BcastSource
X12:

;   if ((dNet = pup->dPort.net) == 0) goto ZeroDNet;

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

;	←dNet ← AX
MOV [BP-8],AX
OR AX,AX
JNZ X13
JMP ←ZeroDNet
X13:

;   if (dNet != localNet) {
MOV BX,←localNet

;	CX ← ←dNet
MOV CX,[BP-8]
CMP CX,BX
JZ X14

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

;	BX ← ←dNet
MOV BX,[BP-8]
CALL ←SetLocalNet

;     else goto Misaddressed;
JR X16
X15:
JMP ←Misaddressed
X16:

;     };
X14:

;   if (((dHost = pup->dPort.host) != 0) && (dHost != currentHost) &&

;   	(dHost != localHost)) goto BadHost;

;	BX ← ←pup
MOV BX,[BP-4]
MOV AL,[BX+9]
XOR AH,AH

;	←dHost ← AX
MOV [BP-10],AX
OR AX,AX
JZ X18
MOV BX,←currentHost

;	CX ← ←dHost
MOV CX,[BP-10]
CMP CX,BX
JZ X19
MOV BX,←localHost

;	CX ← ←dHost
MOV CX,[BP-10]
CMP CX,BX
X19:
X18:
JZ X17
JMP ←BadHost
X17:

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

;	BX ← ←i
MOV BX,[BP-12]
CMP BX,0AX
JG X21
JR X20
X23:
INC WORD PTR [BP-12]
JR X22
X20:

;     if (DoubleEq(&pupSockets[i].port.socket, &pup->dPort.socket)) {

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

;	BX ← ←pup
MOV BX,[BP-4]
ADD BX,0AX
MOV CX,AX
CALL ←DoubleEq
OR BX,BX
JZ X24

;       temp = (int) pupSockets[i].PortProc;

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

;	←temp ← BX
POP DX
PUSH BX

;       pbi->clientWord = temp;

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

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

;       if ((npbi = MaybeGetPBI(0)) != 0) {
XOR BX,BX
CALL ←MaybeGetPBI

;	←npbi ← BX
MOV [BP-6],BX
OR BX,BX
JZ X25

;         Enqueue(pupSockets[i].q, pbi)

;	BX ← ←i
MOV BX,[BP-12]
LEA CX,←pupSockets
MOV AX,0AX
IMUL AX,BX
ADD AX,CX
MOV DI,AX
MOV BX,[DI+8]
PUSH BX

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

;         pbi = npbi;

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

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

;         };

;       else noBuffer += 1;
JR X26
X25:
INC ←noBuffer
X26:

;       goto FoundIt;
JMP ←FoundIt

;       };
X24:

;     };
JR $+5
X21:
JMP X27
JR X23
X27:
←Misaddressed:

;   Misaddressed:
←BcastSource:

;   BcastSource:
←ZeroDNet:

;   ZeroDNet:
←BadHost:

;   BadHost:
←FoundIt:

;   FoundIt:

;     return(pbi);

;	BX ← ←pbi
MOV BX,[BP-2]
MOV SP,BP
POP BP
RET;

;   };

; InitEther(zone, ctxQ, x)
←InitEther:

;   struct ZN *zone;

;   struct Queue *ctxQ;

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

;   {

;   int myc;
PUSH DX

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

;   noBuffer = slrsmash = sltsmash = 0;
MOV ←sltsmash,0
MOV ←slrsmash,0
MOV ←noBuffer,0

;   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 X28
MOV BX,04013X
CALL ←CallSwat
X28:

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

;   myc = InitNContext("EtherPr", etherStack, 200, &EtherPr);
MOV BX,"EtherPr"
PUSH BX
LEA BX,←etherStack
PUSH BX
MOV BX,OFFSET ←EtherPr
MOV CX,0C8X
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

;   SLCReset();
CALL ←SLCReset

;   };
MOV SP,BP
POP BP
RET;

; static SLCReset()
←SLCReset:
 CALL StkChk
PUSH BP
MOV BP,SP

;   {

;   SLCInit(EtherHost());
CALL ←EtherHost
CALL ←SLCInit

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

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

;     if (txPBI = Dequeue(outQ)) Txpkt(txPBI);
LEA BX,←outQ
CALL ←Dequeue
MOV ←txPBI,BX
OR BX,BX
JZ X30
MOV BX,←txPBI
CALL ←Txpkt
X30:

;     };
X29:

;   StartRx();
CALL ←StartRx

;   };
MOV SP,BP
POP BP
RET;

; static StartRx()
←StartRx:
 CALL StkChk
PUSH BP
MOV BP,SP

;   {

;   if (rxPBI == 0) rxPBI = GetPBI(0);
MOV BX,←rxPBI
OR BX,BX
JNZ X31
XOR BX,BX
CALL ←GetPBI
MOV ←rxPBI,BX
X31:

;   rxccb.cmda = 0x00;
MOV ←rxccb,0

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

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

;   rxccb.counta = rBufCount;
MOV AX,←rBufCount
MOV ←rxccb+3,AL

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

;   SetTmr(10000, rxtmr);
LEA BX,←rxtmr
MOV CX,02710X
CALL ←SetTmr

;   SLRStart(&rxccb);
LEA BX,←rxccb
CALL ←SLRStart

;   };
MOV SP,BP
POP BP
RET;

; int EtherHost()
←EtherHost:
 CALL StkChk
PUSH BP
MOV BP,SP

;   {

;   return ((InByte(piob) & 0x003f) + 0x0040);
MOV BX,4
CALL ←InByte
AND BX,03FX
ADD BX,040X
MOV SP,BP
POP BP
RET;

;   };

; TransmitPacket(pbi)
←TransmitPacket:

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

;   {

;   if (txPBI) Enqueue(outQ, pbi);
MOV BX,←txPBI
OR BX,BX
JZ X32

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

;   else Txpkt(pbi);
JR X33
X32:

;	BX ← ←pbi
POP BX
PUSH BX
CALL ←Txpkt
X33:

;   };
MOV SP,BP
POP BP
RET;

; static Txpkt(pbi)
←Txpkt:

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

;   {

;   int len;
PUSH DX

;   txPBI = pbi;

;	BX ← ←pbi
MOV BX,[BP-2]
MOV ←txPBI,BX

;   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
JLE X34
MOV BX,04014X
CALL ←CallSwat
X34:

;   txccb.cmda = 0x50;
MOV ←txccb,050X

;   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

;   SetTmr(2000, txtmr);
LEA BX,←txtmr
MOV CX,07D0X
CALL ←SetTmr

;   slctp += 1;
INC ←slctp

;   };
MOV SP,BP
POP BP
RET;

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

C←CODE ENDS

; Number of Bytes of Code = 0364X, (868)