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