13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 33e12c5d1SDavid du Colombier #include <bio.h> 4*7dd7cddfSDavid du Colombier #include <mach.h> 53e12c5d1SDavid du Colombier 63e12c5d1SDavid du Colombier void record(uchar*, int); 73e12c5d1SDavid du Colombier void usage(void); 83e12c5d1SDavid du Colombier void segment(long, int); 93e12c5d1SDavid du Colombier 103e12c5d1SDavid du Colombier enum 113e12c5d1SDavid du Colombier { 123e12c5d1SDavid du Colombier Recordsize = 32, 133e12c5d1SDavid du Colombier }; 143e12c5d1SDavid du Colombier 153e12c5d1SDavid du Colombier int dsegonly; 163e12c5d1SDavid du Colombier int supressend; 17219b2ee8SDavid du Colombier int binary; 18*7dd7cddfSDavid du Colombier int halfswap; 19*7dd7cddfSDavid du Colombier int srec = 2; 203e12c5d1SDavid du Colombier ulong addr; 213e12c5d1SDavid du Colombier ulong psize = 4096; 223e12c5d1SDavid du Colombier Biobuf stdout; 23*7dd7cddfSDavid du Colombier Fhdr exech; 243e12c5d1SDavid du Colombier Biobuf *bio; 253e12c5d1SDavid du Colombier 263e12c5d1SDavid du Colombier void 273e12c5d1SDavid du Colombier main(int argc, char **argv) 283e12c5d1SDavid du Colombier { 29219b2ee8SDavid du Colombier Dir dir; 30*7dd7cddfSDavid du Colombier ulong totsz; 313e12c5d1SDavid du Colombier 323e12c5d1SDavid du Colombier ARGBEGIN{ 333e12c5d1SDavid du Colombier case 'd': 343e12c5d1SDavid du Colombier dsegonly++; 353e12c5d1SDavid du Colombier break; 363e12c5d1SDavid du Colombier case 's': 373e12c5d1SDavid du Colombier supressend++; 383e12c5d1SDavid du Colombier break; 393e12c5d1SDavid du Colombier case 'a': 403e12c5d1SDavid du Colombier addr = strtoul(ARGF(), 0, 0); 413e12c5d1SDavid du Colombier break; 423e12c5d1SDavid du Colombier case 'p': 433e12c5d1SDavid du Colombier psize = strtoul(ARGF(), 0, 0); 443e12c5d1SDavid du Colombier break; 45219b2ee8SDavid du Colombier case 'b': 46219b2ee8SDavid du Colombier binary++; 47219b2ee8SDavid du Colombier break; 48*7dd7cddfSDavid du Colombier case 'h': 49*7dd7cddfSDavid du Colombier halfswap++; 50*7dd7cddfSDavid du Colombier break; 51*7dd7cddfSDavid du Colombier case '1': 52*7dd7cddfSDavid du Colombier srec = 1; 53*7dd7cddfSDavid du Colombier break; 54*7dd7cddfSDavid du Colombier case '2': 55*7dd7cddfSDavid du Colombier srec = 2; 56*7dd7cddfSDavid du Colombier break; 57*7dd7cddfSDavid du Colombier case '3': 58*7dd7cddfSDavid du Colombier srec = 3; 59*7dd7cddfSDavid du Colombier break; 603e12c5d1SDavid du Colombier default: 613e12c5d1SDavid du Colombier usage(); 623e12c5d1SDavid du Colombier }ARGEND 633e12c5d1SDavid du Colombier 643e12c5d1SDavid du Colombier if(argc != 1) 653e12c5d1SDavid du Colombier usage(); 663e12c5d1SDavid du Colombier 673e12c5d1SDavid du Colombier Binit(&stdout, 1, OWRITE); 683e12c5d1SDavid du Colombier 693e12c5d1SDavid du Colombier bio = Bopen(argv[0], OREAD); 703e12c5d1SDavid du Colombier if(bio == 0) { 713e12c5d1SDavid du Colombier fprint(2, "ms2: open %s: %r\n", argv[0]); 723e12c5d1SDavid du Colombier exits("open"); 733e12c5d1SDavid du Colombier } 743e12c5d1SDavid du Colombier 75219b2ee8SDavid du Colombier if(binary) { 76219b2ee8SDavid du Colombier if(dirfstat(Bfildes(bio), &dir) < 0) { 77219b2ee8SDavid du Colombier fprint(2, "ms2: stat failed %r"); 78219b2ee8SDavid du Colombier exits("dirfstat"); 79219b2ee8SDavid du Colombier } 80219b2ee8SDavid du Colombier segment(0, dir.length); 81219b2ee8SDavid du Colombier Bprint(&stdout, "S9030000FC\n"); 82219b2ee8SDavid du Colombier Bterm(&stdout); 83219b2ee8SDavid du Colombier Bterm(bio); 84219b2ee8SDavid du Colombier exits(0); 85219b2ee8SDavid du Colombier } 86219b2ee8SDavid du Colombier 87*7dd7cddfSDavid du Colombier if(!crackhdr(Bfildes(bio), &exech)) { 88*7dd7cddfSDavid du Colombier fprint(2, "ms2: can't decode file header\n"); 89*7dd7cddfSDavid du Colombier return; 903e12c5d1SDavid du Colombier } 913e12c5d1SDavid du Colombier 92*7dd7cddfSDavid du Colombier totsz = exech.txtsz + exech.datsz + exech.bsssz; 93*7dd7cddfSDavid du Colombier fprint(2, "%s: %lud+%lud+%lud=%lud\n", 94*7dd7cddfSDavid du Colombier exech.name, exech.txtsz, exech.datsz, exech.bsssz, totsz); 953e12c5d1SDavid du Colombier 963e12c5d1SDavid du Colombier if(dsegonly) 97*7dd7cddfSDavid du Colombier segment(exech.datoff, exech.datsz); 983e12c5d1SDavid du Colombier else { 99*7dd7cddfSDavid du Colombier segment(exech.txtoff, exech.txtsz); 1003e12c5d1SDavid du Colombier addr = (addr+(psize-1))&~(psize-1); 101*7dd7cddfSDavid du Colombier segment(exech.datoff, exech.datsz); 1023e12c5d1SDavid du Colombier } 1033e12c5d1SDavid du Colombier 104*7dd7cddfSDavid du Colombier if(supressend == 0) { 105*7dd7cddfSDavid du Colombier switch(srec) { 106*7dd7cddfSDavid du Colombier case 1: 107*7dd7cddfSDavid du Colombier case 2: 1083e12c5d1SDavid du Colombier Bprint(&stdout, "S9030000FC\n"); 109*7dd7cddfSDavid du Colombier break; 110*7dd7cddfSDavid du Colombier case 3: 111*7dd7cddfSDavid du Colombier Bprint(&stdout, "S705000000FA\n"); 112*7dd7cddfSDavid du Colombier break; 113*7dd7cddfSDavid du Colombier } 114*7dd7cddfSDavid du Colombier } 1153e12c5d1SDavid du Colombier 116219b2ee8SDavid du Colombier Bterm(&stdout); 117219b2ee8SDavid du Colombier Bterm(bio); 1183e12c5d1SDavid du Colombier exits(0); 1193e12c5d1SDavid du Colombier } 1203e12c5d1SDavid du Colombier 1213e12c5d1SDavid du Colombier void 1223e12c5d1SDavid du Colombier segment(long foff, int len) 1233e12c5d1SDavid du Colombier { 124*7dd7cddfSDavid du Colombier int l, n, i; 125*7dd7cddfSDavid du Colombier uchar t, buf[2*Recordsize]; 1263e12c5d1SDavid du Colombier 1273e12c5d1SDavid du Colombier Bseek(bio, foff, 0); 1283e12c5d1SDavid du Colombier for(;;) { 1293e12c5d1SDavid du Colombier l = len; 1303e12c5d1SDavid du Colombier if(l > Recordsize) 1313e12c5d1SDavid du Colombier l = Recordsize; 1323e12c5d1SDavid du Colombier n = Bread(bio, buf, l); 1333e12c5d1SDavid du Colombier if(n == 0) 1343e12c5d1SDavid du Colombier break; 1353e12c5d1SDavid du Colombier if(n < 0) { 1363e12c5d1SDavid du Colombier fprint(2, "ms2: read error: %r\n"); 1373e12c5d1SDavid du Colombier exits("read"); 1383e12c5d1SDavid du Colombier } 139*7dd7cddfSDavid du Colombier if(halfswap) { 140*7dd7cddfSDavid du Colombier if(n & 1) { 141*7dd7cddfSDavid du Colombier fprint(2, "ms2: data must be even length\n"); 142*7dd7cddfSDavid du Colombier exits("even"); 143*7dd7cddfSDavid du Colombier } 144*7dd7cddfSDavid du Colombier for(i = 0; i < n; i += 2) { 145*7dd7cddfSDavid du Colombier t = buf[i]; 146*7dd7cddfSDavid du Colombier buf[i] = buf[i+1]; 147*7dd7cddfSDavid du Colombier buf[i+1] = t; 148*7dd7cddfSDavid du Colombier } 149*7dd7cddfSDavid du Colombier } 1503e12c5d1SDavid du Colombier record(buf, l); 1513e12c5d1SDavid du Colombier len -= l; 1523e12c5d1SDavid du Colombier } 1533e12c5d1SDavid du Colombier } 1543e12c5d1SDavid du Colombier 1553e12c5d1SDavid du Colombier void 1563e12c5d1SDavid du Colombier record(uchar *s, int l) 1573e12c5d1SDavid du Colombier { 1583e12c5d1SDavid du Colombier int i; 159*7dd7cddfSDavid du Colombier ulong cksum = 0; 1603e12c5d1SDavid du Colombier 161*7dd7cddfSDavid du Colombier switch(srec) { 162*7dd7cddfSDavid du Colombier case 1: 163*7dd7cddfSDavid du Colombier cksum = l+3; 164*7dd7cddfSDavid du Colombier Bprint(&stdout, "S1%.2X%.4luX", l+3, addr); 165*7dd7cddfSDavid du Colombier cksum += addr&0xff; 166*7dd7cddfSDavid du Colombier cksum += (addr>>8)&0xff; 167*7dd7cddfSDavid du Colombier break; 168*7dd7cddfSDavid du Colombier case 2: 1693e12c5d1SDavid du Colombier cksum = l+4; 170*7dd7cddfSDavid du Colombier Bprint(&stdout, "S2%.2X%.6luX", l+4, addr); 1713e12c5d1SDavid du Colombier cksum += addr&0xff; 1723e12c5d1SDavid du Colombier cksum += (addr>>8)&0xff; 1733e12c5d1SDavid du Colombier cksum += (addr>>16)&0xff; 174*7dd7cddfSDavid du Colombier break; 175*7dd7cddfSDavid du Colombier case 3: 176*7dd7cddfSDavid du Colombier cksum = l+5; 177*7dd7cddfSDavid du Colombier Bprint(&stdout, "S3%.2X%.8luX", l+5, addr); 178*7dd7cddfSDavid du Colombier cksum += addr&0xff; 179*7dd7cddfSDavid du Colombier cksum += (addr>>8)&0xff; 180*7dd7cddfSDavid du Colombier cksum += (addr>>16)&0xff; 181*7dd7cddfSDavid du Colombier cksum += (addr>>24)&0xff; 182*7dd7cddfSDavid du Colombier break; 183*7dd7cddfSDavid du Colombier } 1843e12c5d1SDavid du Colombier 1853e12c5d1SDavid du Colombier for(i = 0; i < l; i++) { 1863e12c5d1SDavid du Colombier cksum += *s; 1873e12c5d1SDavid du Colombier Bprint(&stdout, "%.2X", *s++); 1883e12c5d1SDavid du Colombier } 189*7dd7cddfSDavid du Colombier Bprint(&stdout, "%.2luX\n", (~cksum)&0xff); 1903e12c5d1SDavid du Colombier addr += l; 1913e12c5d1SDavid du Colombier } 1923e12c5d1SDavid du Colombier 1933e12c5d1SDavid du Colombier void 1943e12c5d1SDavid du Colombier usage(void) 1953e12c5d1SDavid du Colombier { 196*7dd7cddfSDavid du Colombier fprint(2, "usage: ms2 [-dsbh] [-a address] [-p pagesize] ?.out\n"); 1973e12c5d1SDavid du Colombier exits("usage"); 1983e12c5d1SDavid du Colombier } 199