source: buchla-68k/orig/GEMDOS/MOTHEX.C@ 7bf3856

Last change on this file since 7bf3856 was 3ae31e9, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Imported original source code.

  • Property mode set to 100755
File size: 9.7 KB
Line 
1/*
2 ============================================================================
3 mothex.c -- convert Alcyon object file to Motorola hex S-records
4 Version 18 -- 1989-07-18 -- D.N. Lynx Crowe
5 (c) Copyright 1987, 1988, 1989 -- D.N. Lynx Crowe
6 ============================================================================
7*/
8
9#include "stdio.h"
10#include "stddefs.h"
11#include "ctype.h"
12#include "portab.h"
13#include "objdefs.h"
14
15#define MOT_ALL "mot" /* extension for un-split files */
16#define MOT_EVN "mhi" /* extension for even (high) byte files */
17#define MOT_ODD "mlo" /* extension for odd (low) byte files */
18
19#define CHUNK 16384 /* input buffer read size */
20
21#define SWITCHAR(c) ((c) EQ '\\') /* TOS definition */
22#define DRIVES(c) ((c) EQ ':') /* TOS / MSDOS / PCDOS definition */
23
24extern char *sbrk();
25
26int textsw, /* user specified text origin switch */
27 bytesw; /* byte split switch */
28
29FILE *curfp, /* input file pointer */
30 *motfp; /* output file pointer */
31
32struct EXFILE fhdr; /* input file header */
33
34long textorg, /* text origin from input file */
35 dataorg, /* data origin from input file */
36 bssorg, /* bss origin from input file */
37 textval; /* text origin for output */
38
39char *buffer, /* input buffer pointer */
40 *obuf, /* output buffer pointer */
41 fnbuf[64]; /* output file name buffer */
42
43/*
44
45*/
46
47/*
48 ============================================================================
49 usage() -- print the usage message on stderr
50 ============================================================================
51*/
52
53usage()
54{
55 fprintf(stderr, "\nmothex: Alcyon .abs to Motorola .mot file converter\n\n");
56
57 fprintf(stderr, "usage: mothex [-b] [-t addr]\n\n");
58
59 fprintf(stderr, " -b byte split (produces .mhi, .mlo files\n");
60 fprintf(stderr, " -t addr set text origin\n");
61}
62
63/*
64
65*/
66
67/*
68 ============================================================================
69 base_nm(s1, s2) -- copy the base name from 's2' into 's1'
70 ============================================================================
71*/
72
73char *
74base_nm(s1, s2)
75char *s1;
76register char *s2;
77{
78 register char *cp, *s3;
79 register char c;
80
81 cp = s2;
82 s3 = s1;
83
84 while ('\0' NE *s2) {
85
86 c = *s2++;
87
88 if (SWITCHAR(c) OR DRIVES(c))
89 cp = s2;
90 }
91
92 while (*s3++ = *cp++) ;
93
94 *s3++ = '\0';
95
96 return(s1);
97}
98
99/*
100
101*/
102
103/*
104 ============================================================================
105 root_nm(s1, s2) -- copy the root name from file name 's2'
106 to string 's1'
107 ============================================================================
108*/
109
110char *
111root_nm(s1, s2)
112register char *s1, *s2;
113{
114 register int c;
115 register char *s4;
116 char *s3;
117 char buf[33];
118
119 s3 = s1;
120 s4 = base_nm(buf, s2);
121
122 while (c = 0x00FF & *s4++) {
123
124 if (c EQ '.')
125 break;
126
127 *s1++ = c;
128 }
129
130 *s1++ = '\0';
131 return(s3);
132}
133
134/*
135
136*/
137
138/*
139 ============================================================================
140 out_nm(s1, s2, s3) -- create an output file name in 's1' from
141 the input string 's2' and extension string 's3'
142
143 s1 output string pointer
144 s2 input string pointer
145 s3 extension string pointer
146 ============================================================================
147*/
148
149char *
150out_nm(s1, s2, s3)
151register char *s1;
152char *s2, *s3;
153{
154 root_nm(s1, s2);
155 strcat(s1, ".");
156 strcat(s1, s3);
157 return(s1);
158}
159
160/*
161 ============================================================================
162 atolx(p) -- convert an ASCII hex string to a long
163 ============================================================================
164*/
165
166long
167atolx(p)
168register char **p;
169{
170 register long n;
171 register int c;
172
173 n = 0L;
174 --*p;
175
176 while (isxdigit(c = *++*p))
177 n = (n << 4) + tonumber(c);
178
179 --*p;
180 return(n);
181}
182
183/*
184
185*/
186
187/*
188 ============================================================================
189 findopt -- process options and find first file name
190 ============================================================================
191*/
192
193findopt(argc, argv)
194int argc;
195char *argv[];
196{
197 char **eargv;
198 int eargc, c;
199
200 eargv = argv;
201 eargc = 0;
202 textval = 0L;
203 textsw = FALSE;
204 bytesw = FALSE;
205
206 while (--argc > 0) {
207
208 switch (c = **++argv) {
209
210 case '-':
211
212 if ((c = *++*argv) EQ '\0')
213 break;
214
215 do {
216 switch (c) {
217
218 case 'b': /* byte split the file */
219
220 bytesw = TRUE;
221 continue;
222
223 case 't': /* set text origin */
224
225 textsw = TRUE;
226
227 if (--argc > 0) {
228
229 ++argv;
230 textval = atolx(argv);
231 }
232
233 continue;
234/*
235
236*/
237 default:
238
239 fprintf(stderr, "mothex: Invalid option [%c]\n", c);
240 usage();
241 exit(2);
242 }
243
244 } while ((c = *++*argv) NE '\0');
245
246 continue;
247 }
248
249 *eargv++ = *argv;
250 ++eargc;
251 }
252
253 return (eargc);
254}
255
256/*
257
258*/
259
260/*
261 ============================================================================
262 lread(buff, len, fp) -- read 'len' bytes into 'buff' from file 'fp'
263 ============================================================================
264*/
265
266int
267lread(buff, len, fp)
268char *buff;
269long len;
270FILE *fp;
271{
272 int ilen;
273
274 while (len > 0) {
275
276 if (len GE (long)CHUNK) {
277
278 if (1 NE fread(buff, CHUNK, 1, fp))
279 return(EOF);
280
281 buff += (long)CHUNK;
282 len -= (long)CHUNK;
283
284 } else {
285
286 ilen = len;
287
288 if (1 NE fread(buff, ilen, 1, fp))
289 return(EOF);
290
291 len = 0L;
292 }
293 }
294
295 return(0);
296}
297
298/*
299
300*/
301
302/*
303 ============================================================================
304 process(fn) -- output file 'fn' as Motorola hex S-records
305 ============================================================================
306*/
307
308process(fn)
309char *fn;
310{
311 long bufneed, len_evn, len_odd;
312 register long i;
313 char *ofn;
314 register char *p1, *p2;
315
316 textorg = 0L; /* initialize the origins to 0 */
317 dataorg = 0L;
318 bssorg = 0L;
319
320 /* open the input file */
321
322 if ((FILE *)NULL EQ (curfp = fopenb(fn, "r") ) ) {
323
324 fprintf(stderr, "mothex: Unable to open \"%s\"\n", fn);
325 exit(2);
326 }
327
328 /* read in the file header */
329
330 fprintf(stderr, "mothex: Reading \"%s\"\n", fn);
331
332 if (1 NE fread(&fhdr, sizeof fhdr, 1, curfp)) {
333
334 fprintf(stderr, "mothex: Unable to read \"%s\"\n", fn);
335 fclose(curfp);
336 exit(2);
337 }
338
339 /* check the magic */
340
341 if ((fhdr.F_Magic NE F_R_C) AND (fhdr.F_Magic NE F_R_D)) {
342
343 fprintf(stderr, "mothex: Bad magic [0x%04x] in \"%s\"",
344 fhdr.F_Magic, fn);
345
346 fclose(curfp);
347 exit(2);
348 }
349/*
350
351*/
352 /* if it's a discontinuous file, read the origins */
353
354 if (fhdr.F_Magic EQ F_R_D) {
355
356 dataorg = getl(curfp);
357 bssorg = getl(curfp);
358 }
359
360 bufneed = fhdr.F_Text + fhdr.F_Data;
361 buffer = (char *)sbrk(0);
362
363 if (-1 EQ brk((char *)(buffer + bufneed))) {
364
365 fprintf(stderr, "mothex: Unable to allocate %ld byte input buffer at $%lx\n",
366 bufneed, buffer);
367
368 fprintf(stderr, "mothex: F_Text = %ld F_Data = %ld\n",
369 fhdr.F_Text, fhdr.F_Data);
370
371 fclose(curfp);
372 exit(2);
373 }
374
375 if (bytesw) { /* allocate byte split buffer */
376
377 obuf = sbrk(0);
378
379 if (-1 EQ brk((char *)(obuf + 1 + (bufneed >> 1)))) {
380
381 fprintf(stderr, "mothex: Unable to allocate bytesplit buffer\n");
382 fclose(curfp);
383 exit(2);
384 }
385 }
386
387 if (0 NE lread(buffer, bufneed, curfp)) {
388
389 fprintf(stderr, "mothex: Unable to read \"%s\"\n", fn);
390 fclose(curfp);
391 exit(2);
392 }
393
394 fclose(curfp);
395
396 if (textsw)
397 textorg = textval;
398 else
399 textorg = fhdr.F_Res2;
400
401 if ((fhdr.F_Magic EQ F_R_D) AND (dataorg NE 0L) AND (fhdr.F_Data NE 0L)) {
402
403 fprintf(stderr, "mothex: ERROR - can't split text and data\n");
404 exit(2);
405 }
406/*
407
408*/
409 if (bytesw) { /* process byte-split file */
410
411 len_evn = (bufneed & 1L) + (bufneed >> 1);
412 len_odd = bufneed >> 1;
413
414 /* create the even byte output file */
415
416 ofn = out_nm(fnbuf, fn, MOT_EVN);
417
418 if ((FILE *)NULL EQ (motfp = fopena(ofn, "w") ) ) {
419
420 fprintf(stderr, "mothex: Unable to open \"%s\"\n", fn);
421 exit(2);
422 }
423
424 p1 = obuf;
425 p2 = buffer;
426
427 for (i = len_evn; i--; ) {
428
429 *p1++ = *p2;
430 p2 += 2;
431 }
432
433 fprintf(stderr, "mothex: Writing \"%s\"\n", ofn);
434 msrec(motfp, textorg, len_evn, obuf);
435 fclose(motfp);
436
437 /* create the odd byte output file */
438
439 p1 = obuf;
440 p2 = buffer + 1;
441
442 for (i = len_odd; i--; ) {
443
444 *p1++ = *p2;
445 p2 += 2;
446 }
447
448 ofn = out_nm(fnbuf, fn, MOT_ODD);
449
450 if ((FILE *)NULL EQ (motfp = fopena(ofn, "w") ) ) {
451
452 fprintf(stderr, "mothex: Unable to open \"%s\"\n", fn);
453 exit(2);
454 }
455
456 fprintf(stderr, "mothex: Writing \"%s\"\n", ofn);
457 msrec(motfp, textorg, len_odd, obuf);
458 fclose(motfp);
459/*
460
461*/
462 } else { /* process un-split file */
463
464 /* create the output file */
465
466 ofn = out_nm(fnbuf, fn, MOT_ALL);
467
468 if ((FILE *)NULL EQ (motfp = fopena(ofn, "w") ) ) {
469
470 fprintf(stderr, "mothex: Unable to open \"%s\"\n", fn);
471 exit(2);
472 }
473
474 fprintf(stderr, "mothex: Writing \"%s\"\n", ofn);
475 msrec(motfp, textorg, bufneed, buffer);
476 fclose(motfp);
477 }
478
479 brk(buffer); /* restore program break for next file */
480}
481
482/*
483
484*/
485
486/*
487 ============================================================================
488 main processing loop -- process arguments and files
489 ============================================================================
490*/
491
492main(argc, argv)
493int argc;
494char *argv[];
495{
496 argc = findopt(argc, argv); /* analyze the command line */
497
498 while (argc-- > 0) /* process the files */
499 process(*argv++);
500
501 exit(0);
502}
Note: See TracBrowser for help on using the repository browser.