13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 33e12c5d1SDavid du Colombier #include <a.out.h> 43e12c5d1SDavid du Colombier #include <bio.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; 17*219b2ee8SDavid du Colombier int binary; 183e12c5d1SDavid du Colombier ulong addr; 193e12c5d1SDavid du Colombier ulong psize = 4096; 203e12c5d1SDavid du Colombier Biobuf stdout; 213e12c5d1SDavid du Colombier Exec exech; 223e12c5d1SDavid du Colombier Biobuf *bio; 233e12c5d1SDavid du Colombier 243e12c5d1SDavid du Colombier void 253e12c5d1SDavid du Colombier main(int argc, char **argv) 263e12c5d1SDavid du Colombier { 273e12c5d1SDavid du Colombier int n; 28*219b2ee8SDavid du Colombier Dir dir; 293e12c5d1SDavid du Colombier 303e12c5d1SDavid du Colombier ARGBEGIN{ 313e12c5d1SDavid du Colombier case 'd': 323e12c5d1SDavid du Colombier dsegonly++; 333e12c5d1SDavid du Colombier break; 343e12c5d1SDavid du Colombier case 's': 353e12c5d1SDavid du Colombier supressend++; 363e12c5d1SDavid du Colombier break; 373e12c5d1SDavid du Colombier case 'a': 383e12c5d1SDavid du Colombier addr = strtoul(ARGF(), 0, 0); 393e12c5d1SDavid du Colombier break; 403e12c5d1SDavid du Colombier case 'p': 413e12c5d1SDavid du Colombier psize = strtoul(ARGF(), 0, 0); 423e12c5d1SDavid du Colombier break; 43*219b2ee8SDavid du Colombier case 'b': 44*219b2ee8SDavid du Colombier binary++; 45*219b2ee8SDavid du Colombier break; 463e12c5d1SDavid du Colombier default: 473e12c5d1SDavid du Colombier usage(); 483e12c5d1SDavid du Colombier }ARGEND 493e12c5d1SDavid du Colombier 503e12c5d1SDavid du Colombier if(argc != 1) 513e12c5d1SDavid du Colombier usage(); 523e12c5d1SDavid du Colombier 533e12c5d1SDavid du Colombier Binit(&stdout, 1, OWRITE); 543e12c5d1SDavid du Colombier 553e12c5d1SDavid du Colombier bio = Bopen(argv[0], OREAD); 563e12c5d1SDavid du Colombier if(bio == 0) { 573e12c5d1SDavid du Colombier fprint(2, "ms2: open %s: %r\n", argv[0]); 583e12c5d1SDavid du Colombier exits("open"); 593e12c5d1SDavid du Colombier } 603e12c5d1SDavid du Colombier 61*219b2ee8SDavid du Colombier if(binary) { 62*219b2ee8SDavid du Colombier if(dirfstat(Bfildes(bio), &dir) < 0) { 63*219b2ee8SDavid du Colombier fprint(2, "ms2: stat failed %r"); 64*219b2ee8SDavid du Colombier exits("dirfstat"); 65*219b2ee8SDavid du Colombier } 66*219b2ee8SDavid du Colombier segment(0, dir.length); 67*219b2ee8SDavid du Colombier Bprint(&stdout, "S9030000FC\n"); 68*219b2ee8SDavid du Colombier Bterm(&stdout); 69*219b2ee8SDavid du Colombier Bterm(bio); 70*219b2ee8SDavid du Colombier exits(0); 71*219b2ee8SDavid du Colombier } 72*219b2ee8SDavid du Colombier 733e12c5d1SDavid du Colombier n = Bread(bio, &exech, sizeof(Exec)); 743e12c5d1SDavid du Colombier if(n != sizeof(Exec)) { 753e12c5d1SDavid du Colombier fprint(2, "ms2: read failed: %r\n"); 763e12c5d1SDavid du Colombier exits("read"); 773e12c5d1SDavid du Colombier } 783e12c5d1SDavid du Colombier 793e12c5d1SDavid du Colombier switch(exech.magic) { 803e12c5d1SDavid du Colombier default: 813e12c5d1SDavid du Colombier fprint(2, "ms2: bad magic\n"); 823e12c5d1SDavid du Colombier exits("magic"); 833e12c5d1SDavid du Colombier case A_MAGIC: 843e12c5d1SDavid du Colombier case I_MAGIC: 853e12c5d1SDavid du Colombier case J_MAGIC: 863e12c5d1SDavid du Colombier case K_MAGIC: 873e12c5d1SDavid du Colombier case V_MAGIC: 883e12c5d1SDavid du Colombier break; 893e12c5d1SDavid du Colombier } 903e12c5d1SDavid du Colombier 913e12c5d1SDavid du Colombier if(dsegonly) 923e12c5d1SDavid du Colombier segment(exech.text+sizeof(exech), exech.data); 933e12c5d1SDavid du Colombier else { 943e12c5d1SDavid du Colombier segment(sizeof(exech), exech.text); 953e12c5d1SDavid du Colombier addr = (addr+(psize-1))&~(psize-1); 963e12c5d1SDavid du Colombier segment(exech.text+sizeof(exech), exech.data); 973e12c5d1SDavid du Colombier } 983e12c5d1SDavid du Colombier 993e12c5d1SDavid du Colombier if(supressend == 0) 1003e12c5d1SDavid du Colombier Bprint(&stdout, "S9030000FC\n"); 1013e12c5d1SDavid du Colombier 102*219b2ee8SDavid du Colombier Bterm(&stdout); 103*219b2ee8SDavid du Colombier Bterm(bio); 1043e12c5d1SDavid du Colombier exits(0); 1053e12c5d1SDavid du Colombier } 1063e12c5d1SDavid du Colombier 1073e12c5d1SDavid du Colombier void 1083e12c5d1SDavid du Colombier segment(long foff, int len) 1093e12c5d1SDavid du Colombier { 1103e12c5d1SDavid du Colombier int l, n; 1113e12c5d1SDavid du Colombier uchar buf[2*Recordsize]; 1123e12c5d1SDavid du Colombier 1133e12c5d1SDavid du Colombier Bseek(bio, foff, 0); 1143e12c5d1SDavid du Colombier for(;;) { 1153e12c5d1SDavid du Colombier l = len; 1163e12c5d1SDavid du Colombier if(l > Recordsize) 1173e12c5d1SDavid du Colombier l = Recordsize; 1183e12c5d1SDavid du Colombier n = Bread(bio, buf, l); 1193e12c5d1SDavid du Colombier if(n == 0) 1203e12c5d1SDavid du Colombier break; 1213e12c5d1SDavid du Colombier if(n < 0) { 1223e12c5d1SDavid du Colombier fprint(2, "ms2: read error: %r\n"); 1233e12c5d1SDavid du Colombier exits("read"); 1243e12c5d1SDavid du Colombier } 1253e12c5d1SDavid du Colombier record(buf, l); 1263e12c5d1SDavid du Colombier len -= l; 1273e12c5d1SDavid du Colombier } 1283e12c5d1SDavid du Colombier } 1293e12c5d1SDavid du Colombier 1303e12c5d1SDavid du Colombier void 1313e12c5d1SDavid du Colombier record(uchar *s, int l) 1323e12c5d1SDavid du Colombier { 1333e12c5d1SDavid du Colombier int i; 1343e12c5d1SDavid du Colombier ulong cksum; 1353e12c5d1SDavid du Colombier 1363e12c5d1SDavid du Colombier cksum = l+4; 1373e12c5d1SDavid du Colombier Bprint(&stdout, "S2%.2X%.6X", l+4, addr); 1383e12c5d1SDavid du Colombier cksum += addr&0xff; 1393e12c5d1SDavid du Colombier cksum += (addr>>8)&0xff; 1403e12c5d1SDavid du Colombier cksum += (addr>>16)&0xff; 1413e12c5d1SDavid du Colombier 1423e12c5d1SDavid du Colombier for(i = 0; i < l; i++) { 1433e12c5d1SDavid du Colombier cksum += *s; 1443e12c5d1SDavid du Colombier Bprint(&stdout, "%.2X", *s++); 1453e12c5d1SDavid du Colombier } 1463e12c5d1SDavid du Colombier Bprint(&stdout, "%.2X\n", (~cksum)&0xff); 1473e12c5d1SDavid du Colombier addr += l; 1483e12c5d1SDavid du Colombier } 1493e12c5d1SDavid du Colombier 1503e12c5d1SDavid du Colombier void 1513e12c5d1SDavid du Colombier usage(void) 1523e12c5d1SDavid du Colombier { 1533e12c5d1SDavid du Colombier fprint(2, "usage: ms2 [-ds] [-a address] [-p pagesize] ?.out\n"); 1543e12c5d1SDavid du Colombier exits("usage"); 1553e12c5d1SDavid du Colombier } 156