;Alto->8086 small-c compiler rev 2.0 C←CODE SEGMENT $INCLUDE(8086LIB.D) $INCLUDE(pupmisc.DEC) ASSUME CS:C←CODE, DS:C←DATA ; #include <Ec.h> ; struct Calendar { ; int time[2]; ; int zoneInfo; ; int dstStartDay; ; int dstEndDay; ; int base[2]; /* last ms timer, for updating time */ ; }; ; struct RoutingEntry { ; byte net; /* Target net */ ; byte gateNet; /* A net along the route */ ; byte gateHost; /* A gateway on gateNet */ ; byte hops; /* hops from responding gateway to target net */ ; }; ; extern Move2(); ; extern Timer(); ; extern DoubleDifference(); ; extern DoubleIncrement(); ; extern DoubleUDiv(); ; extern GetRem(); ; extern Marshall(); ; extern CallSwat(); ; extern SetTmr(); ; extern TmrExp(); ; extern Swab(); ; extern InitQueue(); ; extern Block(); ; extern GetPBI(); ; extern ReleasePBI(); ; extern OpenLevel1Socket(); ; extern WaitUntilSent(); ; extern CloseLevel1Socket(); ; extern AppendStringToPup(); ; extern SendPup(); ; static int simpleSent; ; static int simpleRcvd; ; static int calSent; ; static int calRcvd; ; static int routSent; ; static int routRcvd; ; struct Calendar calendar; ; ReadCalendar(c) ←ReadCalendar: ; int c[]; PUSH BP MOV BP,SP PUSH BX ; { ; int t[], newbase[2], ms[2]; ; if (calendar.base[0] == 0) Timer(calendar.base); ADD SP,0FFF6X MOV BX,WORD PTR ←calendar+0AX OR BX,BX JNZ X1 LEA BX,←calendar+0AX CALL ←Timer X1: ; t = calendar.time; LEA BX,←calendar ; ←t ← BX MOV [BP-4],BX ; Timer(newbase); ;&←newbase LEA BX,[BP-8] CALL ←Timer ; Move2(ms, newbase); ;&←newbase LEA BX,[BP-8] ;&←ms LEA CX,[BP-12] CALL ←Move2 ; DoubleDifference(ms, calendar.base); LEA BX,←calendar+0AX ;&←ms LEA CX,[BP-12] CALL ←DoubleDifference ; DoubleIncrement(t, DoubleUDiv(ms, 1000)); MOV BX,03E8X ;&←ms LEA CX,[BP-12] CALL ←DoubleUDiv ; CX ← ←t MOV CX,[BP-4] CALL ←DoubleIncrement ; ms[1] = 0; MOV WORD PTR [BP-10],0 ; ms[0] = GetRem(); CALL ←GetRem ; ←ms ← BX POP DX PUSH BX ; DoubleDifference(newbase, ms); ;&←ms LEA BX,[BP-12] ;&←newbase LEA CX,[BP-8] CALL ←DoubleDifference ; Move2(calendar.base, newbase); ;&←newbase LEA BX,[BP-8] LEA CX,←calendar+0AX CALL ←Move2 ; Move2(c, t); ; BX ← ←t MOV BX,[BP-4] ; CX ← ←c MOV CX,[BP-2] CALL ←Move2 ; }; MOV SP,BP POP BP RET; ; InitCalendar() ←InitCalendar: PUSH BP MOV BP,SP ; { ; struct PBI *pbi; ; struct Pup *p; ; int temp; ADD SP,0FFFAX ; Timer(calendar.base); LEA BX,←calendar+0AX CALL ←Timer ; Timer(calendar.time); /* Default value, if no answer */ LEA BX,←calendar CALL ←Timer ; pbi = SimpleExch(0206, 0207, 4, 3); MOV BX,086X PUSH BX MOV BX,087X PUSH BX MOV BX,3 MOV CX,4 CALL ←SimpleExch ADD SP,4 ; ←pbi ← BX MOV [BP-2],BX ; calSent += simpleSent; MOV BX,←simpleSent ADD ←calSent,BX ; if (pbi == 0) return; /* didn't get an answer, fake it */ ; BX ← ←pbi MOV BX,[BP-2] OR BX,BX JNZ X2 MOV SP,BP POP BP RET; X2: ; calRcvd += 1; INC ←calRcvd ; p = pbi->pup; ; BX ← ←pbi MOV BX,[BP-2] MOV CX,[BX+6] ; ←p ← CX MOV [BP-4],CX ; Marshall(true, calendar.time, p->data.words, 5); MOV BX,0FFFFX PUSH BX LEA BX,←calendar PUSH BX ; BX ← ←p MOV BX,[BP-4] ADD BX,014X PUSH BX MOV BX,5 POP CX CALL ←Marshall ADD SP,4 ; ReleasePBI(pbi); ; BX ← ←pbi MOV BX,[BP-2] CALL ←ReleasePBI ; temp = calendar.time[0]; MOV BX,WORD PTR ←calendar ; ←temp ← BX POP DX PUSH BX ; calendar.time[0] = calendar.time[1]; MOV BX,WORD PTR ←calendar+2 MOV WORD PTR ←calendar,BX ; calendar.time[1] = temp; ; BX ← ←temp POP BX PUSH BX MOV WORD PTR ←calendar+2,BX ; }; MOV SP,BP POP BP RET; ; extern struct SocketEntry pupSockets[1 /*maxPupSockets*/]; ; extern struct Route routingTable[maxNetworks]; ; extern int localNet; ; extern int localHost; ; int routingSoc; ; static RoutePr(pbi) ←RoutePr: ; struct PBI *pbi; PUSH BP MOV BP,SP PUSH BX ; { ; struct Pup *p; ; int numEntries, i; ; struct RoutingEntry entries[]; ; int net, hops; ; struct Route *route; ADD SP,0FFF2X ; p = pbi->pup; ; BX ← ←pbi MOV BX,[BP-2] MOV CX,[BX+6] ; ←p ← CX MOV [BP-4],CX ; if (p->type == 0201) { ; BX ← ←p MOV BX,[BP-4] MOV AL,[BX+3] CMP AL,081X JNZ X3 ; routRcvd += 1; INC ←routRcvd ; numEntries = (Swab(p->length) - pupOvBytes) >> 2; ; DI ← ←p MOV DI,[BP-4] MOV BX,[DI] CALL ←Swab ADD BX,0FFEAX MOV CX,2 SHR BX,CX ; ←numEntries ← BX MOV [BP-6],BX ; entries = (struct RoutingEntry *) p->data.words; ; BX ← ←p MOV BX,[BP-4] ADD BX,014X ; ←entries ← BX MOV [BP-10],BX ; for (i = 0; i < numEntries; i += 1) { MOV WORD PTR [BP-8],0 X6: ; BX ← ←numEntries MOV BX,[BP-6] ; CX ← ←i MOV CX,[BP-8] CMP CX,BX JGE X5 JR X4 X7: INC WORD PTR [BP-8] JR X6 X4: ; Block(); CALL ←Block ; net = entries[i].net; ; BX ← ←i MOV BX,[BP-8] ; CX ← ←entries MOV CX,[BP-10] SAL BX SAL BX ADD BX,CX MOV AL,[BX] XOR AH,AH ; ←net ← AX MOV [BP-12],AX ; route = &routingTable[net]; ; BX ← ←net MOV BX,[BP-12] LEA CX,←routingTable ADD CX,BX ADD CX,BX ADD BX,CX ; ←route ← BX POP DX PUSH BX ; hops = entries[i].hops + 1; ; BX ← ←i MOV BX,[BP-8] ; CX ← ←entries MOV CX,[BP-10] SAL BX SAL BX ADD BX,CX MOV AL,[BX+3] INC AL XOR AH,AH ; ←hops ← AX MOV [BP-14],AX ; if ((route->hops > hops) || (route->host == p->sPort.host) || ((route->hops == hops) && (route->age == 0x00ff))) { ; BX ← ←route POP BX PUSH BX MOV AL,[BX+1] JR $+5 X3: JMP X9 XOR AH,AH ; BX ← ←hops MOV BX,[BP-14] CMP AX,BX JG X11 ; DI ← ←route POP DI PUSH DI MOV AL,[DI] ; BX ← ←p MOV BX,[BP-4] MOV CL,[BX+15] CMP AL,CL JZ X13 ; BX ← ←route POP BX PUSH BX MOV AL,[BX+1] XOR AH,AH ; BX ← ←hops MOV BX,[BP-14] CMP AX,BX JNZ X14 ; BX ← ←route POP BX PUSH BX MOV AL,[BX+2] JR $+5 X5: JMP X15 CMP AL,0FFX X14: X13: X12: JNZ X10 X11: MOV AL,1 JR X16 X10: XOR AL,AL X16: OR AL,AL JZ X8 ; route->host = p->sPort.host; ; BX ← ←p MOV BX,[BP-4] MOV AL,[BX+15] ; BX ← ←route POP BX PUSH BX MOV [BX],AL ; route->hops = hops; ; BX ← ←route POP BX PUSH BX ; AL ← ←hops MOV AL,[BP-14] MOV [BX+1],AL ; route->age = 0; ; BX ← ←route POP BX PUSH BX MOV BYTE PTR [BX+2],0 ; }; X8: ; }; JMP X7 X15: ; }; X9: ; ReleasePBI(pbi); ; BX ← ←pbi MOV BX,[BP-2] CALL ←ReleasePBI ; }; MOV SP,BP POP BP RET; ; RequestRoute(net) ←RequestRoute: ; int net; PUSH BP MOV BP,SP PUSH BX ; { ; struct PBI *pbi; ; struct SocketEntry *pse; ; struct Port lclPort; ; if (!routingSoc) { ADD SP,0FFF6X MOV BX,←routingSoc OR BX,BX JNZ X17 ; lclPort.net = localNet; MOV AX,←localNet ; ←lclPort ← AL POP DX PUSH AX ; lclPort.host = localHost; MOV AX,←localHost ; ←lclPort+1 ← AL MOV [BP-11],AL ; lclPort.socket.LS = 0; MOV WORD PTR [BP-10],0 ; lclPort.socket.ms = Swab(2); MOV BX,2 CALL ←Swab ; ←lclPort+4 ← BX MOV [BP-8],BX ; routingSoc = OpenLevel1Socket(&lclPort, &RoutePr, 0); ;&←lclPort LEA BX,[BP-12] PUSH BX XOR BX,BX MOV CX,OFFSET ←RoutePr CALL ←OpenLevel1Socket POP DX MOV ←routingSoc,BX ; if (!routingSoc) return; MOV BX,←routingSoc OR BX,BX JNZ X18 MOV SP,BP POP BP RET; X18: ; }; X17: ; pbi = GetPBI(); CALL ←GetPBI ; ←pbi ← BX MOV [BP-4],BX ; pbi->pup->sPort.socket.LS = 0; ; BX ← ←pbi MOV BX,[BP-4] MOV CX,[BX+6] MOV BX,CX MOV WORD PTR [BX+16],0 ; pbi->pup->sPort.socket.ms = Swab(2); ; BX ← ←pbi MOV BX,[BP-4] MOV CX,[BX+6] PUSH CX MOV BX,2 CALL ←Swab MOV CX,BX POP BX MOV [BX+18],CX ; SimpleSend(pbi, 0200, 02); ; BX ← ←pbi MOV BX,[BP-4] PUSH BX MOV BX,2 MOV CX,080X CALL ←SimpleSend POP DX ; routSent += 1; INC ←routSent ; }; MOV SP,BP POP BP RET; ; static struct PBI *rcvPBI; ; static int rcvType; ; static int z[2]; /* actually a null ShortSTRING */ ; static int counter[2]; ; static RcvPr(pbi) ←RcvPr: ; struct PBI *pbi; PUSH BP MOV BP,SP PUSH BX ; { ; if ((pbi->pup->type != rcvType) || (rcvPBI != 0)) ReleasePBI(pbi); ; BX ← ←pbi POP BX PUSH BX MOV CX,[BX+6] MOV DI,CX MOV AL,[DI+3] XOR AH,AH MOV BX,←rcvType CMP AX,BX JNZ X21 MOV BX,←rcvPBI OR BX,BX X21: X20: JZ X19 ; BX ← ←pbi POP BX PUSH BX CALL ←ReleasePBI ; else { JR X22 X19: ; rcvPBI = pbi; ; BX ← ←pbi POP BX PUSH BX MOV ←rcvPBI,BX ; simpleRcvd += 1; INC ←simpleRcvd ; }; X22: ; }; MOV SP,BP POP BP RET; ; struct PBI *SimpleExch(sendType, recvType, servSoc, tries) ←SimpleExch: ; int sendType, recvType, servSoc, tries; PUSH BP MOV BP,SP PUSH CX PUSH BX ; { ; struct PBI *pbi; ; struct Pup *p; ; int soc, i; ; struct Queue tQ[1]; ; int tmr[1]; ; int wait; ADD SP,0FFF0X ; InitQueue(tQ) ;&←tQ LEA BX,[BP-16] CALL ←InitQueue ; pbi = GetPBI(); CALL ←GetPBI ; ←pbi ← BX MOV [BP-6],BX ; p = pbi->pup; ; BX ← ←pbi MOV BX,[BP-6] MOV CX,[BX+6] ; ←p ← CX MOV [BP-8],CX ; Timer(&p->sPort.socket.LS); ; BX ← ←p MOV BX,[BP-8] ADD BX,010X CALL ←Timer ; rcvPBI = 0; MOV WORD PTR ←rcvPBI,0 ; if (!(soc = OpenLevel1Socket(&p->sPort, &RcvPr, 0))) CallSwat(ecPup1+10); ; BX ← ←p MOV BX,[BP-8] ADD BX,0EX PUSH BX XOR BX,BX MOV CX,OFFSET ←RcvPr CALL ←OpenLevel1Socket POP DX ; ←soc ← BX MOV [BP-10],BX OR BX,BX JNZ X23 MOV BX,0400AX CALL ←CallSwat X23: ; pbi->queue = tQ; ; BX ← ←pbi MOV BX,[BP-6] ;&←tQ LEA CX,[BP-16] MOV [BX+2],CX ; rcvType = recvType; ; BX ← ←recvType MOV BX,[BP+4] MOV ←rcvType,BX ; Timer(counter); LEA BX,←counter CALL ←Timer ; wait = 100; MOV WORD PTR [BP-20],064X ; for (i = 0; ((i<tries) && (rcvPBI == 0)); i += 1) { MOV WORD PTR [BP-12],0 X26: ; BX ← ←tries MOV BX,[BP-4] ; CX ← ←i MOV CX,[BP-12] CMP CX,BX JGE X27 MOV BX,←rcvPBI OR BX,BX JNZ X27 MOV AL,1 JR X28 X27: XOR AL,AL X28: OR AL,AL JZ X25 JR X24 X29: INC WORD PTR [BP-12] JR X26 X24: ; simpleSent += 1; INC ←simpleSent ; SimpleSend(pbi, sendType, servSoc); ; BX ← ←pbi MOV BX,[BP-6] PUSH BX ; BX ← ←servSoc MOV BX,[BP-2] ; CX ← ←sendType MOV CX,[BP+6] CALL ←SimpleSend POP DX ; WaitUntilSent(pbi); /* Removed from tQ after sent */ ; BX ← ←pbi MOV BX,[BP-6] CALL ←WaitUntilSent ; SetTmr(wait, tmr); ;&←tmr LEA BX,[BP-18] ; CX ← ←wait POP CX PUSH CX CALL ←SetTmr ; while ((!TmrExp(tmr)) && (rcvPBI == 0)) Block(); X30: ;&←tmr LEA BX,[BP-18] CALL ←TmrExp OR BX,BX JNZ X32 MOV BX,←rcvPBI OR BX,BX X32: JNZ X31 CALL ←Block JR X30 X31: ; wait = wait + 500; ; BX ← ←wait POP BX ADD BX,01F4X ; ←wait ← BX PUSH BX ; }; JR X29 X25: ; ReleasePBI(pbi); ; BX ← ←pbi MOV BX,[BP-6] CALL ←ReleasePBI ; CloseLevel1Socket(soc); /* We either got it or we didn't! */ ; BX ← ←soc MOV BX,[BP-10] CALL ←CloseLevel1Socket ; return(rcvPBI); MOV BX,←rcvPBI MOV SP,BP POP BP RET; ; }; ; SimpleSend(pbi, sendType, servSoc) ←SimpleSend: ; struct PBI *pbi; ; int sendType, servSoc; PUSH BP MOV BP,SP PUSH CX PUSH BX ; { ; struct Pup *p; PUSH DX ; p = pbi->pup; ; BX ← ←pbi MOV BX,[BP+4] MOV CX,[BX+6] ; ←p ← CX POP DX PUSH CX ; p->dPort.net = localNet; ; BX ← ←p POP BX PUSH BX MOV AX,←localNet MOV [BX+8],AL ; p->dPort.socket.ms = Swab(servSoc); ; BX ← ←p POP BX PUSH BX PUSH BX ; BX ← ←servSoc MOV BX,[BP-4] CALL ←Swab MOV CX,BX POP BX MOV [BX+12],CX ; p->sPort.net = localNet; ; BX ← ←p POP BX PUSH BX MOV AX,←localNet MOV [BX+14],AL ; p->sPort.host = localHost; ; BX ← ←p POP BX PUSH BX MOV AX,←localHost MOV [BX+15],AL ; p->type = sendType; ; BX ← ←p POP BX PUSH BX ; AL ← ←sendType MOV AL,[BP-2] MOV [BX+3],AL ; if (!counter[0]) Timer(counter); MOV BX,←counter OR BX,BX JNZ X33 LEA BX,←counter CALL ←Timer X33: ; DoubleInc(counter, 1); MOV BX,1 LEA CX,←counter CALL ←DoubleInc ; p->id[0] = counter[1]; ; BX ← ←p POP BX PUSH BX ADD BX,4 MOV CX,←counter+2 MOV [BX],CX ; p->id[1] = counter[0]; ; BX ← ←p POP BX PUSH BX ADD BX,4 MOV CX,←counter MOV [BX+2],CX ; Zero(z, 2); MOV BX,2 LEA CX,←z CALL ←Zero ; AppendStringToPup(pbi, 0, z); /* Just to compute length of empty packet */ ; BX ← ←pbi MOV BX,[BP+4] PUSH BX LEA BX,←z XOR CX,CX CALL ←AppendStringToPup POP DX ; SendPup(pbi); ; BX ← ←pbi MOV BX,[BP+4] CALL ←SendPup ; }; MOV SP,BP POP BP RET; ; Externals Declared Here PUBLIC ←calendar PUBLIC ←ReadCalendar PUBLIC ←InitCalendar PUBLIC ←SimpleExch PUBLIC ←routingSoc PUBLIC ←RequestRoute PUBLIC ←SimpleSend C←CODE ENDS ; Number of Bytes of Code = 0404X, (1028)