Charles.Forsyth20060303644188019 years agoHistory
186 lines · 2.7 KB · C
RawDownload
#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; voidmain(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);} voiddosegment(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;	}} voidrecord(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;} voidheader(void){	Bprint(&bout, "S0030000FC\n");} voidtrailer(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);} voidusage(void){	fprint(2, "usage: ms2 [-dsb] [-T address] [-R pagesize] [-S startaddress] ?.out\n");	exits("usage");}