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