Pristine Ack-5.5
[Ack-5.5.git] / mach / i80 / dl / mccpm.c
1 /* $Id: mccpm.c,v 2.6 1994/06/24 12:58:26 ceriel Exp $ */
2 /*
3  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4  * See the copyright notice in the ACK home directory, in the file "Copyright".
5  */
6 /*
7  * dit programma leest een a.out file
8  * voor een kleine uP (adres space = 64K)
9  * en levert aan de standaard output een
10  * download formaat voor de MCCPM computer.
11  *
12  */
13
14 #define MAXBYTE 24
15 #include <stdio.h>
16 #include <out.h>
17 char hex[] =  "0123456789ABCDEF";
18 char **s;
19 int bytes, bytcnt, checksum;
20 unsigned pc;
21 unsigned offset;
22 unsigned htou();
23
24
25 main (argc,argv)
26 int argc;
27 char *argv[];
28         {
29         if (argc > 3)
30                 fatal ("usage: %s filename [start-adres]\n",argv[0]);
31         offset = 0;
32         if (argc == 3)
33                 if (!(offset = htou(argv[2])))
34                         fatal ("adres error %s\n", argv[2]);
35         if (! rd_open(*++argv)) fatal ("can't open %s\n",*argv);
36         else    {
37                 s = argv;
38                 convert ();
39                 }
40         }
41
42 convert ()
43         {
44         struct outhead head;
45         struct outsect sect[MAXSECT];
46         int i;
47
48         rd_ohead(&head);
49         if (head.oh_flags & HF_LINK) {
50                 fatal("%s contains unresolved references\n",s);
51         }
52         rd_sect(sect, head.oh_nsect);
53         for (i = 0; i < head.oh_nsect; i++) {
54                 rd_outsect(i);
55                 pc = sect[i].os_base - offset;
56                 while (sect[i].os_size) {
57                         unsigned int sz = 8096, fl;
58                         extern char *calloc();
59                         register char *buf;
60                         char *pbuf;
61
62                         if (sz > sect[i].os_size) sz = sect[i].os_size;
63                         sect[i].os_size -= sz;
64                         pbuf = buf = calloc(sz, 1);
65                         if (fl = sect[i].os_flen) {
66                                 if (fl > sz) fl = sz;
67                                 sect[i].os_flen -= fl;
68
69                                 rd_emit(buf, (long) fl);
70                         }
71                         while (sz >= MAXBYTE) {
72                                 data(MAXBYTE, (int) pc, buf);
73                                 checksum = 0;
74                                 sz -= MAXBYTE;
75                                 buf += MAXBYTE;
76                                 pc += MAXBYTE;
77                         }
78                         if (sz > 0) {
79                                 data(sz, (int) pc, buf);
80                                 checksum = 0;
81                         }
82                         free(pbuf);
83                 }
84         }
85         printf (":00000001FF\n");
86         }
87
88
89 data (sz, pc, buf)
90         register char *buf;
91 {
92         printf (":");
93         outbyte (sz);
94         bytcnt += 4;
95         outbyte (pc >> 8);
96         outbyte (pc);
97         outbyte (0);
98         while (sz != 0) 
99                 {
100                 outbyte (*buf++);
101                 sz--;
102                 }
103         outbyte (-checksum);
104         putchar ('\n');
105         putchar (0);
106         putchar (0);
107         }
108
109 outbyte (b)
110 int b;
111         {
112         checksum = (checksum + b) & 0xFF;
113         putchar (hex[(b>>4) & 0xF]);
114         putchar  (hex[b & 0xF]);
115         }
116
117 fatal (s,a)
118         char *s, *a;
119         {
120         fprintf (stderr,s,a);
121         exit (-1);
122         }
123
124 rd_fatal()
125 {
126         fatal("Read error\n");
127 }
128 /* convert a string of hex digits to an unsigned 16 bit number */
129
130 unsigned htou(t)
131 char *t;
132 {
133 unsigned n = 0;
134 char c;
135 while(c = *t++){
136         if(c >= '0' && c <= '9')
137                 c -= '0';
138         else if(c >= 'a' && c <= 'f')
139                 c -= 'a' - 10;
140         else if(c >= 'A' && c <= 'F')
141                 c -= 'A' - 10;
142         else
143                 return(0);
144         n = n * 16 + c;
145         }
146 return(n);
147 }