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