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