Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
 
5
enum
6
{
7
	Doff=		4,	/* offset into Cpline.bytes of data */
8
 
9
	Memsize=	1<<16,	/* max size of 186 memory */
10
};
11
 
12
int dump, image, noload, nostart;
13
 
14
typedef struct
15
{
16
	int	type;
17
	int	dlen;
18
	ulong	addr;
19
	uchar	bytes[256+4];
20
	uchar	csum;
21
} Cpline;
22
 
23
char*	rdcpline(Biobuf*, Cpline*);
24
void	clearmem(int);
25
 
26
void
27
usage(void)
28
{
29
	fprint(2, "usage: %s [-0123] file\n", argv0);
30
	exits("usage");
31
}
32
 
33
static void
34
loadimage(char* file, int mfd)
35
{
36
	uchar buf[256];
37
	int fd, n, r;
38
 
39
	if((fd = open(file, OREAD)) < 0)
40
		sysfatal("opening %s: %r", file);
41
 
42
	seek(mfd, 0, 0);
43
	do{
44
		n = read(fd, buf, sizeof(buf));
45
		if(n < 0)
46
			sysfatal("read %s: %r", file);
47
		if(n > 0)
48
			if((r = write(mfd, buf, n)) != n)
49
				sysfatal("write %s: %d != %d: %r", file, n, r);
50
	}while(n > 0);
51
	close(fd);
52
}
53
 
54
static void
55
loadhex(char* file, int mfd)
56
{
57
	int done;
58
	Cpline c;
59
	Biobuf *b;
60
	char *err;
61
	ulong addr, seg;
62
	int lineno;
63
	uchar buf[1024];
64
 
65
	b = Bopen(file, OREAD);
66
	if(b == 0)
67
		sysfatal("opening %s: %r", file);
68
 
69
	lineno = 1;
70
	seg = 0;
71
	for(done = 0; !done; lineno++){
72
		err = rdcpline(b, &c);
73
		if(err)
74
			sysfatal("%s line %d: %s", file, lineno, err);
75
		switch(c.type){
76
		case 0: /* data */
77
			addr = seg + c.addr;
78
			if(addr + c.dlen > Memsize)
79
				sysfatal("addr out of range: %lux-%lux", addr, addr+c.dlen);
80
			if(seek(mfd, addr, 0) < 0)
81
				sysfatal("seeking to %lud: %r", addr);
82
			if(write(mfd, c.bytes+Doff, c.dlen) != c.dlen)
83
				sysfatal("writing: %r");
84
			if(seek(mfd, addr, 0) < 0)
85
				sysfatal("seeking to %lud: %r", addr);
86
			if(read(mfd, buf, c.dlen) != c.dlen)
87
				sysfatal("reading: %r");
88
			if(memcmp(buf, c.bytes+Doff, c.dlen) != 0)
89
				print("readback error at %lux\n", addr);
90
			if(dump)
91
				print("%8.8lux: %d\n", addr, c.dlen);
92
			break;
93
		case 1: /* termination */
94
			done = 1;
95
			break;
96
		case 2: /* segment */
97
			seg = ((c.bytes[Doff]<<8) | c.bytes[Doff+1]) <<4;
98
			if(seg >= Memsize)
99
				sysfatal("seg out of range: %lux", seg);
100
			if(dump)
101
				print("seg %8.8lux\n", seg);
102
			break;
103
		default: /* ignore */
104
			if(dump)
105
				print("bad type %d\n", c.type);
106
			break;
107
		}
108
	}
109
	Bterm(b);
110
}
111
 
