/* teleload.c January 4, 1982 11:49 AM */ extern char IRESET; extern char mstate[26]; struct ccb { char cmda; char *addra; char counta; char stata; }; struct port { char net, host; int soc1, soc2; }; struct pup { int eaddr; int etype; int len; char tpc, type; int id1, id2; struct port dport, sport; char data[1]; }; struct core { int addrlo, addrhi, count; char data[1]; }; struct ccb minccb, inccb, outccb; /* really want length to be unsigned, but *char is ok too. The problem is to avoid sign extension when assigning from inccb.counta to length */ char *cdata, *caddr, *length; int ccount; struct pup *rpup, *tpup; struct core *tcore; int lastid1, lastid2, tplen, rv, valid; int rbuf[130], buf[130]; /* Pup echo server */ main() { minccb.cmda = 0x00; minccb.addra = rbuf; minccb.counta = 0; minccb.stata = 0; portstr(&IRESET); tpup = (struct pup *) buf; tcore = (struct core *) tpup->data; cdata = tcore->data; rpup = (struct pup *) rbuf; slcinit(0x0055); for (;;) { startrx(); waitccb(&inccb); if (inccb.stata != 0x88) continue; if (inccb.counta == 0) length = 256; else length = inccb.counta; echo(length); }; }; echo(leng) int leng; { int plen; if (!(rpup->eaddr & 0xff)) return; if (leng&01) return; if (leng<26) return; /* generate a delay */ plen = 3000; while (--plen); /* unswabbed etype should be 2 */ if (rpup->etype != 2) return; /* check lengths */ plen = (swab(rpup->len)+5) & 0xfffe; if (plen != leng) return; /* check pup destintion */ if (rpup->dport.host != 0x55) return; if ((rpup->dport.soc1) || (rpup->dport.soc2 != 0x3000)) return; if ((rpup->type != 0xc0) && (rpup->type != 0xc2)) { if ((rpup->type != 0xc4) && (rpup->type != 0xc6)) return; }; if ((rpup->id1 == lastid1) && (rpup->id2 == lastid2)) { if (valid) sendpkt(); return; }; /* copy packet accross */ blt(rbuf, buf, 260); valid = 0; rv = 0; caddr = swab(tcore->addrlo); ccount = swab(tcore->count); if (tcore->addrhi) return; /* check puptype */ if (tpup->type == 0xc0) { /* core store */ blt(cdata, caddr, ccount); blt(caddr, cdata, ccount); comtc(); tplen = leng; }; if (tpup->type == 0xc2) { /* core fetch */ mcomc(); }; if (tpup->type == 0xc6) { /* state fetch */ if (((int) caddr != 1) || (ccount != 28)) return; caddr = mstate; mcomc(); }; if (tpup->type == 0xc4) { /* state store */ if (((int) caddr != 1) || (ccount != 28)) return; caddr = mstate; blt(cdata, caddr, ccount); mcomc(); setuppkt(); sendpkt(); startm(); }; if (!rv) return(0); setuppkt(); sendpkt(); }; mcomc() { blt(caddr, cdata, ccount); tplen = (33+ccount) & 0xfffe; tpup->len = swab(tplen - 4); comtc(); }; sendpkt() { outccb.cmda = 0x50; outccb.addra = buf; outccb.counta = tplen; outccb.stata = 0; sltstart(&outccb); /* wait for transmit done */ waitccb(&outccb); }; setuppkt() { /* swap src and destination */ ssd(buf); /* fill in no-checksum */ buf[(tplen/2)-1] = 0xffff; /* swap ether source and destination */ tpup->eaddr = swab(tpup->eaddr); /* zero transport control */ tpup->tpc = 0; /* set puptype */ /* tpup->type += 1; doesn't work */ tpup->type = tpup->type+1; }; comtc() { rv = 1; valid = 1; lastid1 = tpup->id1; lastid2 = tpup->id2; }; ssd(p) char *p; { char temp[6]; blt(&p[12],temp, 6); blt(&p[18],&p[12], 6); blt(temp,&p[18], 6); }; startrx() { if (slrstat() & 0x000c) slrinit(); blt(&minccb, &inccb, 5); slrstart(&inccb); };