123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- enum
- {
- Doff= 4, /* offset into Cpline.bytes of data */
- Memsize= 1<<16, /* max size of 186 memory */
- };
- int dump, image, noload, nostart;
- typedef struct
- {
- int type;
- int dlen;
- ulong addr;
- uchar bytes[256+4];
- uchar csum;
- } Cpline;
- char* rdcpline(Biobuf*, Cpline*);
- void clearmem(int);
- void
- usage(void)
- {
- fprint(2, "usage: %s [-0123] file\n", argv0);
- exits("usage");
- }
- static void
- loadimage(char* file, int mfd)
- {
- uchar buf[256];
- int fd, n, r;
- if((fd = open(file, OREAD)) < 0)
- sysfatal("opening %s: %r", file);
- seek(mfd, 0, 0);
- do{
- n = read(fd, buf, sizeof(buf));
- if(n < 0)
- sysfatal("read %s: %r", file);
- if(n > 0)
- if((r = write(mfd, buf, n)) != n)
- sysfatal("write %s: %d != %d: %r", file, n, r);
- }while(n > 0);
- close(fd);
- }
- static void
- loadhex(char* file, int mfd)
- {
- int done;
- Cpline c;
- Biobuf *b;
- char *err;
- ulong addr, seg;
- int lineno;
- uchar buf[1024];
- b = Bopen(file, OREAD);
- if(b == 0)
- sysfatal("opening %s: %r", file);
- lineno = 1;
- seg = 0;
- for(done = 0; !done; lineno++){
- err = rdcpline(b, &c);
- if(err)
- sysfatal("%s line %d: %s", file, lineno, err);
- switch(c.type){
- case 0: /* data */
- addr = seg + c.addr;
- if(addr + c.dlen > Memsize)
- sysfatal("addr out of range: %lux-%lux", addr, addr+c.dlen);
- if(seek(mfd, addr, 0) < 0)
- sysfatal("seeking to %lud: %r", addr);
- if(write(mfd, c.bytes+Doff, c.dlen) != c.dlen)
- sysfatal("writing: %r");
- if(seek(mfd, addr, 0) < 0)
- sysfatal("seeking to %lud: %r", addr);
- if(read(mfd, buf, c.dlen) != c.dlen)
- sysfatal("reading: %r");
- if(memcmp(buf, c.bytes+Doff, c.dlen) != 0)
- print("readback error at %lux\n", addr);
- if(dump)
- print("%8.8lux: %d\n", addr, c.dlen);
- break;
- case 1: /* termination */
- done = 1;
- break;
- case 2: /* segment */
- seg = ((c.bytes[Doff]<<8) | c.bytes[Doff+1]) <<4;
- if(seg >= Memsize)
- sysfatal("seg out of range: %lux", seg);
- if(dump)
- print("seg %8.8lux\n", seg);
- break;
- default: /* ignore */
- if(dump)
- print("bad type %d\n", c.type);
- break;
- }
- }
- Bterm(b);
- }
- void
- main(int argc, char **argv)
- {
- int unit;
- int cfd, mfd;
- char file[128];
- unit = 0;
- ARGBEGIN{
- case 'd':
- dump = 1;
- break;
- case 'i':
- image = 1;
- break;
- case 'n':
- noload = 1;
- break;
- case 's':
- nostart = 1;
- break;
- case '0':
- unit = 0;
- break;
- case '1':
- unit = 1;
- break;
- case '2':
- unit = 2;
- break;
- case '3':
- unit = 3;
- break;
- }ARGEND;
- if(argc == 0)
- usage();
- if(noload == 0){
- sprint(file, "#G/astar%dctl", unit);
- cfd = open(file, ORDWR);
- if(cfd < 0)
- sysfatal("opening %s\n", file);
- sprint(file, "#G/astar%dmem", unit);
- mfd = open(file, ORDWR);
- if(mfd < 0)
- sysfatal("opening %s\n", file);
-
- if(write(cfd, "download", 8) != 8)
- sysfatal("requesting download: %r");
- } else {
- cfd = -1;
- mfd = create("/tmp/astarmem", ORDWR, 0664);
- if(mfd < 0)
- sysfatal("creating /tmp/astarmem: %r");
- }
- if(image)
- loadimage(argv[0], mfd);
- else{
- /* zero out the memory */
- clearmem(mfd);
- loadhex(argv[0], mfd);
- }
- close(mfd);
- if(noload == 0 && nostart == 0)
- if(write(cfd, "run", 3) != 3)
- sysfatal("requesting run: %r");
- close(cfd);
- exits(0);
- }
- void
- clearmem(int fd)
- {
- char buf[4096];
- char buf2[4096];
- int i, n;
- memset(buf, 0, sizeof buf);
- for(i = 0; i < Memsize; i += n){
- if(seek(fd, i, 0) < 0)
- sysfatal("seeking to %ux: %r", i);
- n = write(fd, buf, sizeof buf);
- if(n <= 0)
- break;
- if(seek(fd, i, 0) < 0)
- sysfatal("seeking to %ux: %r", i);
- n = read(fd, buf2, sizeof buf2);
- if(n <= 0)
- break;
- if(memcmp(buf, buf2, sizeof buf) != 0)
- print("error zeroing mem at %ux\n", i);
- }
- print("zero'd %d bytes\n", i);
- }
- int
- hex(char c)
- {
- if(c <= '9' && c >= '0')
- return c - '0';
- if(c <= 'f' && c >= 'a')
- return (c - 'a') + 10;
- if(c <= 'F' && c >= 'A')
- return (c - 'A') + 10;
- return -1;
- }
- char*
- rdcpline(Biobuf *b, Cpline *cpl)
- {
- char *cp, *ep, *p;
- uchar *up;
- uchar csum;
- int c;
- cp = Brdline(b, '\n');
- if(cp == 0)
- return "early eof";
- ep = cp + Blinelen(b);
- if(*cp++ != ':')
- return "bad load line";
- csum = 0;
- up = cpl->bytes;
- for(p = cp; p < ep;){
- c = hex(*p++)<<4;
- c |= hex(*p++);
- if(c < 0)
- break;
- csum += c;
- *up++ = c;
- }
- cpl->csum = csum;
- if(csum != 0){
- fprint(2, "checksum %ux\n", csum);
- return "bad checksum";
- }
- cpl->dlen = cpl->bytes[0];
- if(cpl->dlen + 5 != up - cpl->bytes){
- fprint(2, "%d %ld\n", cpl->dlen + 5, up - cpl->bytes);
- return "bad data length";
- }
- cpl->addr = (cpl->bytes[1]<<8) | cpl->bytes[2];
- cpl->type = cpl->bytes[3];
- return 0;
- }
|