|
|
1.1 ! root 1: #define M32LD "/bin/32reloc" ! 2: #define BINARY_LOAD 0 ! 3: #define HEX_LOAD 1 ! 4: int Loadtype = BINARY_LOAD; ! 5: ! 6: /* ! 7: * MAC-32 (down)loader ! 8: */ ! 9: ! 10: char Usage[] = "Usage: 32ld [-d] [-p] [-z] objectfile"; ! 11: /* also a [-l] flag, but the user never sees this */ ! 12: char *name; ! 13: ! 14: /* ! 15: * swapw words must be swapped between host and MAC-32 ! 16: * swapb bytes must be swapped between host and MAC-32 ! 17: */ ! 18: #ifdef pdp11 ! 19: #define swapb 1 ! 20: #define swapw 0 ! 21: #endif ! 22: #ifdef vax ! 23: #define swapb 1 ! 24: #define swapw 1 ! 25: #endif ! 26: #ifdef u3b ! 27: #define swapb 0 ! 28: #define swapw 0 ! 29: #endif ! 30: #ifdef u3b2 ! 31: #define swapb 0 ! 32: #define swapw 0 ! 33: #endif ! 34: #ifdef u3b5 ! 35: #define swapb 0 ! 36: #define swapw 0 ! 37: #endif ! 38: ! 39: #include <sgtty.h> ! 40: #include "a.out.h" ! 41: #include "aouthdr.h" ! 42: #include "filehdr.h" ! 43: #include "scnhdr.h" ! 44: #include <stdio.h> ! 45: #include <errno.h> ! 46: #include <jioctl.h> ! 47: #include "proto.h" ! 48: #include <sys/types.h> ! 49: #include <sys/stat.h> ! 50: ! 51: #define MAXRETRIES 10 ! 52: #define SLEEPTIME 7 ! 53: #define DATASIZE 512 ! 54: ! 55: #define NSECTS 12 ! 56: ! 57: #define MPX_VER 0x5620 ! 58: #define FBOMAGIC 0560 ! 59: #define SENDTERMID "\033[c" ! 60: #define TERM_1_0 "\033[?8;7;1c" ! 61: #define TERMB_1_0 "\033[?8;7;2c" ! 62: #define TERM_DMD "\033[?8;" ! 63: #define TERMIDSIZE 9 ! 64: #define STR_EQUAL 0 ! 65: ! 66: struct filehdr fileheader; ! 67: struct aouthdr aoutheader; ! 68: struct scnhdr secthdrs[NSECTS]; ! 69: char *errname; /* name of error file for m32ld */ ! 70: ! 71: #if vax | u3b | u3b2 ! 72: struct sgttyb ttysave, /* save the state of tty */ ! 73: ttyraw; ! 74: struct ttydevb ttydsave, ttydraw; ! 75: #else ! 76: struct termio ttysave, /* save the state of tty */ ! 77: ttyraw; ! 78: #endif ! 79: int obj; /* File descriptor for object file */ ! 80: int mpx; /* Running under mpx */ ! 81: long location; ! 82: char file[128]; /* Name of file */ ! 83: char m32ld[128]; /* path name to m32ld command */ ! 84: int nargchars; /* Number of characters, including nulls, in args */ ! 85: long longbuf[3]; ! 86: int debug; /* Show sizes etc. */ ! 87: int psflag; /* Print error detection statistics */ ! 88: short maxpktdsize; ! 89: int rflag; /* relocate? */ ! 90: int zflag; /* Do a JZOMBOOT */ ! 91: int booted; ! 92: int errfile; ! 93: int retries; ! 94: int open(); ! 95: int access(); ! 96: char *malloc(); ! 97: ! 98: char Load_str[] = "\033[0;0v"; /* default download (binary & standalone*/ ! 99: int Layerflag = 0; ! 100: struct stat Statbuf, *Statptr; ! 101: ! 102: short speeds[16]={ ! 103: 1, 5, 7, 10, 13, 15, 20, 30, ! 104: 60, 120, 180, 240, 480, 960, 1920, 1 ! 105: }; ! 106: ! 107: unsigned char sizes[16]={ ! 108: 16, 16, 16, 16, 16, 16, 16, 16, ! 109: 16, 32, 32, 56, 56, 120, 60, 16 ! 110: }; ! 111: ! 112: void Psend(); ! 113: void Precv(); ! 114: void Write(); ! 115: ! 116: extern int errno; ! 117: extern char *getenv(); ! 118: ! 119: timeout_id() ! 120: { ! 121: error(0, "Error: can't identify terminal:\n\t not a 5620 terminal or 5620 failed to respond", ! 122: (char *) 0); ! 123: } ! 124: ! 125: main(argc, argv) ! 126: int argc; ! 127: register char *argv[]; ! 128: { ! 129: char *dwnldflag; ! 130: ! 131: #ifndef M32LD ! 132: M32LD; /* force a compile time error if undefined */ ! 133: #endif ! 134: /* Start out by checking that download is going */ ! 135: /* to a DMD with at least 1.1 firmware (not 1.0) */ ! 136: char termid[TERMIDSIZE+1]; ! 137: int lpindex; ! 138: int count; ! 139: char *strcpy(), *strcat(); ! 140: ! 141: for (lpindex=0; lpindex<=TERMIDSIZE; lpindex++) ! 142: termid[lpindex] = 0; ! 143: ! 144: (void)strcpy(m32ld, getenv("DMDSGS")? getenv("DMDSGS") : "/usr/jerq"); ! 145: (void)strcat(m32ld, M32LD); /* attach tail of path to head */ ! 146: ! 147: #if vax | u3b | u3b2 ! 148: (void)ioctl(1, TIOCGETP, &ttysave); /* get the current state */ ! 149: if (ioctl(1, TIOCGDEV, &ttydsave) < 0) { ! 150: ttydsave.ospeed = ttysave.sg_ospeed; ! 151: ttydsave.ispeed = ttysave.sg_ispeed; ! 152: } ! 153: #else ! 154: (void)ioctl(1, TCGETA, &ttysave); /* get the current state */ ! 155: #endif ! 156: ! 157: name = *argv; ! 158: ! 159: while(argc>1 && argv[1][0]=='-'){ ! 160: switch(argv[1][1]){ ! 161: case 'd': ! 162: debug++; ! 163: break; ! 164: case 'e': ! 165: printf("-e flag no longer used: always assumed\n"); ! 166: break; ! 167: case 'p': ! 168: psflag++; ! 169: break; ! 170: case 'z': ! 171: zflag++; ! 172: break; ! 173: case 'l': ! 174: Layerflag++; ! 175: break; ! 176: case '\0': ! 177: break; ! 178: default: ! 179: error(0, Usage, (char *)0); ! 180: return 1; ! 181: } ! 182: argv++; argc--; ! 183: } ! 184: if(argc<2){ ! 185: error(0, Usage, (char *)0); ! 186: return 2; ! 187: } ! 188: ! 189: /* ! 190: * see what type of download is expected ! 191: */ ! 192: if(((dwnldflag = getenv("DMDLOAD")) != NULL) && (dwnldflag[0] != NULL)) { ! 193: if(strcmp(dwnldflag, "hex") == 0) ! 194: Loadtype = HEX_LOAD; ! 195: else ! 196: Loadtype = BINARY_LOAD; ! 197: } ! 198: Load_str[4] = Loadtype + '0'; ! 199: ! 200: ! 201: #if vax | u3b | u3b2 ! 202: ttyraw = ttysave; ! 203: ttydraw = ttydsave; ! 204: ttyraw.sg_flags |= RAW; ! 205: ttydraw.flags |= F8BIT; ! 206: (void)ioctl(1, TIOCSETP, &ttyraw); ! 207: (void)ioctl(1, TIOCSDEV, &ttydraw); ! 208: #else ! 209: ttyraw.c_iflag = IGNBRK; ! 210: ttyraw.c_cflag = (ttysave.c_cflag & CBAUD) | (ttysave.c_cflag & CLOCAL) | CS8 | CREAD; ! 211: ttyraw.c_cc[VMIN] = 1; ! 212: (void)ioctl(1, TCSETAW, &ttyraw); ! 213: #endif ! 214: mpx = (ioctl(1, JMUX, 0) > -1); ! 215: if ( !mpx ) ! 216: { ! 217: ! 218: /* make sure we've got the correct rom */ ! 219: write(1,SENDTERMID,strlen(SENDTERMID)); ! 220: count = 0; ! 221: while(count < TERMIDSIZE){ ! 222: lpindex = read(0,&termid[count],TERMIDSIZE); ! 223: if(lpindex <= 0) ! 224: error(1, "read error", (char *)0); ! 225: count += lpindex; ! 226: } ! 227: if ((strcmp(termid,TERM_1_0) == STR_EQUAL) || /* equal strings */ ! 228: (strcmp(termid,TERMB_1_0) == STR_EQUAL)) ! 229: error(0,"Error: Firmware not updated to 1.1 or greater\n", ! 230: (char *) 0); ! 231: if (strncmp(termid,TERM_DMD,strlen(TERM_DMD)) != STR_EQUAL) ! 232: error(0, "Error: 32ld must be run on a 5620 terminal\n", ! 233: (char *) 0); ! 234: } else { ! 235: ! 236: /* load sequence for mux is shorter */ ! 237: Load_str[3] = '\0'; ! 238: } ! 239: ! 240: if(jpath(argv[1], access, 4)!=0) ! 241: error(1, "no such file '%s'", argv[1]); ! 242: ! 243: Statptr= &Statbuf; ! 244: stat(argv[1], Statptr); ! 245: if(Layerflag && (Statbuf.st_size == 0)) { ! 246: Load_str[2] = '2'; ! 247: realwrite(Load_str, 6); ! 248: goto cleanup; ! 249: } ! 250: ! 251: obj=jpath(argv[1], open, 0); ! 252: if(obj<0) ! 253: error(1, "cannot open '%s'", file); ! 254: ! 255: Read (&fileheader, sizeof(struct filehdr)); ! 256: if(fileheader.f_magic!=FBOMAGIC) /* FBOMAGIC is 0560 */ ! 257: error(0, "'%s' is not a MAC-32 a.out", file); ! 258: Read (&aoutheader, fileheader.f_opthdr); ! 259: ! 260: if (fileheader.f_nscns > NSECTS) ! 261: error(0,"32ld: exceeded max number of sections -- see system administrator"); ! 262: if((aoutheader.vstamp==MPX_VER) ^ mpx) /* MPX_VER is 0x5620 */ ! 263: error(0, mpx? "'%s' compiled stand-alone": "'%s' compiled for mpx", file); ! 264: ! 265: if(((aoutheader.tsize + aoutheader.dsize + aoutheader.bsize) == 0) && Layerflag) { ! 266: Load_str[2] = '2'; ! 267: realwrite(Load_str, mpx ? 3 : 6); ! 268: goto cleanup; ! 269: } ! 270: if(Layerflag) { ! 271: /* ! 272: * if it got here then we want to download layers with a patch ! 273: */ ! 274: Load_str[2] = '1'; ! 275: } ! 276: ! 277: if(boot() && rflag==0) ! 278: rflag++; ! 279: if(!mpx){ ! 280: #if vax | u3b | u3b2 ! 281: maxpktdsize = min(sizes[ttydsave.ospeed & 017], (long)MAXPKTDSIZE); ! 282: pinit(speeds[ttydsave.ospeed & 017], maxpktdsize, ACKON); ! 283: #else ! 284: maxpktdsize = min(sizes[ttysave.c_cflag&CBAUD], (long)MAXPKTDSIZE); ! 285: pinit(speeds[ttysave.c_cflag&CBAUD], maxpktdsize, ACKON); ! 286: #endif ! 287: } ! 288: ! 289: load(argv[1], argc-1, argv+1); ! 290: if(!mpx){ /* ACKON is always true */ ! 291: buzz(); ! 292: (void)ioctl(0, TIOCFLUSH, (struct termio *)0); ! 293: } ! 294: (void)ioctl(1, TIOCNXCL, 0); ! 295: cleanup: ! 296: #if vax | u3b | u3b2 ! 297: (void)ioctl(1, TIOCSETP, &ttysave); ! 298: (void)ioctl(1, TIOCSDEV, &ttydsave); ! 299: #else ! 300: (void)ioctl(1, TCSETAW, &ttysave); ! 301: #endif ! 302: ! 303: if(psflag) ! 304: pstats(stderr); ! 305: return(0); ! 306: } ! 307: ! 308: ! 309: char * ! 310: bldargs(argc, argv) ! 311: char *argv[]; ! 312: { ! 313: register i; ! 314: register char *argp, *p, *q; ! 315: for(nargchars=0, i=0; i<argc; i++) ! 316: nargchars+=strlen(argv[i])+1; ! 317: if((argp=malloc(nargchars))==0) ! 318: error("can't allocate argument chars", ""); ! 319: /* this loop is probably not necessary, but it's safe */ ! 320: for(i=0, q=argp; i<argc; i++){ ! 321: p=argv[i]; ! 322: do; while(*q++ = *p++); ! 323: } ! 324: return argp; ! 325: } ! 326: ! 327: ! 328: load(f, argc, argv) ! 329: char *f; ! 330: char *argv[]; ! 331: { ! 332: char *argp; ! 333: long largc; ! 334: int i; ! 335: if(mpx){ ! 336: argp=bldargs(argc, argv); ! 337: largc=argc; ! 338: writeswap((char *)&largc, 4); /* number of arguments */ ! 339: largc=nargchars; ! 340: writeswap((char *)&largc, 4); /* number of chars in arguments */ ! 341: writeswap((char *)&aoutheader.tsize, 12); ! 342: } ! 343: ! 344: if(rflag) ! 345: relocate(); ! 346: else ! 347: location = aoutheader.entry; ! 348: if(mpx) ! 349: Write(argp, nargchars); ! 350: for (i = 0; i < fileheader.f_nscns; ++i) /* read section header array */ ! 351: Read (§hdrs[i], sizeof(struct scnhdr)); ! 352: ! 353: if(debug){ ! 354: fprintf(stderr, "%s:\nSection:\taddr:\tsize:\n", file); ! 355: for ( i = 0; i < fileheader.f_nscns; ++i) ! 356: fprintf(stderr,"%s\t\t0x%lx\t0x%lx\n", ! 357: secthdrs[i].s_name,secthdrs[i].s_paddr,secthdrs[i].s_size); ! 358: buzz(); ! 359: } ! 360: sendfile(); ! 361: if(!mpx){ ! 362: long startaddr; ! 363: ! 364: retries = 0; ! 365: while(freepkts != NPBUFS) ! 366: Precv(); ! 367: location = aoutheader.entry; ! 368: swaw(&location, &startaddr, PKTASIZE); ! 369: psend((char *)&startaddr, PKTASIZE); ! 370: retries = 0; ! 371: while(freepkts != NPBUFS) ! 372: Precv(); ! 373: } ! 374: } ! 375: ! 376: jpath(f, fn, a) ! 377: register char *f; ! 378: register int (*fn)(); ! 379: { ! 380: char *getenv(), *strcpy(); ! 381: register char *jp, *p; ! 382: register o; ! 383: if (*f != '/' && strncmp(f, "./", 2) && strncmp(f, "../", 3) && ! 384: (jp=getenv("JPATH"))!=0){ ! 385: while(*jp){ ! 386: for(p=file; *jp && *jp!=':'; p++,jp++) ! 387: *p= *jp; ! 388: if(p!=file) ! 389: *p++='/'; ! 390: if(*jp) ! 391: jp++; ! 392: (void)strcpy(p, f); ! 393: if((o=(*fn)(file, a))!=-1) ! 394: return o; ! 395: } ! 396: } ! 397: return((*fn)(strcpy(file, f), a)); ! 398: } ! 399: ! 400: error(pflag, s1, s2) ! 401: char *s1, *s2; ! 402: { ! 403: long flushval = 0L; ! 404: register int n; ! 405: register int saverrno; ! 406: char buf[BUFSIZ]; ! 407: extern int errno; ! 408: ! 409: saverrno = errno; ! 410: if(booted){ ! 411: if (mpx) /* tell dmd side to give up */ ! 412: (void)ioctl(1, JTERM, 0); ! 413: else ! 414: { ! 415: psend((char *)(&flushval),sizeof(long)); ! 416: } ! 417: if(errfile>0){ ! 418: buzz(); ! 419: while((n=read(errfile, buf, sizeof buf))>0) ! 420: write(2, buf, n); ! 421: unlink(errname); ! 422: } ! 423: } ! 424: (void)ioctl(1, TIOCNXCL, 0); ! 425: #if vax | u3b | u3b2 ! 426: (void)ioctl(1, TIOCSETP, &ttysave); ! 427: (void)ioctl(1, TIOCSDEV, &ttydsave); ! 428: #else ! 429: (void)ioctl(1, TCSETAW, &ttysave); ! 430: #endif ! 431: if(pflag){ ! 432: errno=saverrno; ! 433: perror(s2); ! 434: } ! 435: fprintf(stderr, "%s: ", name); ! 436: fprintf(stderr, s1, s2); ! 437: fprintf(stderr, "\n"); ! 438: if(psflag) ! 439: pstats(stderr); ! 440: exit(1); ! 441: } ! 442: int ! 443: Read(a, n) ! 444: char *a; ! 445: { ! 446: register i; ! 447: i=read(obj, a, n); ! 448: if(i<0) ! 449: error(1, "read error on '%s'", file); ! 450: return(i); ! 451: } ! 452: void ! 453: Write(a, n) ! 454: char *a; ! 455: { ! 456: if(realwrite(a, n)!=n) ! 457: error(1, "write error to jerq", (char *)0); ! 458: if(psflag && !mpx) ! 459: trace(a); ! 460: } ! 461: writeswap(a, n) ! 462: char *a; ! 463: { ! 464: char buf1[DATASIZE+PKTASIZE], buf2[DATASIZE+PKTASIZE]; ! 465: swaw(a, buf1, n); ! 466: swab(buf1, buf2, n); ! 467: Write(buf2, n); ! 468: } ! 469: trace(a) ! 470: char *a; ! 471: { ! 472: register int i; ! 473: ! 474: for(i=0; i<(PKTHDRSIZE+PKTASIZE); i++) ! 475: fprintf(stderr, "<%o>", a[i]&0xff); ! 476: fprintf(stderr, "\n"); ! 477: } ! 478: ! 479: sendfile() ! 480: { ! 481: register int i; ! 482: for ( i = 0; i<fileheader.f_nscns; ++i) { ! 483: if(secthdrs[i].s_scnptr > 0) { ! 484: if ((secthdrs[i].s_flags & STYP_NOLOAD) || ! 485: (secthdrs[i].s_flags & STYP_DSECT)) ! 486: continue; ! 487: lseek(obj,secthdrs[i].s_scnptr,0); ! 488: sendseg(secthdrs[i].s_paddr,secthdrs[i].s_paddr+secthdrs[i].s_size); ! 489: } ! 490: } ! 491: } ! 492: ! 493: sendseg(strloc,endloc) ! 494: long strloc; ! 495: long endloc; ! 496: { ! 497: char buf[DATASIZE+PKTASIZE], buf2[DATASIZE]; ! 498: char tmpbuf[DATASIZE+PKTASIZE]; ! 499: register n; ! 500: while((n=Read(&buf[PKTASIZE], min(!mpx?maxpktdsize:DATASIZE, endloc-strloc)))>0){ ! 501: if(mpx){ ! 502: /* swab(&buf[PKTASIZE], buf2, n); NOT RITE with m32 sgs*/ ! 503: Write(&buf[PKTASIZE], n); ! 504: }else{ ! 505: swab(&buf[PKTASIZE], &tmpbuf[PKTASIZE], n); ! 506: swaw((short *)&strloc, (short *)&tmpbuf[0], PKTASIZE); ! 507: Psend(tmpbuf, n+PKTASIZE); ! 508: } ! 509: strloc+=n; ! 510: } ! 511: } ! 512: void ! 513: Psend(bufp, count) ! 514: char *bufp; ! 515: int count; ! 516: { ! 517: retries = 0; ! 518: while(freepkts == 0) ! 519: Precv(); ! 520: psend(bufp, count); ! 521: } ! 522: void ! 523: Precv() ! 524: { ! 525: char c; ! 526: ! 527: alarm(3); /* sleep at least 2 seconds */ ! 528: if(realread(&c, 1) == 1){ ! 529: alarm(0); ! 530: if(psflag) ! 531: fprintf(stderr, "recv <%o>\n", c&0xff); ! 532: precv(c); ! 533: }else if(errno != EINTR ) ! 534: error(1, "read error", (char *)0); ! 535: else if(++retries >= MAXRETRIES) ! 536: error(0, "load protocol failed", (char *)0); ! 537: else if(psflag) ! 538: fprintf(stderr, "recv timeout.. retries=%d\n",retries); ! 539: } ! 540: ! 541: min(a, b) ! 542: long b; /* not your average min() */ ! 543: { ! 544: return(a<b? a : (int)b); ! 545: } ! 546: ! 547: swab(a, b, n) ! 548: register char *a, *b; ! 549: register n; ! 550: { ! 551: # if(swapb) ! 552: register char *s, *t; ! 553: n/=2; /* n in bytes */ ! 554: s=b+1; ! 555: t=b; ! 556: while(n--){ ! 557: *s= *a++; ! 558: *t= *a++; ! 559: s+=2; ! 560: t+=2; ! 561: } ! 562: # else ! 563: while(n--) ! 564: *b++= *a++; ! 565: # endif ! 566: } ! 567: ! 568: swaw(a, b, n) ! 569: register short *a, *b; ! 570: register n; ! 571: { ! 572: # if(swapw) ! 573: register short *s, *t; ! 574: n/=4; /* n in bytes */ ! 575: s=b+1; ! 576: t=b; ! 577: while(n--){ ! 578: *s= *a++; ! 579: *t= *a++; ! 580: s+=2; ! 581: t+=2; ! 582: } ! 583: # else ! 584: n>>=1; ! 585: while(n--) ! 586: *b++= *a++; ! 587: # endif ! 588: } ! 589: relocate(){ ! 590: long address; ! 591: char buf[200]; ! 592: char *mktemp(); ! 593: long caddress; ! 594: register i; ! 595: register char *p=(char *)&address; ! 596: char *tmpname; /* name of temporary file for reloc */ ! 597: for(i=0; i<4; i++) ! 598: read(0, p++, 1); ! 599: (void)ioctl(1, TIOCEXCL, 0); /* must be here so PUSHLD can work in mux */ ! 600: swab(&address, &caddress, 4); ! 601: swaw(&caddress, &address, 4); ! 602: location=address; ! 603: if(location==0) ! 604: error(0, "no memory in terminal", (char *)0); ! 605: sprintf(buf, "%s -b %lx %s >%s 2>%s", m32ld, location, file, ! 606: tmpname=mktemp("/tmp/32XXXXXX"), ! 607: errname=mktemp("/tmp/32EXXXXXX")); ! 608: if(system(buf)){ ! 609: errfile=open(errname, 0); ! 610: if (!debug) ! 611: unlink(tmpname); ! 612: unlink(errname); ! 613: error(0, "reloc errors", (char *)0); ! 614: } ! 615: close(obj); ! 616: unlink(errname); ! 617: obj=open(tmpname, 0); ! 618: if(obj<0) /* HELP!! */ ! 619: error(1, "tmp file vanished! (%s)", tmpname); ! 620: if (!debug) ! 621: unlink (tmpname); ! 622: Read (&fileheader, sizeof(struct filehdr)); ! 623: Read (&aoutheader, fileheader.f_opthdr); ! 624: } ! 625: ! 626: boot(){ ! 627: char c = 0; ! 628: ! 629: if(mpx){ ! 630: (void)ioctl(0, TIOCFLUSH, 0); /* throw away type-ahead! */ ! 631: (void)ioctl(1, zflag?JZOMBOOT:JBOOT, 0); ! 632: }else{ ! 633: write(1, Load_str,6); /* esc sequence for download */ ! 634: while(c != 'a' && c != 1) ! 635: read(0, &c, 1); /* wait for terminal to be ready */ ! 636: } ! 637: booted++; ! 638: return mpx; ! 639: } ! 640: ! 641: buzz(){ ! 642: /* sleep for a time >~0.5 sec; nice if we had nap! */ ! 643: sleep(2); /* sleep(1) not necessarily long enough */ ! 644: } ! 645: ! 646: /* ! 647: * This routine is the lowest level write routine to the dmd. It provides a ! 648: * simple way to implement a safer download protocol through networks. ! 649: * This requires that a shell varariable will be set if this extra precaution ! 650: * is to be taken. ! 651: */ ! 652: ! 653: realwrite(a,n) ! 654: char *a; ! 655: { ! 656: char cbuf[(MAXPKTSIZE + PKTASIZE) * 2], c; ! 657: int i, j, maxsize; ! 658: ! 659: if((Loadtype == BINARY_LOAD) || mpx){ ! 660: return(write(1,a,n)); ! 661: } ! 662: else { ! 663: /* ! 664: * do a hex load ! 665: */ ! 666: j = n; ! 667: maxsize = ((MAXPKTSIZE + PKTASIZE) / 2); ! 668: for(i = 0;i < n*2; i++){ ! 669: c = *a++; ! 670: cbuf[i]=(c & 0xf) | 0x40; ! 671: cbuf[++i]=((c >> 4) & 0xf) | 0x40; ! 672: } ! 673: i = 0; ! 674: while(n > 0) { ! 675: if(n > maxsize) { ! 676: if(write(1, &cbuf[i*maxsize*2], maxsize*2) != maxsize*2) ! 677: return(-1); ! 678: n -= maxsize; ! 679: i++; ! 680: } ! 681: else { ! 682: if(write(1, &cbuf[i*maxsize*2], n*2) != n*2) ! 683: return(-1); ! 684: n=0; /* last buffer so don't loop anymore */ ! 685: } ! 686: } ! 687: return(j); /* all correct so return number of actual characters sent */ ! 688: } ! 689: } ! 690: ! 691: realread(a, n) ! 692: char *a; ! 693: { ! 694: char cbuf[2]; ! 695: int i; ! 696: ! 697: if((Loadtype == BINARY_LOAD) || mpx){ ! 698: return(read(0, a, n)); ! 699: } ! 700: else { ! 701: for(i = 0; i < n ; i++) { ! 702: if(read(0, cbuf, 2) != 2) ! 703: return(-1); ! 704: *a++ = (cbuf[0] & 0xf) | ((cbuf[1] & 0xf) << 4); ! 705: } ! 706: return(n); ! 707: } ! 708: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.