ncr53cxxx.c revision 1.12 1 /* $NetBSD: ncr53cxxx.c,v 1.12 2003/07/14 15:44:04 lukem Exp $ */
2
3 /*
4 * Copyright (c) 1995,1999 Michael L. Hitch
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Michael L. Hitch.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /* ncr53cxxx.c - SCSI SCRIPTS Assembler */
34
35 #include <sys/cdefs.h>
36 __RCSID("$NetBSD: ncr53cxxx.c,v 1.12 2003/07/14 15:44:04 lukem Exp $");
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <time.h>
42
43 #ifndef AMIGA
44 #define strcmpi strcasecmp
45 #endif
46
47 #define MAXTOKENS 16
48 #define MAXINST 1024
49 #define MAXSYMBOLS 128
50
51 struct {
52 int type;
53 char *name;
54 } tokens[MAXTOKENS];
55 int ntokens;
56 int tokenix;
57
58 void f_proc (void);
59 void f_pass (void);
60 void f_list (void); /* ENTRY, EXTERNAL label list */
61 void f_define (void); /* ABSOLUTE, RELATIVE label list */
62 void f_move (void);
63 void f_jump (void);
64 void f_call (void);
65 void f_return (void);
66 void f_int (void);
67 void f_intfly (void);
68 void f_select (void);
69 void f_reselect (void);
70 void f_wait (void);
71 void f_disconnect (void);
72 void f_set (void);
73 void f_clear (void);
74 void f_load (void);
75 void f_store (void);
76 void f_nop (void);
77 void f_arch (void);
78
79 struct {
80 char *name;
81 void (*func)(void);
82 } directives[] = {
83 {"PROC", f_proc},
84 {"PASS", f_pass},
85 {"ENTRY", f_list},
86 {"ABSOLUTE", f_define},
87 {"EXTERN", f_list},
88 {"EXTERNAL", f_list},
89 {"RELATIVE", f_define},
90 {"MOVE", f_move},
91 {"JUMP", f_jump},
92 {"CALL", f_call},
93 {"RETURN", f_return},
94 {"INT", f_int},
95 {"INTFLY", f_intfly},
96 {"SELECT", f_select},
97 {"RESELECT", f_reselect},
98 {"WAIT", f_wait},
99 {"DISCONNECT", f_disconnect},
100 {"SET", f_set},
101 {"CLEAR", f_clear},
102 {"LOAD", f_load},
103 {"STORE", f_store},
104 {"NOP", f_nop},
105 {"ARCH", f_arch},
106 {NULL, NULL}};
107
108 u_int32_t script[MAXINST];
109 int dsps;
110 char *script_name = "SCRIPT";
111 u_int32_t inst0, inst1, inst2;
112 unsigned int ninsts;
113 unsigned int npatches;
114
115 struct patchlist {
116 struct patchlist *next;
117 unsigned offset;
118 } *patches;
119
120 #define S_LABEL 0x0000
121 #define S_ABSOLUTE 0x0001
122 #define S_RELATIVE 0x0002
123 #define S_EXTERNAL 0x0003
124 #define F_DEFINED 0x0001
125 #define F_ENTRY 0x0002
126 struct {
127 short type;
128 short flags;
129 u_int32_t value;
130 struct patchlist *patchlist;
131 char *name;
132 } symbols[MAXSYMBOLS];
133 int nsymbols;
134
135 char *stypes[] = {"Label", "Absolute", "Relative", "External"};
136
137 char *phases[] = {
138 "data_out", "data_in", "cmd", "status",
139 "res4", "res5", "msg_out", "msg_in"
140 };
141
142 struct ncrregs {
143 char *name;
144 int addr[5];
145 };
146 #define ARCH700 1
147 #define ARCH710 2
148 #define ARCH720 3
149 #define ARCH810 4
150 #define ARCH825 5
151
152 struct ncrregs regs[] = {
153 {"scntl0", {0x00, 0x00, 0x00, 0x00, 0x00}},
154 {"scntl1", {0x01, 0x01, 0x01, 0x01, 0x01}},
155 {"sdid", {0x02, 0x02, -1, -1, -1}},
156 {"sien", {0x03, 0x03, -1, -1, -1}},
157 {"scid", {0x04, 0x04, -1, -1, -1}},
158 {"scntl2", { -1, -1, 0x02, 0x02, 0x02}},
159 {"scntl3", { -1, -1, 0x03, 0x03, 0x03}},
160 {"scid", { -1, -1, 0x04, 0x04, 0x04}},
161 {"sxfer", {0x05, 0x05, 0x05, 0x05, 0x05}},
162 {"sodl", {0x06, 0x06, -1, -1, -1}},
163 {"socl", {0x07, 0x07, -1, -1, -1}},
164 {"sdid", { -1, -1, 0x06, 0x06, 0x06}},
165 {"gpreg", { -1, -1, 0x07, 0x07, 0x07}},
166 {"sfbr", {0x08, 0x08, 0x08, 0x08, 0x08}},
167 {"sidl", {0x09, 0x09, -1, -1, -1}},
168 {"sbdl", {0x0a, 0x0a, -1, -1, -1}},
169 {"socl", { -1, -1, 0x09, 0x09, 0x09}},
170 {"ssid", { -1, -1, 0x0a, 0x0a, 0x0a}},
171 {"sbcl", {0x0b, 0x0b, 0x0b, 0x0b, 0x0b}},
172 {"dstat", {0x0c, 0x0c, 0x0c, 0x0c, 0x0c}},
173 {"sstat0", {0x0d, 0x0d, 0x0d, 0x0d, 0x0d}},
174 {"sstat1", {0x0e, 0x0e, 0x0e, 0x0e, 0x0e}},
175 {"sstat2", {0x0f, 0x0f, 0x0f, 0x0f, 0x0f}},
176 {"dsa0", { -1, 0x10, 0x10, 0x10, 0x10}},
177 {"dsa1", { -1, 0x11, 0x11, 0x11, 0x11}},
178 {"dsa2", { -1, 0x12, 0x12, 0x12, 0x12}},
179 {"dsa3", { -1, 0x13, 0x13, 0x13, 0x13}},
180 {"ctest0", {0x14, 0x14, 0x18, 0x18, 0x18}},
181 {"ctest1", {0x15, 0x15, 0x19, 0x19, 0x19}},
182 {"ctest2", {0x16, 0x16, 0x1a, 0x1a, 0x1a}},
183 {"ctest3", {0x17, 0x17, 0x1b, 0x1b, 0x1b}},
184 {"ctest4", {0x18, 0x18, 0x21, 0x21, 0x21}},
185 {"ctest5", {0x19, 0x19, 0x22, 0x22, 0x22}},
186 {"ctest6", {0x1a, 0x1a, 0x23, 0x23, 0x23}},
187 {"ctest7", {0x1b, 0x1b, -1, -1, -1}},
188 {"temp0", {0x1c, 0x1c, 0x1c, 0x1c, 0x1c}},
189 {"temp1", {0x1d, 0x1d, 0x1d, 0x1d, 0x1d}},
190 {"temp2", {0x1e, 0x1e, 0x1e, 0x1e, 0x1e}},
191 {"temp3", {0x1f, 0x1f, 0x1f, 0x1f, 0x1f}},
192 {"dfifo", {0x20, 0x20, 0x20, 0x20, 0x20}},
193 {"istat", {0x21, 0x21, 0x14, 0x14, 0x14}},
194 {"ctest8", {0x22, 0x22, -1, -1, -1}},
195 {"lcrc", { -1, 0x23, -1, -1, -1}},
196 {"ctest9", {0x23, -1, -1, -1, -1}},
197 {"dbc0", {0x24, 0x24, 0x24, 0x24, 0x24}},
198 {"dbc1", {0x25, 0x25, 0x25, 0x25, 0x25}},
199 {"dbc2", {0x26, 0x26, 0x26, 0x26, 0x26}},
200 {"dcmd", {0x27, 0x27, 0x27, 0x27, 0x27}},
201 {"dnad0", {0x28, 0x28, 0x28, 0x28, 0x28}},
202 {"dnad1", {0x29, 0x29, 0x29, 0x29, 0x29}},
203 {"dnad2", {0x2a, 0x2a, 0x2a, 0x2a, 0x2a}},
204 {"dnad3", {0x2b, 0x2b, 0x2b, 0x2b, 0x2b}},
205 {"dsp0", {0x2c, 0x2c, 0x2c, 0x2c, 0x2c}},
206 {"dsp1", {0x2d, 0x2d, 0x2d, 0x2d, 0x2d}},
207 {"dsp2", {0x2e, 0x2e, 0x2e, 0x2e, 0x2e}},
208 {"dsp3", {0x2f, 0x2f, 0x2f, 0x2f, 0x2f}},
209 {"dsps0", {0x30, 0x30, 0x30, 0x30, 0x30}},
210 {"dsps1", {0x31, 0x31, 0x31, 0x31, 0x31}},
211 {"dsps2", {0x32, 0x32, 0x32, 0x32, 0x32}},
212 {"dsps3", {0x33, 0x33, 0x33, 0x33, 0x33}},
213 {"scratch0", { -1, 0x34, -1, -1, -1}},
214 {"scratch1", { -1, 0x35, -1, -1, -1}},
215 {"scratch2", { -1, 0x36, -1, -1, -1}},
216 {"scratch3", { -1, 0x37, -1, -1, -1}},
217 {"scratcha0", {0x10, -1, 0x34, 0x34, 0x34}},
218 {"scratcha1", {0x11, -1, 0x35, 0x35, 0x35}},
219 {"scratcha2", {0x12, -1, 0x36, 0x36, 0x36}},
220 {"scratcha3", {0x13, -1, 0x37, 0x37, 0x37}},
221 {"dmode", {0x34, 0x38, 0x38, 0x38, 0x38}},
222 {"dien", {0x39, 0x39, 0x39, 0x39, 0x39}},
223 {"dwt", {0x3a, 0x3a, 0x3a, -1, -1}},
224 {"sbr", { -1, -1, -1, 0x3a, 0x3a}},
225 {"dcntl", {0x3b, 0x3b, 0x3b, 0x3b, 0x3b}},
226 {"addr0", { -1, 0x3c, 0x3c, 0x3c, 0x3c}},
227 {"addr1", { -1, 0x3d, 0x3d, 0x3d, 0x3d}},
228 {"addr2", { -1, 0x3e, 0x3e, 0x3e, 0x3e}},
229 {"addr3", { -1, 0x3f, 0x3f, 0x3f, 0x3f}},
230 {"sien0", { -1, -1, 0x40, 0x40, 0x40}},
231 {"sien1", { -1, -1, 0x41, 0x41, 0x41}},
232 {"sist0", { -1, -1, 0x42, 0x42, 0x42}},
233 {"sist1", { -1, -1, 0x43, 0x43, 0x43}},
234 {"slpar", { -1, -1, 0x44, 0x44, 0x44}},
235 {"swide", { -1, -1, 0x45, -1, 0x45}},
236 {"macntl", { -1, -1, 0x46, 0x46, 0x46}},
237 {"gpcntl", { -1, -1, 0x47, 0x47, 0x47}},
238 {"stime0", { -1, -1, 0x48, 0x48, 0x48}},
239 {"stime1", { -1, -1, 0x49, 0x49, 0x49}},
240 {"respid0", { -1, -1, 0x4a, 0x4a, 0x4a}},
241 {"respid1", { -1, -1, 0x4b, -1, 0x4b}},
242 {"stest0", { -1, -1, 0x4c, 0x4c, 0x4c}},
243 {"stest1", { -1, -1, 0x4d, 0x4d, 0x4d}},
244 {"stest2", { -1, -1, 0x4e, 0x4e, 0x4e}},
245 {"stest3", { -1, -1, 0x4f, 0x4f, 0x4f}},
246 {"sidl0", { -1, -1, 0x50, 0x50, 0x50}},
247 {"sidl1", { -1, -1, 0x51, -1, 0x51}},
248 {"sodl0", { -1, -1, 0x54, 0x54, 0x54}},
249 {"sodl1", { -1, -1, 0x55, -1, 0x55}},
250 {"sbdl0", { -1, -1, 0x58, 0x58, 0x58}},
251 {"sbdl1", { -1, -1, 0x59, -1, 0x59}},
252 {"scratchb0", {0x3c, -1, 0x5c, 0x5c, 0x5c}},
253 {"scratchb1", {0x3d, -1, 0x5d, 0x5d, 0x5d}},
254 {"scratchb2", {0x3e, -1, 0x5e, 0x5e, 0x5e}},
255 {"scratchb3", {0x3f, -1, 0x5f, 0x5f, 0x5f}},
256 {"scratchc0", { -1, -1, -1, -1, 0x60}},
257 {"scratchc1", { -1, -1, -1, -1, 0x61}},
258 {"scratchc2", { -1, -1, -1, -1, 0x62}},
259 {"scratchc3", { -1, -1, -1, -1, 0x63}},
260 {"scratchd0", { -1, -1, -1, -1, 0x64}},
261 {"scratchd1", { -1, -1, -1, -1, 0x65}},
262 {"scratchd2", { -1, -1, -1, -1, 0x66}},
263 {"scratchd3", { -1, -1, -1, -1, 0x67}},
264 {"scratche0", { -1, -1, -1, -1, 0x68}},
265 {"scratche1", { -1, -1, -1, -1, 0x69}},
266 {"scratche2", { -1, -1, -1, -1, 0x6a}},
267 {"scratche3", { -1, -1, -1, -1, 0x6b}},
268 {"scratchf0", { -1, -1, -1, -1, 0x6c}},
269 {"scratchf1", { -1, -1, -1, -1, 0x6d}},
270 {"scratchf2", { -1, -1, -1, -1, 0x6e}},
271 {"scratchf3", { -1, -1, -1, -1, 0x6f}},
272 {"scratchg0", { -1, -1, -1, -1, 0x70}},
273 {"scratchg1", { -1, -1, -1, -1, 0x71}},
274 {"scratchg2", { -1, -1, -1, -1, 0x72}},
275 {"scratchg3", { -1, -1, -1, -1, 0x73}},
276 {"scratchh0", { -1, -1, -1, -1, 0x74}},
277 {"scratchh1", { -1, -1, -1, -1, 0x75}},
278 {"scratchh2", { -1, -1, -1, -1, 0x7e}},
279 {"scratchh3", { -1, -1, -1, -1, 0x77}},
280 {"scratchi0", { -1, -1, -1, -1, 0x78}},
281 {"scratchi1", { -1, -1, -1, -1, 0x79}},
282 {"scratchi2", { -1, -1, -1, -1, 0x7a}},
283 {"scratchi3", { -1, -1, -1, -1, 0x7b}},
284 {"scratchj0", { -1, -1, -1, -1, 0x7c}},
285 {"scratchj1", { -1, -1, -1, -1, 0x7d}},
286 {"scratchj2", { -1, -1, -1, -1, 0x7e}},
287 {"scratchj3", { -1, -1, -1, -1, 0x7f}},
288 };
289
290 int lineno;
291 int err_listed;
292 int arch;
293 int partial_flag;
294
295 char inbuf[128];
296
297 char *sourcefile;
298 char *outputfile;
299 char *listfile;
300 char *errorfile;
301
302 FILE *infp;
303 FILE *outfp;
304 FILE *listfp;
305 FILE *errfp;
306
307 void setarch(char *);
308 void parse (void);
309 void process (void);
310 void emit_symbols (void);
311 void list_symbols (void);
312 void errout (char *);
313 void define_symbol (char *, u_int32_t, short, short);
314 void patch_label (void);
315 void close_script (void);
316 void new_script (char *);
317 void store_inst (void);
318 int expression (int *);
319 int evaluate (int);
320 int number (char *);
321 int lookup (char *);
322 int reserved (char *, int);
323 int CheckPhase (int);
324 int CheckRegister (int);
325 void transfer (int, int);
326 void select_reselect (int);
327 void set_clear (u_int32_t);
328 void block_move (void);
329 void register_write (void);
330 void memory_to_memory (void);
331 void loadstore (int);
332 void error_line(void);
333 char *makefn(char *, char *);
334 void usage(void);
335
336 int
337 main (int argc, char *argv[])
338 {
339 int i;
340 struct patchlist *p;
341
342 if (argc < 2 || argv[1][0] == '-')
343 usage();
344 sourcefile = argv[1];
345 infp = fopen (sourcefile, "r");
346 if (infp == NULL) {
347 perror ("open source");
348 fprintf (stderr, "scc: error opening source file %s\n", argv[1]);
349 exit (1);
350 }
351 /*
352 * process options
353 * -l [listfile]
354 * -o [outputfile]
355 * -p [outputfile]
356 * -z [debugfile]
357 * -e [errorfile]
358 * -a arch
359 * -v
360 * -u
361 */
362 for (i = 2; i < argc; ++i) {
363 if (argv[i][0] != '-')
364 usage();
365 switch (argv[i][1]) {
366 case 'o':
367 case 'p':
368 partial_flag = argv[i][1] == 'p';
369 if (i + 1 >= argc || argv[i + 1][0] == '-')
370 outputfile = makefn (sourcefile, "out");
371 else {
372 outputfile = argv[i + 1];
373 ++i;
374 }
375 break;
376 case 'l':
377 if (i + 1 >= argc || argv[i + 1][0] == '-')
378 listfile = makefn (sourcefile, "lis");
379 else {
380 listfile = argv[i + 1];
381 ++i;
382 }
383 break;
384 case 'e':
385 if (i + 1 >= argc || argv[i + 1][0] == '-')
386 errorfile = makefn (sourcefile, "err");
387 else {
388 errorfile = argv[i + 1];
389 ++i;
390 }
391 break;
392 case 'a':
393 if (i + 1 == argc)
394 usage();
395 setarch(argv[i +1]);
396 if (arch == 0) {
397 fprintf(stderr,"%s: bad arch '%s'\n",
398 argv[0], argv[i +1]);
399 exit(1);
400 }
401 ++i;
402 break;
403 default:
404 fprintf (stderr, "scc: unrecognized option '%c'\n",
405 argv[i][1]);
406 usage();
407 }
408 }
409 if (outputfile)
410 outfp = fopen (outputfile, "w");
411 if (listfile)
412 listfp = fopen (listfile, "w");
413 if (errorfile)
414 errfp = fopen (errorfile, "w");
415 else
416 errfp = stderr;
417
418 if (outfp) {
419 time_t cur_time;
420
421 fprintf(outfp, "/*\t$NetBSD: ncr53cxxx.c,v 1.12 2003/07/14 15:44:04 lukem Exp $\t*/\n");
422 fprintf(outfp, "/*\n");
423 fprintf(outfp, " *\tDO NOT EDIT - this file is automatically generated.\n");
424 time(&cur_time);
425 fprintf(outfp, " *\tcreated from %s on %s", sourcefile, ctime(&cur_time));
426 fprintf(outfp, " */\n");
427 }
428
429 while (fgets (inbuf, sizeof (inbuf), infp)) {
430 ++lineno;
431 if (listfp)
432 fprintf (listfp, "%3d: %s", lineno, inbuf);
433 err_listed = 0;
434 parse ();
435 if (ntokens) {
436 #ifdef DUMP_TOKENS
437 int i;
438
439 fprintf (listfp, " %d tokens\n", ntokens);
440 for (i = 0; i < ntokens; ++i) {
441 fprintf (listfp, " %d: ", i);
442 if (tokens[i].type)
443 fprintf (listfp,"'%c'\n", tokens[i].type);
444 else
445 fprintf (listfp, "%s\n", tokens[i].name);
446 }
447 #endif
448 if (ntokens >= 2 && tokens[0].type == 0 &&
449 tokens[1].type == ':') {
450 define_symbol (tokens[0].name, dsps, S_LABEL, F_DEFINED);
451 tokenix += 2;
452 }
453 if (tokenix < ntokens)
454 process ();
455 }
456
457 }
458 close_script ();
459 emit_symbols ();
460 if (outfp && !partial_flag) {
461 fprintf (outfp, "\nu_int32_t INSTRUCTIONS = 0x%08x;\n", ninsts);
462 fprintf (outfp, "u_int32_t PATCHES = 0x%08x;\n", npatches);
463 fprintf (outfp, "u_int32_t LABELPATCHES[] = {\n");
464 p = patches;
465 while (p) {
466 fprintf (outfp, "\t0x%08x,\n", p->offset / 4);
467 p = p->next;
468 }
469 fprintf (outfp, "};\n\n");
470 }
471 list_symbols ();
472 exit(0);
473 }
474
475 void setarch(char *val)
476 {
477 switch (atoi(val)) {
478 case 700:
479 arch = ARCH700;
480 break;
481 case 710:
482 arch = ARCH710;
483 break;
484 case 720:
485 arch = ARCH720;
486 break;
487 case 810:
488 arch = ARCH810;
489 break;
490 case 825:
491 arch = ARCH825;
492 break;
493 default:
494 arch = 0;
495 }
496 }
497
498 void emit_symbols ()
499 {
500 int i;
501 struct patchlist *p;
502
503 if (nsymbols == 0 || outfp == NULL)
504 return;
505
506 for (i = 0; i < nsymbols; ++i) {
507 char *code;
508 if ((symbols[i].flags & F_DEFINED) == 0 &&
509 symbols[i].type != S_EXTERNAL) {
510 fprintf(stderr, "warning: symbol %s undefined\n",
511 symbols[i].name);
512 }
513 if (symbols[i].type == S_ABSOLUTE)
514 code = "A_";
515 else if (symbols[i].type == S_RELATIVE)
516 code = "R_";
517 else if (symbols[i].type == S_EXTERNAL)
518 code = "E_";
519 else if (symbols[i].flags & F_ENTRY)
520 code = "Ent_";
521 else
522 continue;
523 fprintf (outfp, "#define\t%s%s\t0x%08x\n", code, symbols[i].name,
524 symbols[i].value);
525 if (symbols[i].flags & F_ENTRY || symbols[i].patchlist == NULL)
526 continue;
527 fprintf (outfp, "u_int32_t %s%s_Used[] = {\n", code, symbols[i].name);
528 #if 1
529 p = symbols[i].patchlist;
530 while (p) {
531 fprintf (outfp, "\t0x%08x,\n", p->offset / 4);
532 p = p->next;
533 }
534 #endif
535 fprintf (outfp, "};\n\n");
536 }
537 /* patches ? */
538 }
539
540 void list_symbols ()
541 {
542 int i;
543
544 if (nsymbols == 0 || listfp == NULL)
545 return;
546 fprintf (listfp, "\n\nValue Type Symbol\n");
547 for (i = 0; i < nsymbols; ++i) {
548 fprintf (listfp, "%08x: %-8s %s\n", symbols[i].value,
549 stypes[symbols[i].type], symbols[i].name);
550 }
551 }
552
553 void errout (char *text)
554 {
555 error_line();
556 fprintf (errfp, "*** %s ***\n", text);
557 }
558
559 void parse ()
560 {
561 char *p = inbuf;
562 char c;
563 char string[64];
564 char *s;
565
566 ntokens = tokenix = 0;
567 while (1) {
568 while ((c = *p++) && c != '\n' && (c <= ' ' || c == '\t'))
569 ;
570 if (c == '\n' || c == 0 || c == ';')
571 break;
572 if (ntokens >= MAXTOKENS) {
573 errout ("Token table full");
574 break;
575 }
576 if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
577 (c >= 'A' && c <= 'Z') || c == '$' || c == '_') {
578 s = string;
579 *s++ = c;
580 while (((c = *p) >= '0' && c <= '9') ||
581 (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
582 c == '_' || c == '$') {
583 *s++ = *p++;
584 }
585 *s = 0;
586 tokens[ntokens].name = malloc (strlen (string) + 1);
587 strcpy (tokens[ntokens].name, string);
588 tokens[ntokens].type = 0;
589 }
590 else {
591 tokens[ntokens].type = c;
592 }
593 ++ntokens;
594 }
595 return;
596 }
597
598 void process ()
599 {
600 int i;
601
602 if (tokens[tokenix].type) {
603 error_line();
604 fprintf (errfp, "Error: expected directive, found '%c'\n",
605 tokens[tokenix].type);
606 return;
607 }
608 for (i = 0; directives[i].name; ++i) {
609 if (strcmpi (directives[i].name, tokens[tokenix].name) == 0)
610 break;
611 }
612 if (directives[i].name == NULL) {
613 error_line();
614 fprintf (errfp, "Error: expected directive, found \"%s\"\n",
615 tokens[tokenix].name);
616 return;
617 }
618 if (directives[i].func == NULL) {
619 error_line();
620 fprintf (errfp, "No function for directive \"%s\"\n", tokens[tokenix].name);
621 } else {
622 #if 0
623 fprintf (listfp, "Processing directive \"%s\"\n", directives[i].name);
624 #endif
625 ++tokenix;
626 (*directives[i].func) ();
627 }
628 }
629
630 void define_symbol (char *name, u_int32_t value, short type, short flags)
631 {
632 int i;
633 struct patchlist *p;
634
635 for (i = 0; i < nsymbols; ++i) {
636 if (symbols[i].type == type && strcmp (symbols[i].name, name) == 0) {
637 if (symbols[i].flags & F_DEFINED) {
638 error_line();
639 fprintf (errfp, "*** Symbol \"%s\" multiply defined\n",
640 name);
641 } else {
642 symbols[i].flags |= flags;
643 symbols[i].value = value;
644 p = symbols[i].patchlist;
645 while (p) {
646 if (p->offset > dsps)
647 errout ("Whoops\007");
648 else
649 script[p->offset / 4] += dsps;
650 p = p->next;
651 }
652 }
653 return;
654 }
655 }
656 if (nsymbols >= MAXSYMBOLS) {
657 errout ("Symbol table full");
658 return;
659 }
660 symbols[nsymbols].type = type;
661 symbols[nsymbols].flags = flags;
662 symbols[nsymbols].value = value;
663 symbols[nsymbols].patchlist = NULL;
664 symbols[nsymbols].name = malloc (strlen (name) + 1);
665 strcpy (symbols[nsymbols].name, name);
666 ++nsymbols;
667 }
668
669 void patch_label (void)
670 {
671 struct patchlist *p, **h;
672
673 h = &patches;
674 while(*h)
675 h = &(*h)->next;
676 p = (struct patchlist *) malloc (sizeof (struct patchlist));
677 *h = p;
678 p->next = NULL;
679 p->offset = dsps + 4;
680 npatches++;
681 }
682
683 void close_script ()
684 {
685 int i;
686
687 if (dsps == 0)
688 return;
689 if (outfp) {
690 fprintf (outfp, "const u_int32_t %s[] = {\n", script_name);
691 for (i = 0; i < dsps / 4; i += 2) {
692 fprintf (outfp, "\t0x%08x, 0x%08x", script[i],
693 script[i + 1]);
694 /* check for memory move instruction */
695 if ((script[i] & 0xe0000000) == 0xc0000000)
696 fprintf (outfp, ", 0x%08x,", script[i + 2]);
697 else
698 if ((i + 2) <= dsps / 4) fprintf (outfp, ",\t\t");
699 fprintf (outfp, "\t/* %03x - %3d */\n", i * 4, i * 4);
700 if ((script[i] & 0xe0000000) == 0xc0000000)
701 ++i;
702 }
703 fprintf (outfp, "};\n\n");
704 }
705 dsps = 0;
706 }
707
708 void new_script (char *name)
709 {
710 close_script ();
711 script_name = malloc (strlen (name) + 1);
712 strcpy (script_name, name);
713 }
714
715 int reserved (char *string, int t)
716 {
717 if (tokens[t].type == 0 && strcmpi (tokens[t].name, string) == 0)
718 return (1);
719 return (0);
720 }
721
722 int CheckPhase (int t)
723 {
724 int i;
725
726 for (i = 0; i < 8; ++i) {
727 if (reserved (phases[i], t)) {
728 inst0 |= i << 24;
729 return (1);
730 }
731 }
732 return (0);
733 }
734
735 int CheckRegister (int t)
736 {
737 int i;
738
739 if (arch <= 0) {
740 errout("'ARCH' statement missing");
741 return -1;
742 }
743 for (i = 0; i < (sizeof(regs) / sizeof(regs[0])); i++) {
744 if (regs[i].addr[arch - 1] >= 0 && reserved(regs[i].name, t))
745 return regs[i].addr[arch-1];
746 }
747 return (-1);
748 }
749
750 int expression (int *t)
751 {
752 int value;
753 int i = *t;
754
755 value = evaluate (i++);
756 while (i < ntokens) {
757 if (tokens[i].type == '+')
758 value += evaluate (i + 1);
759 else if (tokens[i].type == '-')
760 value -= evaluate (i + 1);
761 else
762 errout ("Unknown identifier");
763 i += 2;
764 }
765 *t = i;
766 return (value);
767 }
768
769 int evaluate (t)
770 {
771 int value;
772 char *name;
773
774 if (tokens[t].type) {
775 errout ("Expected an identifier");
776 return (0);
777 }
778 name = tokens[t].name;
779 if (*name >= '0' && *name <= '9')
780 value = number (name);
781 else
782 value = lookup (name);
783 return (value);
784 }
785
786 int number (char *s)
787 {
788 int value;
789 int n;
790 int radix;
791
792 radix = 10;
793 if (*s == '0') {
794 ++s;
795 radix = 8;
796 switch (*s) {
797 case 'x':
798 case 'X':
799 radix = 16;
800 break;
801 case 'b':
802 case 'B':
803 radix = 2;
804 }
805 if (radix != 8)
806 ++s;
807 }
808 value = 0;
809 while (*s) {
810 n = *s++;
811 if (n >= '0' && n <= '9')
812 n -= '0';
813 else if (n >= 'a' && n <= 'f')
814 n -= 'a' - 10;
815 else if (n >= 'A' && n <= 'F')
816 n -= 'A' - 10;
817 else {
818 error_line();
819 fprintf (errfp, "*** Expected digit\n");
820 n = 0;
821 }
822 if (n >= radix)
823 errout ("Expected digit");
824 else
825 value = value * radix + n;
826 }
827 return (value);
828 }
829
830 int lookup (char *name)
831 {
832 int i;
833 struct patchlist *p;
834
835 for (i = 0; i < nsymbols; ++i) {
836 if (strcmp (name, symbols[i].name) == 0) {
837 if ((symbols[i].flags & F_DEFINED) == 0) {
838 p = (struct patchlist *) &symbols[i].patchlist;
839 while (p->next)
840 p = p->next;
841 p->next = (struct patchlist *) malloc (sizeof (struct patchlist));
842 p = p->next;
843 p->next = NULL;
844 p->offset = dsps + 4;
845 }
846 return ((int) symbols[i].value);
847 }
848 }
849 if (nsymbols >= MAXSYMBOLS) {
850 errout ("Symbol table full");
851 return (0);
852 }
853 symbols[nsymbols].type = S_LABEL; /* assume forward reference */
854 symbols[nsymbols].flags = 0;
855 symbols[nsymbols].value = 0;
856 p = (struct patchlist *) malloc (sizeof (struct patchlist));
857 symbols[nsymbols].patchlist = p;
858 p->next = NULL;
859 p->offset = dsps + 4;
860 symbols[nsymbols].name = malloc (strlen (name) + 1);
861 strcpy (symbols[nsymbols].name, name);
862 ++nsymbols;
863 return (0);
864 }
865
866 void f_arch (void)
867 {
868 int i, archsave;
869
870 i = tokenix;
871
872 archsave = arch;
873 setarch(tokens[i].name);
874 if( arch == 0) {
875 errout("Unrecognized ARCH");
876 arch = archsave;
877 }
878 }
879
880 void f_proc (void)
881 {
882 if (tokens[tokenix].type != 0 || tokens[tokenix + 1].type != ':')
883 errout ("Invalid PROC statement");
884 else
885 new_script (tokens[tokenix].name);
886 }
887
888 void f_pass (void)
889 {
890 errout ("PASS option not implemented");
891 }
892
893 /*
894 * f_list: process list of symbols for the ENTRY and EXTERNAL directive
895 */
896
897 void f_list (void)
898 {
899 int i;
900 short type;
901 short flags;
902
903 type = strcmpi (tokens[tokenix-1].name, "ENTRY") ? S_EXTERNAL : S_LABEL;
904 flags = type == S_LABEL ? F_ENTRY : 0;
905 for (i = tokenix; i < ntokens; ++i) {
906 if (tokens[i].type != 0) {
907 errout ("Expected an identifier");
908 return;
909 }
910 define_symbol (tokens[i].name, 0, type, flags);
911 if (i + 1 < ntokens) {
912 if (tokens[++i].type == ',')
913 continue;
914 errout ("Expected a separator");
915 return;
916 }
917 }
918 }
919
920 /*
921 * f_define: process list of definitions for ABSOLUTE and RELATIVE directive
922 */
923
924 void f_define (void)
925 {
926 int i;
927 char *name;
928 u_int32_t value;
929 int type;
930
931 type = strcmpi (tokens[tokenix-1].name, "ABSOLUTE") ? S_RELATIVE : S_ABSOLUTE;
932 i = tokenix;
933 while (i < ntokens) {
934 if (tokens[i].type) {
935 errout ("Expected an identifier");
936 return;
937 }
938 if (tokens[i + 1].type != '=') {
939 errout ("Expected a separator");
940 return;
941 }
942 name = tokens[i].name;
943 i += 2;
944 value = expression (&i);
945 define_symbol (name, value, type, F_DEFINED);
946 }
947 }
948
949 void store_inst ()
950 {
951 int i = dsps / 4;
952 int l = 8;
953
954 if ((inst0 & 0xe0000000) == 0xc0000000)
955 l = 12; /* Memory to memory move is 12 bytes */
956 if ((dsps + l) / 4 > MAXINST) {
957 errout ("Instruction table overflow");
958 return;
959 }
960 script[i++] = inst0;
961 script[i++] = inst1;
962 if (l == 12)
963 script[i++] = inst2;
964 if (listfp) {
965 fprintf (listfp, "\t%04x: %08x %08x", dsps, inst0, inst1);
966 if (l == 12)
967 fprintf (listfp, " %08x", inst2);
968 fprintf (listfp, "\n");
969 }
970 dsps += l;
971 inst0 = inst1 = inst2 = 0;
972 ++ninsts;
973 }
974
975 void f_move (void)
976 {
977 if (reserved ("memory", tokenix))
978 memory_to_memory ();
979 else if (reserved ("from", tokenix) || tokens[tokenix+1].type == ',')
980 block_move ();
981 else
982 register_write ();
983 store_inst ();
984 }
985
986 void f_jump (void)
987 {
988 transfer (0x80000000, 0);
989 }
990
991 void f_call (void)
992 {
993 transfer (0x88000000, 0);
994 }
995
996 void f_return (void)
997 {
998 transfer (0x90000000, 1);
999 }
1000
1001 void f_int (void)
1002 {
1003 transfer (0x98000000, 2);
1004 }
1005
1006 void f_intfly (void)
1007 {
1008 transfer (0x98100000, 2);
1009 }
1010
1011 void f_select (void)
1012 {
1013 int t = tokenix;
1014
1015 if (reserved ("atn", t)) {
1016 inst0 = 0x01000000;
1017 ++t;
1018 }
1019 select_reselect (t);
1020 }
1021
1022 void f_reselect (void)
1023 {
1024 select_reselect (tokenix);
1025 }
1026
1027 void f_wait (void)
1028 {
1029 int i = tokenix;
1030
1031 inst1 = 0;
1032 if (reserved ("disconnect", i)) {
1033 inst0 = 0x48000000;
1034 }
1035 else {
1036 if (reserved ("reselect", i))
1037 inst0 = 0x50000000;
1038 else if (reserved ("select", i))
1039 inst0 = 0x50000000;
1040 else
1041 errout ("Expected SELECT or RESELECT");
1042 ++i;
1043 if (reserved ("rel", i)) {
1044 #if 0 /* driver will fix relative dsps to absolute */
1045 if (arch < ARCH710) {
1046 errout ("Wrong arch for relative dsps");
1047 }
1048 #endif
1049 i += 2;
1050 inst1 = evaluate (i) - dsps - 8;
1051 inst0 |= 0x04000000;
1052 }
1053 else {
1054 inst1 = evaluate (i);
1055 patch_label();
1056 }
1057 }
1058 store_inst ();
1059 }
1060
1061 void f_disconnect (void)
1062 {
1063 inst0 = 0x48000000;
1064 store_inst ();
1065 }
1066
1067 void f_set (void)
1068 {
1069 set_clear (0x58000000);
1070 }
1071
1072 void f_clear (void)
1073 {
1074 set_clear (0x60000000);
1075 }
1076
1077 void f_load (void)
1078 {
1079 inst0 = 0xe1000000;
1080 if (arch < ARCH810) {
1081 errout ("Wrong arch for load/store");
1082 return;
1083 }
1084 loadstore(tokenix);
1085 }
1086
1087 void f_store (void)
1088 {
1089 int i;
1090 inst0 = 0xe0000000;
1091 if (arch < ARCH810) {
1092 errout ("Wrong arch for load/store");
1093 return;
1094 }
1095 i = tokenix;
1096 if (reserved("noflush", i)) {
1097 inst0 |= 0x2000000;
1098 i++;
1099 }
1100 loadstore(i);
1101 }
1102
1103 void f_nop (void)
1104 {
1105 inst0 = 0x80000000;
1106 inst1 = 0x00000000;
1107 store_inst ();
1108 }
1109
1110 void loadstore(int i)
1111 {
1112 int reg, size;
1113
1114 reg = CheckRegister(i);
1115 if (reg < 0)
1116 errout ("Expected register");
1117 else
1118 inst0 |= reg << 16;
1119 if (reg == 8)
1120 errout ("Register can't be SFBR");
1121 i++;
1122 if (tokens[i].type == ',')
1123 i++;
1124 else
1125 errout ("expected ','");
1126 size = evaluate(i);
1127 if (i < 1 || i > 4)
1128 errout("wrong size");
1129 if ((reg & 0x3) + size > 4)
1130 errout("size too big for register");
1131 inst0 |= size;
1132 i++;
1133 if (tokens[i].type == ',')
1134 i++;
1135 else
1136 errout ("expected ','");
1137 if (reserved("from", i) || reserved("dsarel", i)) {
1138 if (arch < ARCH710) {
1139 errout ("Wrong arch for table indirect");
1140 return;
1141 }
1142 i++;
1143 inst0 |= 0x10000000;
1144 }
1145 inst1 = evaluate(i);
1146 store_inst ();
1147 }
1148
1149 void transfer (int word0, int type)
1150 {
1151 int i;
1152
1153 i = tokenix;
1154 inst0 = word0;
1155 if (type == 0 && reserved ("rel", i)) {
1156 #if 0 /* driver will fix relative dsps to absolute */
1157 if (arch < ARCH710) {
1158 errout ("Wrong arch for relative dsps");
1159 }
1160 #endif
1161 inst1 = evaluate (i + 2) - dsps - 8;
1162 i += 4;
1163 inst0 |= 0x00800000;
1164 }
1165 else if (type != 1) {
1166 inst1 = evaluate (i);
1167 ++i;
1168 if (type == 0)
1169 patch_label();
1170 }
1171 if (i >= ntokens) {
1172 inst0 |= 0x00080000;
1173 store_inst ();
1174 return;
1175 }
1176 if (tokens[i].type != ',')
1177 errout ("Expected a separator, ',' assumed");
1178 else
1179 ++i;
1180 if (reserved("when", i))
1181 inst0 |= 0x00010000;
1182 else if (reserved ("if", i) == 0) {
1183 errout ("Expected a reserved word");
1184 store_inst ();
1185 return;
1186 }
1187 i++;
1188 if (reserved("false", i)) {
1189 store_inst ();
1190 return;
1191 }
1192 if (reserved ("not", i))
1193 ++i;
1194 else
1195 inst0 |= 0x00080000;
1196 if (reserved ("atn", i)) {
1197 inst0 |= 0x00020000;
1198 ++i;
1199 } else if (CheckPhase (i)) {
1200 inst0 |= 0x00020000;
1201 ++i;
1202 }
1203 if (i < ntokens && tokens[i].type != ',') {
1204 if (inst0 & 0x00020000) {
1205 if (inst0 & 0x00080000 && reserved ("and", i)) {
1206 ++i;
1207 }
1208 else if ((inst0 & 0x00080000) == 0 && reserved ("or", i)) {
1209 ++i;
1210 }
1211 else
1212 errout ("Expected a reserved word");
1213 }
1214 inst0 |= 0x00040000 + (evaluate (i++) & 0xff);
1215 }
1216 if (i < ntokens) {
1217 if (tokens[i].type == ',')
1218 ++i;
1219 else
1220 errout ("Expected a separator, ',' assumed");
1221 if (reserved ("and", i) && reserved ("mask", i + 1))
1222 inst0 |= ((evaluate (i + 2) & 0xff) << 8);
1223 else
1224 errout ("Expected , AND MASK");
1225 }
1226 store_inst ();
1227 }
1228
1229 void select_reselect (int t)
1230 {
1231 inst0 |= 0x40000000; /* ATN may be set from SELECT */
1232 if (reserved ("from", t)) {
1233 if (arch < ARCH710) {
1234 errout ("Wrong arch for table indirect");
1235 return;
1236 }
1237 ++t;
1238 inst0 |= 0x02000000 | evaluate (t++);
1239 }
1240 else
1241 inst0 |= (evaluate (t++) & 0xff) << 16;
1242 if (tokens[t++].type == ',') {
1243 if (reserved ("rel", t)) {
1244 #if 0 /* driver will fix relative dsps to absolute */
1245 if (arch < ARCH710) {
1246 errout ("Wrong arch for relative dsps");
1247 }
1248 #endif
1249 inst0 |= 0x04000000;
1250 inst1 = evaluate (t + 2) - dsps - 8;
1251 }
1252 else {
1253 inst1 = evaluate (t);
1254 patch_label();
1255 }
1256 }
1257 else
1258 errout ("Expected separator");
1259 store_inst ();
1260 }
1261
1262 void set_clear (u_int32_t code)
1263 {
1264 int i = tokenix;
1265 short need_and = 0;
1266
1267 inst0 = code;
1268 while (i < ntokens) {
1269 if (need_and) {
1270 if (reserved ("and", i))
1271 ++i;
1272 else
1273 errout ("Expected AND");
1274 }
1275 if (reserved ("atn", i)) {
1276 inst0 |= 0x0008;
1277 ++i;
1278 }
1279 else if (reserved ("ack", i)) {
1280 inst0 |= 0x0040;
1281 ++i;
1282 }
1283 else if (reserved ("target", i)) {
1284 inst0 |= 0x0200;
1285 ++i;
1286 }
1287 else if (reserved ("carry", i)) {
1288 inst0 |= 0x0400;
1289 ++i;
1290 }
1291 else
1292 errout ("Expected ATN, ACK, TARGET or CARRY");
1293 need_and = 1;
1294 }
1295 store_inst ();
1296 }
1297
1298 void block_move ()
1299 {
1300 if (reserved ("from", tokenix)) {
1301 if (arch < ARCH710) {
1302 errout ("Wrong arch for table indirect");
1303 return;
1304 }
1305 inst1 = evaluate (tokenix+1);
1306 inst0 |= 0x10000000 | inst1; /*** ??? to match Zeus script */
1307 tokenix += 2;
1308 }
1309 else {
1310 inst0 |= evaluate (tokenix++); /* count */
1311 tokenix++; /* skip ',' */
1312 if (reserved ("ptr", tokenix)) {
1313 ++ tokenix;
1314 inst0 |= 0x20000000;
1315 }
1316 inst1 = evaluate (tokenix++); /* address */
1317 }
1318 if (tokens[tokenix].type != ',')
1319 errout ("Expected separator");
1320 if (reserved ("when", tokenix + 1)) {
1321 inst0 |= 0x08000000;
1322 CheckPhase (tokenix + 2);
1323 }
1324 else if (reserved ("with", tokenix + 1)) {
1325 CheckPhase (tokenix + 2);
1326 }
1327 else
1328 errout ("Expected WITH or WHEN");
1329 }
1330
1331 void register_write ()
1332 {
1333 /*
1334 * MOVE reg/data8 TO reg register write
1335 * MOVE reg <op> data8 TO reg register write
1336 * MOVE reg + data8 TO reg WITH CARRY register write
1337 */
1338 int op;
1339 int reg;
1340 int data;
1341
1342 if (reserved ("to", tokenix+1))
1343 op = 0;
1344 else if (reserved ("shl", tokenix+1))
1345 op = 1;
1346 else if (reserved ("shr", tokenix+1))
1347 op = 5;
1348 else if (tokens[tokenix+1].type == '|')
1349 op = 2;
1350 else if (reserved ("xor", tokenix+1))
1351 op = 3;
1352 else if (tokens[tokenix+1].type == '&')
1353 op = 4;
1354 else if (tokens[tokenix+1].type == '+')
1355 op = 6;
1356 else if (tokens[tokenix+1].type == '-')
1357 op = 8;
1358 else
1359 errout ("Unknown register operator");
1360 switch (op) {
1361 case 2:
1362 case 3:
1363 case 4:
1364 case 6:
1365 case 8:
1366 if (reserved ("to", tokenix+3) == 0)
1367 errout ("Register command expected TO");
1368 default:
1369 }
1370 reg = CheckRegister (tokenix);
1371 if (reg < 0) { /* Not register, must be data */
1372 data = evaluate (tokenix);
1373 if (op)
1374 errout ("Register operator not move");
1375 reg = CheckRegister (tokenix+2);
1376 if (reg < 0)
1377 errout ("Expected register");
1378 inst0 = 0x78000000 | (data << 8) | reg << 16;
1379 #if 0
1380 fprintf (listfp, "Move data to register: %02x %d\n", data, reg);
1381 #endif
1382 } else if (op) {
1383 switch (op) {
1384 case 2:
1385 case 3:
1386 case 4:
1387 case 6:
1388 case 8:
1389 inst0 = 0;
1390 /* A register read/write operator */
1391 if (reserved("sfbr", tokenix+2)) {
1392 if (arch < ARCH825)
1393 errout("wrong arch for add with SFBR");
1394 if (op == 8)
1395 errout("can't substract SFBR");
1396 inst0 |= 0x00800000;
1397 data = 0;
1398 } else
1399 data = evaluate (tokenix+2);
1400 if (tokenix+5 < ntokens) {
1401 if (!reserved("with", tokenix+5) ||
1402 !reserved("carry", tokenix+6)) {
1403 errout("Expected 'WITH CARRY'");
1404 } else if (op != 6) {
1405 errout("'WITH CARRY' only valide "
1406 "with '+'");
1407 }
1408 op = 7;
1409 }
1410 if (op == 8) {
1411 data = -data;
1412 op = 6;
1413 }
1414 inst0 |= (data & 0xff) << 8;
1415 data = CheckRegister (tokenix+4);
1416 break;
1417 default:
1418 data = CheckRegister (tokenix+2);
1419 break;
1420 }
1421 if (data < 0)
1422 errout ("Expected register");
1423 if (reg != data && reg != 8 && data != 8)
1424 errout ("One register MUST be SBFR");
1425 if (reg == data) { /* A register read/modify/write */
1426 #if 0
1427 fprintf (listfp, "Read/modify register: %02x %d %d\n", inst0 >> 8, op, reg);
1428 #endif
1429 inst0 |= 0x78000000 | (op << 24) | (reg << 16);
1430 }
1431 else { /* A move to/from SFBR */
1432 if (reg == 8) { /* MOVE SFBR <> TO reg */
1433 #if 0
1434 fprintf (listfp, "Move SFBR to register: %02x %d %d\n", inst0 >> 8, op, data);
1435 #endif
1436 inst0 |= 0x68000000 | (op << 24) | (data << 16);
1437 }
1438 else {
1439 #if 0
1440 fprintf (listfp, "Move register to SFBR: %02x %d %d\n", inst0 >> 8, op, reg);
1441 #endif
1442 inst0 |= 0x70000000 | (op << 24) | (reg << 16);
1443 }
1444 }
1445 } else { /* register to register */
1446 data = CheckRegister (tokenix+2);
1447 if (data < 0)
1448 errout ("Expected register");
1449 if (reg == 8) /* move SFBR to reg */
1450 inst0 = 0x6a000000 | (data << 16);
1451 else if (data == 8) /* move reg to SFBR */
1452 inst0 = 0x72000000 | (reg << 16);
1453 else
1454 errout ("One register must be SFBR");
1455 }
1456 }
1457
1458 void memory_to_memory ()
1459 {
1460 inst0 = 0xc0000000 + evaluate (tokenix+1);
1461 inst1 = evaluate (tokenix+3);
1462 /*
1463 * need to hack dsps, otherwise patch offset will be wrong for
1464 * second pointer
1465 */
1466 dsps += 4;
1467 inst2 = evaluate (tokenix+5);
1468 dsps -= 4;
1469 }
1470
1471 void error_line()
1472 {
1473 if (errfp != listfp && errfp && err_listed == 0) {
1474 fprintf (errfp, "%3d: %s", lineno, inbuf);
1475 err_listed = 1;
1476 }
1477 }
1478
1479 char * makefn (base, sub)
1480 char *base;
1481 char *sub;
1482 {
1483 char *fn;
1484
1485 fn = malloc (strlen (base) + strlen (sub) + 2);
1486 strcpy (fn, base);
1487 base = strrchr(fn, '.');
1488 if (base)
1489 *base = 0;
1490 strcat (fn, ".");
1491 strcat (fn, sub);
1492 return (fn);
1493 }
1494
1495 void usage()
1496 {
1497 fprintf (stderr, "usage: scc sourcfile [options]\n");
1498 exit(1);
1499 }
1500