diff options
Diffstat (limited to 'utils/ms2/ms2.c')
| -rw-r--r-- | utils/ms2/ms2.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/utils/ms2/ms2.c b/utils/ms2/ms2.c new file mode 100644 index 00000000..e36307db --- /dev/null +++ b/utils/ms2/ms2.c @@ -0,0 +1,186 @@ +#include <lib9.h> +#include <bio.h> +#include <mach.h> + +void record(uchar*, int); +void usage(void); +void dosegment(long, int); +void trailer(ulong); +void header(void); + +enum +{ + Recordsize = 32 +}; + +int dsegonly; +int supressend; +int binary; +ulong addr; +ulong psize = 4096; +ulong startaddr = 0x030000; +Biobuf bout; +Biobuf bio; + +void +main(int argc, char **argv) +{ + Dir *dir; + Fhdr f; + int fd; + + ARGBEGIN{ + case 'd': + dsegonly++; + break; + case 's': + supressend++; + break; + case 'a': + case 'T': + addr = strtoul(ARGF(), 0, 0); + break; + case 'p': + case 'R': + psize = strtoul(ARGF(), 0, 0); + break; + case 'b': + binary++; + break; + case 'S': + startaddr = strtoul(ARGF(), 0, 0); + break; + default: + usage(); + }ARGEND + + if(argc != 1) + usage(); + + Binit(&bout, 1, OWRITE); + + fd = open(argv[0], OREAD); + if(fd < 0) { + fprint(2, "ms2: open %s: %r\n", argv[0]); + exits("open"); + } + + if(binary) { + if((dir = dirfstat(fd)) == nil) { + fprint(2, "ms2: stat failed %r"); + exits("dirfstat"); + } + Binit(&bio, fd, OREAD); + header(); + dosegment(0, dir->length); + if(supressend == 0) + trailer(startaddr); + Bterm(&bout); + Bterm(&bio); + free(dir); + exits(0); + } + + if(crackhdr(fd, &f) == 0){ + fprint(2, "ms2: bad magic: %r\n"); + exits("magic"); + } + seek(fd, 0, 0); + + Binit(&bio, fd, OREAD); + + header(); + if(dsegonly) + dosegment(f.datoff, f.datsz); + else { + dosegment(f.txtoff, f.txtsz); + addr = (addr+(psize-1))&~(psize-1); + dosegment(f.datoff, f.datsz); + } + + if(supressend == 0) + trailer(startaddr); + + Bterm(&bout); + Bterm(&bio); + exits(0); +} + +void +dosegment(long foff, int len) +{ + int l, n; + uchar buf[2*Recordsize]; + + Bseek(&bio, foff, 0); + for(;;) { + l = len; + if(l > Recordsize) + l = Recordsize; + n = Bread(&bio, buf, l); + if(n == 0) + break; + if(n < 0) { + fprint(2, "ms2: read error: %r\n"); + exits("read"); + } + record(buf, l); + len -= l; + } +} + +void +record(uchar *s, int l) +{ + int i; + ulong cksum; + + if(addr & (0xFF<<24)){ + Bprint(&bout, "S3%.2X%.8X", l+5, addr); + cksum = l+5; + cksum += (addr>>24)&0xff; + }else{ + Bprint(&bout, "S2%.2X%.6X", l+4, addr); + cksum = l+4; + } + cksum += addr&0xff; + cksum += (addr>>8)&0xff; + cksum += (addr>>16)&0xff; + + for(i = 0; i < l; i++) { + cksum += *s; + Bprint(&bout, "%.2X", *s++); + } + Bprint(&bout, "%.2X\n", (~cksum)&0xff); + addr += l; +} + +void +header(void) +{ + Bprint(&bout, "S0030000FC\n"); +} + +void +trailer(ulong a) +{ + ulong cksum; + + cksum = 0; + if(a & (0xFF<<24)){ + Bprint(&bout, "S7%.8X", a); + cksum += (a>>24)&0xff; + }else + Bprint(&bout, "S9%.6X", a); + cksum += a&0xff; + cksum += (a>>8)&0xff; + cksum += (a>>16)&0xff; + Bprint(&bout, "%.2X\n", (~cksum)&0xff); +} + +void +usage(void) +{ + fprint(2, "usage: ms2 [-dsb] [-T address] [-R pagesize] [-S startaddress] ?.out\n"); + exits("usage"); +} |