112
void
113
main(int argc, char **argv)
114
{
115
	int unit;
116
	int cfd, mfd;
117
	char file[128];
118
 
119
	unit = 0;
120
	ARGBEGIN{
121
	case 'd':
122
		dump = 1;
123
		break;
124
	case 'i':
125
		image = 1;
126
		break;
127
	case 'n':
128
		noload = 1;
129
		break;
130
	case 's':
131
		nostart = 1;
132
		break;
133
	case '0':
134
		unit = 0;
135
		break;
136
	case '1':
137
		unit = 1;
138
		break;
139
	case '2':
140
		unit = 2;
141
		break;
142
	case '3':
143
		unit = 3;
144
		break;
145
	}ARGEND;
146
 
147
	if(argc == 0)
148
		usage();
149
 
150
	if(noload == 0){
151
		sprint(file, "#G/astar%dctl", unit);
152
		cfd = open(file, ORDWR);
153
		if(cfd < 0)
154
			sysfatal("opening %s", file);
155
		sprint(file, "#G/astar%dmem", unit);
156
		mfd = open(file, ORDWR);
157
		if(mfd < 0)
158
			sysfatal("opening %s", file);
159
 
160
		if(write(cfd, "download", 8) != 8)
161
			sysfatal("requesting download: %r");
162
	} else {
163
		cfd = -1;
164
		mfd = create("/tmp/astarmem", ORDWR, 0664);
165
		if(mfd < 0)
166
			sysfatal("creating /tmp/astarmem: %r");
167
	}
168
 
169
	if(image)
170
		loadimage(argv[0], mfd);
171
	else{
172
		/* zero out the memory */
173
		clearmem(mfd);
174
		loadhex(argv[0], mfd);
175
	}
176
	close(mfd);
177
 
178
	if(noload == 0 && nostart == 0)
179
		if(write(cfd, "run", 3) != 3)
180
			sysfatal("requesting run: %r");
181
	close(cfd);
182
 
183
	exits(0);
184
}
185
 
186
void
187
clearmem(int fd)
188
{
189
	char buf[4096];
190
	char buf2[4096];
191
	int i, n;
192
 
193
	memset(buf, 0, sizeof buf);
194
	for(i = 0; i < Memsize; i += n){
195
		if(seek(fd, i, 0) < 0)
196
			sysfatal("seeking to %ux: %r", i);
197
		n = write(fd, buf, sizeof buf);
198
		if(n <= 0)
199
			break;
200
		if(seek(fd, i, 0) < 0)
201
			sysfatal("seeking to %ux: %r", i);
202
		n = read(fd, buf2, sizeof buf2);
203
		if(n <= 0)
204
			break;
205
		if(memcmp(buf, buf2, sizeof buf) != 0)
206
			print("error zeroing mem at %ux\n", i);
207
	}
208
	print("zero'd %d bytes\n", i);
209
}
210
 
211
int
212
hex(char c)
213
{
214
	if(c <= '9' && c >= '0')
215
		return c - '0';
216
	if(c <= 'f' && c >= 'a')
217
		return (c - 'a') + 10;
218
	if(c <= 'F' && c >= 'A')
219
		return (c - 'A') + 10;
220
	return -1;
221
}
222
 
223
char*
224
rdcpline(Biobuf *b, Cpline *cpl)
225
{
226
	char *cp, *ep, *p;
227
	uchar *up;
228
	uchar csum;
229
	int c;
230
 
231
	cp = Brdline(b, '\n');
232
	if(cp == 0)
233
		return "early eof";
234
	ep = cp + Blinelen(b);
235
 
236
	if(*cp++ != ':')
237
		return "bad load line";
238
 
239
	csum = 0;
240
	up = cpl->bytes;
241
 	for(p = cp; p < ep;){
242
		c = hex(*p++)<<4;
243
		c |= hex(*p++);
244
		if(c < 0)
245
			break;
246
		csum += c;
247
		*up++ = c;
248
	}
249
 
250
	cpl->csum = csum;
251
	if(csum != 0){
252
		fprint(2, "checksum %ux\n", csum);
253
		return "bad checksum";
254
	}
255
 
256
	cpl->dlen = cpl->bytes[0];
257
	if(cpl->dlen + 5 != up - cpl->bytes){
258
		fprint(2, "%d %ld\n", cpl->dlen + 5, up - cpl->bytes);
259
		return "bad data length";
260
	}
261
 
262
	cpl->addr = (cpl->bytes[1]<<8) | cpl->bytes[2];
263
	cpl->type = cpl->bytes[3];
264
	return 0;
265
}