/*%cc -n -O % -o comhex * comhex - convert .com files to (intel) .hex format * * operates just like 'cat' * */ #include #include #include char stdbuf[BUFSIZ]; main(argc, argv) char **argv; { int fflg = 0; register FILE *fi; register c; register cx; int ccount; int address; int checksum; int dev, ino = -1; struct stat statb; setbuf(stdout, stdbuf); for( ; argc>1 && argv[1][0]=='-'; argc--,argv++) { switch(argv[1][1]) { case 0: break; case 'u': setbuf(stdout, (char *)NULL); continue; } break; } fstat(fileno(stdout), &statb); statb.st_mode &= S_IFMT; if (statb.st_mode!=S_IFCHR && statb.st_mode!=S_IFBLK) { dev = statb.st_dev; ino = statb.st_ino; } if (argc < 2) { argc = 2; fflg++; } while (--argc > 0) { if (fflg || (*++argv)[0]=='-' && (*argv)[1]=='\0') fi = stdin; else { if ((fi = fopen(*argv, "r")) == NULL) { fprintf(stderr, "comhex: can't open %s\n", *argv); continue; } } fstat(fileno(fi), &statb); if (statb.st_dev==dev && statb.st_ino==ino) { fprintf(stderr, "comhex: input %s is output\n", fflg?"-": *argv); fclose(fi); continue; } ccount = 0; address = 0x0100; /* cpm load offset */ while ((c = getc(fi)) != EOF){ if (ccount < 1){ printf(":10"); /* lead-in, 16 bytes follow */ puthex(address,4); /* first address */ printf("00"); /* record type */ checksum = (address/256) + (address%256) + 16; } cx = (c & 0x00ff); puthex(cx,2); /* the byte in two nibbles */ checksum += cx; ccount++; address++; if (ccount > 15){ checksum = -checksum; puthex( checksum, 2); /* the checksum */ printf("\n"); checksum = 0; ccount = 0; } } printf(":0000000000\n"); /* this is the end record */ if (fi!=stdin) fclose(fi); } return(0); } puthex(cx,cols) int cx; int cols; { char h; int i; int pos; for (i = 0; i < cols; i++){ pos = cols - i - 1; h = ((cx >> (pos * 4)) & 0x000f); h = h + (h < 10 ? '0' : '7'); putchar( h & 0x7f); } }