1 #include <lib9.h> 2 #include <bio.h> 3 #include <mach.h> 4 5 void record(uchar*, int); 6 void usage(void); 7 void dosegment(long, int); 8 void trailer(ulong); 9 void header(void); 10 11 enum 12 { 13 Recordsize = 32 14 }; 15 16 int dsegonly; 17 int supressend; 18 int binary; 19 ulong addr; 20 ulong psize = 4096; 21 ulong startaddr = 0x030000; 22 Biobuf bout; 23 Biobuf bio; 24 25 void 26 main(int argc, char **argv) 27 { 28 Dir *dir; 29 Fhdr f; 30 int fd; 31 32 ARGBEGIN{ 33 case 'd': 34 dsegonly++; 35 break; 36 case 's': 37 supressend++; 38 break; 39 case 'a': 40 case 'T': 41 addr = strtoul(ARGF(), 0, 0); 42 break; 43 case 'p': 44 case 'R': 45 psize = strtoul(ARGF(), 0, 0); 46 break; 47 case 'b': 48 binary++; 49 break; 50 case 'S': 51 startaddr = strtoul(ARGF(), 0, 0); 52 break; 53 default: 54 usage(); 55 }ARGEND 56 57 if(argc != 1) 58 usage(); 59 60 Binit(&bout, 1, OWRITE); 61 62 fd = open(argv[0], OREAD); 63 if(fd < 0) { 64 fprint(2, "ms2: open %s: %r\n", argv[0]); 65 exits("open"); 66 } 67 68 if(binary) { 69 if((dir = dirfstat(fd)) == nil) { 70 fprint(2, "ms2: stat failed %r"); 71 exits("dirfstat"); 72 } 73 Binit(&bio, fd, OREAD); 74 header(); 75 dosegment(0, dir->length); 76 if(supressend == 0) 77 trailer(startaddr); 78 Bterm(&bout); 79 Bterm(&bio); 80 free(dir); 81 exits(0); 82 } 83 84 if(crackhdr(fd, &f) == 0){ 85 fprint(2, "ms2: bad magic: %r\n"); 86 exits("magic"); 87 } 88 seek(fd, 0, 0); 89 90 Binit(&bio, fd, OREAD); 91 92 header(); 93 if(dsegonly) 94 dosegment(f.datoff, f.datsz); 95 else { 96 dosegment(f.txtoff, f.txtsz); 97 addr = (addr+(psize-1))&~(psize-1); 98 dosegment(f.datoff, f.datsz); 99 } 100 101 if(supressend == 0) 102 trailer(startaddr); 103 104 Bterm(&bout); 105 Bterm(&bio); 106 exits(0); 107 } 108 109 void 110 dosegment(long foff, int len) 111 { 112 int l, n; 113 uchar buf[2*Recordsize]; 114 115 Bseek(&bio, foff, 0); 116 for(;;) { 117 l = len; 118 if(l > Recordsize) 119 l = Recordsize; 120 n = Bread(&bio, buf, l); 121 if(n == 0) 122 break; 123 if(n < 0) { 124 fprint(2, "ms2: read error: %r\n"); 125 exits("read"); 126 } 127 record(buf, l); 128 len -= l; 129 } 130 } 131 132 void 133 record(uchar *s, int l) 134 { 135 int i; 136 ulong cksum; 137 138 if(addr & (0xFF<<24)){ 139 Bprint(&bout, "S3%.2X%.8lX", l+5, addr); 140 cksum = l+5; 141 cksum += (addr>>24)&0xff; 142 }else{ 143 Bprint(&bout, "S2%.2X%.6lX", l+4, addr); 144 cksum = l+4; 145 } 146 cksum += addr&0xff; 147 cksum += (addr>>8)&0xff; 148 cksum += (addr>>16)&0xff; 149 150 for(i = 0; i < l; i++) { 151 cksum += *s; 152 Bprint(&bout, "%.2X", *s++); 153 } 154 Bprint(&bout, "%.2lX\n", (~cksum)&0xff); 155 addr += l; 156 } 157 158 void 159 header(void) 160 { 161 Bprint(&bout, "S0030000FC\n"); 162 } 163 164 void 165 trailer(ulong a) 166 { 167 ulong cksum; 168 169 cksum = 0; 170 if(a & (0xFF<<24)){ 171 Bprint(&bout, "S7%.8lX", a); 172 cksum += (a>>24)&0xff; 173 }else 174 Bprint(&bout, "S9%.6lX", a); 175 cksum += a&0xff; 176 cksum += (a>>8)&0xff; 177 cksum += (a>>16)&0xff; 178 Bprint(&bout, "%.2lX\n", (~cksum)&0xff); 179 } 180 181 void 182 usage(void) 183 { 184 fprint(2, "usage: ms2 [-dsb] [-T address] [-R pagesize] [-S startaddress] ?.out\n"); 185 exits("usage"); 186 } 187