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