;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)