Annotation of sys/dev/microcode/ncr53cxxx/ncr53cxxx.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ncr53cxxx.c,v 1.4 2003/04/06 18:54:20 ho Exp $ */
2:
3: /*
4: * Copyright (c) 1995 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: /* scc.c - SCSI SCRIPTS Compiler */
34:
35: #include <stdio.h>
36: #include <stdlib.h>
37: #include <string.h>
38:
39: #ifndef AMIGA
40: #define strcmpi strcasecmp
41: #endif
42:
43: #define MAXTOKENS 16
44: #define MAXINST 1024
45: #define MAXSYMBOLS 128
46:
47: struct {
48: long type;
49: char *name;
50: } tokens[MAXTOKENS];
51: int ntokens;
52: int tokenix;
53:
54: void f_proc (void);
55: void f_pass (void);
56: void f_list (void); /* ENTRY, EXTERNAL label list */
57: void f_define (void); /* ABSOLUTE, RELATIVE label list */
58: void f_move (void);
59: void f_jump (void);
60: void f_call (void);
61: void f_return (void);
62: void f_int (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_arch (void);
70:
71: struct {
72: char *name;
73: void (*func)(void);
74: } directives[] = {
75: "PROC", f_proc,
76: "PASS", f_pass,
77: "ENTRY", f_list,
78: "ABSOLUTE", f_define,
79: "EXTERN", f_list,
80: "EXTERNAL", f_list,
81: "RELATIVE", f_define,
82: "MOVE", f_move,
83: "JUMP", f_jump,
84: "CALL", f_call,
85: "RETURN", f_return,
86: "INT", f_int,
87: "SELECT", f_select,
88: "RESELECT", f_reselect,
89: "WAIT", f_wait,
90: "DISCONNECT", f_disconnect,
91: "SET", f_set,
92: "CLEAR", f_clear,
93: "ARCH", f_arch,
94: NULL};
95:
96: unsigned long script[MAXINST];
97: int dsps;
98: char *script_name = "SCRIPT";
99: unsigned long inst0, inst1, inst2;
100: unsigned long ninsts;
101: unsigned long npatches;
102:
103: struct patchlist {
104: struct patchlist *next;
105: unsigned offset;
106: };
107:
108: #define S_LABEL 0x0000
109: #define S_ABSOLUTE 0x0001
110: #define S_RELATIVE 0x0002
111: #define S_EXTERNAL 0x0003
112: #define F_DEFINED 0x0001
113: #define F_ENTRY 0x0002
114: struct {
115: short type;
116: short flags;
117: unsigned long value;
118: struct patchlist *patchlist;
119: char *name;
120: } symbols[MAXSYMBOLS];
121: int nsymbols;
122:
123: char *stypes[] = {"Label", "Absolute", "Relative", "External"};
124:
125: char *phases[] = {
126: "data_out", "data_in", "cmd", "status",
127: "res4", "res5", "msg_out", "msg_in"
128: };
129:
130: char *regs710[] = {
131: "scntl0", "scntl1", "sdid", "sien",
132: "scid", "sxfer", "sodl", "socl",
133: "sfbr", "sidl", "sbdl", "sbcl",
134: "dstat", "sstat0", "sstat1", "sstat2",
135: "dsa0", "dsa1", "dsa2", "dsa3",
136: "ctest0", "ctest1", "ctest2", "ctest3",
137: "ctest4", "ctest5", "ctest6", "ctest7",
138: "temp0", "temp1", "temp2", "temp3",
139: "dfifo", "istat", "ctest8", "lcrc",
140: "dbc0", "dbc1", "dbc2", "dcmd",
141: "dnad0", "dnad1", "dnad2", "dnad3",
142: "dsp0", "dsp1", "dsp2", "dsp3",
143: "dsps0", "dsps1", "dsps2", "dsps3",
144: "scratch0", "scratch1", "scratch2", "scratch3",
145: "dmode", "dien", "dwt", "dcntl",
146: "addr0", "addr1", "addr2", "addr3"
147: };
148:
149: char *regs720[] = {
150: "scntl0", "scntl1", "scntl2", "scntl3",
151: "scid", "sxfer", "sdid", "gpreg",
152: "sfbr", "socl", "ssid", "sbcl",
153: "dstat", "sstat0", "sstat1", "sstat2",
154: "dsa0", "dsa1", "dsa2", "dsa3",
155: "istat", "", "", "",
156: "ctest0", "ctest1", "ctest2", "ctest3",
157: "temp0", "temp1", "temp2", "temp3",
158: "dfifo", "ctest4", "ctest5", "ctest6",
159: "dbc0", "dbc1", "dbc2", "dcmd",
160: "dnad0", "dnad1", "dnad2", "dnad3",
161: "dsp0", "dsp1", "dsp2", "dsp3",
162: "dsps0", "dsps1", "dsps2", "dsps3",
163: "scratcha0", "scratcha1", "scratcha2", "scratcha3",
164: "dmode", "dien", "dwt", "dcntl",
165: "addr0", "addr1", "addr2", "addr3",
166: "sien0", "sien1", "sist0", "sist1",
167: "slpar", "swide", "macntl", "gpcntl",
168: "stime0", "stime1", "respid0", "respid1",
169: "stest0", "stest1", "stest2", "stest3",
170: "sidl0", "sidl1", "", "",
171: "sodl0", "sodl1", "", "",
172: "sbdl0", "sbdl1", "", "",
173: "scratchb0", "scratchb1", "scratchb2", "scratchb3",
174: };
175:
176: int lineno;
177: int err_listed;
178: int arch;
179:
180: char inbuf[128];
181:
182: char *sourcefile;
183: char *outputfile;
184: char *listfile;
185: char *errorfile;
186:
187: FILE *infp;
188: FILE *outfp;
189: FILE *listfp;
190: FILE *errfp;
191:
192: void parse (void);
193: void process (void);
194: void emit_symbols (void);
195: void list_symbols (void);
196: void errout (char *);
197: void define_symbol (char *, unsigned long, short, short);
198: void close_script (void);
199: void new_script (char *);
200: void store_inst (void);
201: int expression (int *);
202: int evaluate (int);
203: int number (char *);
204: int lookup (char *);
205: int reserved (char *, int);
206: int CheckPhase (int);
207: int CheckRegister (int);
208: void transfer (int, int);
209: void select_reselect (int);
210: void set_clear (unsigned long);
211: void block_move (void);
212: void register_write (void);
213: void memory_to_memory (void);
214: void error_line(void);
215: char *makefn(char *, char *);
216: void usage(void);
217:
218: main (int argc, char *argv[])
219: {
220: int i;
221:
222: if (argc < 2 || argv[1][0] == '-')
223: usage();
224: sourcefile = argv[1];
225: infp = fopen (sourcefile, "r");
226: if (infp == NULL) {
227: perror ("open source");
228: fprintf (stderr, "scc: error opening source file %s\n", argv[1]);
229: exit (1);
230: }
231: /*
232: * process options
233: * -l [listfile]
234: * -o [outputfile]
235: * -z [debugfile]
236: * -e [errorfile]
237: * -a arch
238: * -v
239: * -u
240: */
241: for (i = 2; i < argc; ++i) {
242: if (argv[i][0] != '-')
243: usage();
244: switch (argv[i][1]) {
245: case 'o':
246: if (i + 1 >= argc || argv[i + 1][0] == '-')
247: outputfile = makefn (sourcefile, "out");
248: else {
249: outputfile = argv[i + 1];
250: ++i;
251: }
252: break;
253: case 'l':
254: if (i + 1 >= argc || argv[i + 1][0] == '-')
255: listfile = makefn (sourcefile, "lis");
256: else {
257: listfile = argv[i + 1];
258: ++i;
259: }
260: break;
261: case 'e':
262: if (i + 1 >= argc || argv[i + 1][0] == '-')
263: errorfile = makefn (sourcefile, "err");
264: else {
265: errorfile = argv[i + 1];
266: ++i;
267: }
268: break;
269: case 'a':
270: if (i + 1 == argc)
271: usage();
272: arch = 0;
273: arch = atoi(argv[i +1]);
274: if(arch != 720 && arch != 710) {
275: fprintf(stderr,"%s: bad arch '%s'\n",
276: argv[0], argv[i +1]);
277: exit(1);
278: }
279: ++i;
280: break;
281: default:
282: fprintf (stderr, "scc: unrecognized option '%c'\n",
283: argv[i][1]);
284: usage();
285: }
286: }
287: if (outputfile)
288: outfp = fopen (outputfile, "w");
289: if (listfile)
290: listfp = fopen (listfile, "w");
291: if (errorfile)
292: errfp = fopen (errorfile, "w");
293: else
294: errfp = stderr;
295:
296: while (fgets (inbuf, sizeof (inbuf), infp)) {
297: ++lineno;
298: if (listfp)
299: fprintf (listfp, "%3d: %s", lineno, inbuf);
300: err_listed = 0;
301: parse ();
302: if (ntokens) {
303: #ifdef DUMP_TOKENS
304: int i;
305:
306: fprintf (listfp, " %d tokens\n", ntokens);
307: for (i = 0; i < ntokens; ++i) {
308: fprintf (listfp, " %d: ", i);
309: if (tokens[i].type)
310: fprintf (listfp,"'%c'\n", tokens[i].type);
311: else
312: fprintf (listfp, "%s\n", tokens[i].name);
313: }
314: #endif
315: if (ntokens >= 2 && tokens[0].type == 0 &&
316: tokens[1].type == ':') {
317: define_symbol (tokens[0].name, dsps, S_LABEL, F_DEFINED);
318: tokenix += 2;
319: }
320: if (tokenix < ntokens)
321: process ();
322: }
323:
324: }
325: close_script ();
326: emit_symbols ();
327: if (outfp) {
328: fprintf (outfp, "\nunsigned long INSTRUCTIONS = 0x%08x;\n", ninsts);
329: fprintf (outfp, "unsigned long PATCHES = 0x%08x;\n", npatches);
330: }
331: list_symbols ();
332: }
333:
334: void emit_symbols ()
335: {
336: int i;
337: struct patchlist *p;
338:
339: if (nsymbols == 0 || outfp == NULL)
340: return;
341:
342: for (i = 0; i < nsymbols; ++i) {
343: char *code;
344: if (symbols[i].type == S_ABSOLUTE)
345: code = "A_";
346: else if (symbols[i].type == S_RELATIVE)
347: code = "R_";
348: else if (symbols[i].type == S_EXTERNAL)
349: code = "E_";
350: else if (symbols[i].flags & F_ENTRY)
351: code = "Ent_";
352: else
353: continue;
354: fprintf (outfp, "#define\t%s%s\t0x%08x\n", code, symbols[i].name,
355: symbols[i].value);
356: if (symbols[i].flags & F_ENTRY || symbols[i].patchlist == NULL)
357: continue;
358: fprintf (outfp, "unsigned long %s%s_Used[] = {\n", code, symbols[i].name);
359: #if 1
360: p = symbols[i].patchlist;
361: while (p) {
362: fprintf (outfp, "\t%08x,\n", p->offset / 4);
363: p = p->next;
364: }
365: #endif
366: fprintf (outfp, "};\n\n");
367: }
368: /* patches ? */
369: }
370:
371: void list_symbols ()
372: {
373: int i;
374:
375: if (nsymbols == 0 || listfp == NULL)
376: return;
377: fprintf (listfp, "\n\nValue Type Symbol\n");
378: for (i = 0; i < nsymbols; ++i) {
379: fprintf (listfp, "%08x: %-8s %s\n", symbols[i].value,
380: stypes[symbols[i].type], symbols[i].name);
381: }
382: }
383:
384: void errout (char *text)
385: {
386: error_line();
387: fprintf (errfp, "*** %s ***\n", text);
388: }
389:
390: void parse ()
391: {
392: char *p = inbuf;
393: char c;
394: char string[64];
395: char *s;
396: size_t len;
397:
398: ntokens = tokenix = 0;
399: while (1) {
400: while ((c = *p++) && c != '\n' && c <= ' ' || c == '\t')
401: ;
402: if (c == '\n' || c == 0 || c == ';')
403: break;
404: if (ntokens >= MAXTOKENS) {
405: errout ("Token table full");
406: break;
407: }
408: if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
409: (c >= 'A' && c <= 'Z') || c == '$' || c == '_') {
410: s = string;
411: *s++ = c;
412: while (((c = *p) >= '0' && c <= '9') ||
413: (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
414: c == '_' || c == '$') {
415: *s++ = *p++;
416: }
417: *s = 0;
418: len = strlen (string) + 1;
419: tokens[ntokens].name = malloc (len);
420: strlcpy (tokens[ntokens].name, string, len);
421: tokens[ntokens].type = 0;
422: }
423: else {
424: tokens[ntokens].type = c;
425: }
426: ++ntokens;
427: }
428: return;
429: }
430:
431: void process ()
432: {
433: int i;
434:
435: if (tokens[tokenix].type) {
436: error_line();
437: fprintf (errfp, "Error: expected directive, found '%c'\n",
438: tokens[tokenix].type);
439: return;
440: }
441: for (i = 0; directives[i].name; ++i) {
442: if (strcmpi (directives[i].name, tokens[tokenix].name) == 0)
443: break;
444: }
445: if (directives[i].name == NULL) {
446: error_line();
447: fprintf (errfp, "Error: expected directive, found \"%s\"\n",
448: tokens[tokenix].name);
449: return;
450: }
451: if (directives[i].func == NULL) {
452: error_line();
453: fprintf (errfp, "No function for directive \"%s\"\n", tokens[tokenix].name);
454: } else {
455: #if 0
456: fprintf (listfp, "Processing directive \"%s\"\n", directives[i].name);
457: #endif
458: ++tokenix;
459: (*directives[i].func) ();
460: }
461: }
462:
463: void define_symbol (char *name, unsigned long value, short type, short flags)
464: {
465: int i;
466: struct patchlist *p;
467: size_t len;
468:
469: for (i = 0; i < nsymbols; ++i) {
470: if (symbols[i].type == type && strcmp (symbols[i].name, name) == 0) {
471: if (symbols[i].flags & F_DEFINED) {
472: error_line();
473: fprintf (errfp, "*** Symbol \"%s\" multiply defined\n",
474: name);
475: } else {
476: symbols[i].flags |= flags;
477: symbols[i].value = value;
478: p = symbols[i].patchlist;
479: while (p) {
480: if (p->offset > dsps)
481: errout ("Whoops\007");
482: else
483: script[p->offset / 4] = dsps - p->offset - 4;
484: p = p->next;
485: }
486: }
487: return;
488: }
489: }
490: if (nsymbols >= MAXSYMBOLS) {
491: errout ("Symbol table full");
492: return;
493: }
494: symbols[nsymbols].type = type;
495: symbols[nsymbols].flags = flags;
496: symbols[nsymbols].value = value;
497: symbols[nsymbols].patchlist = NULL;
498: len = strlen (name) + 1;
499: symbols[nsymbols].name = malloc (len);
500: strlcpy (symbols[nsymbols].name, name, len);
501: ++nsymbols;
502: }
503:
504: void close_script ()
505: {
506: int i;
507:
508: if (dsps == 0)
509: return;
510: if (outfp) {
511: fprintf (outfp, "unsigned long %s[] = {\n", script_name);
512: for (i = 0; i < dsps / 4; i += 2) {
513: fprintf (outfp, "\t0x%08x, 0x%08x", script[i],
514: script[i + 1]);
515: /* check for memory move instruction */
516: if (script[i] >> 30 == 3)
517: fprintf (outfp, ", 0x%08x,", script[i + 2]);
518: else
519: if ((i + 2) <= dsps / 4) fprintf (outfp, ",\t\t");
520: fprintf (outfp, "\t/* %03x - %3d */\n", i * 4, i * 4);
521: if (script[i] >> 30 == 3)
522: ++i;
523: }
524: fprintf (outfp, "};\n\n");
525: }
526: dsps = 0;
527: }
528:
529: void new_script (char *name)
530: {
531: size_t len = strlen (name) + 1;
532:
533: close_script ();
534: script_name = malloc (len);
535: strlcpy (script_name, name, len);
536: }
537:
538: int reserved (char *string, int t)
539: {
540: if (tokens[t].type == 0 && strcmpi (tokens[t].name, string) == 0)
541: return (1);
542: return (0);
543: }
544:
545: int CheckPhase (int t)
546: {
547: int i;
548:
549: for (i = 0; i < 8; ++i) {
550: if (reserved (phases[i], t)) {
551: inst0 |= i << 24;
552: return (1);
553: }
554: }
555: return (0);
556: }
557:
558: int CheckRegister (int t)
559: {
560: int i;
561:
562: if(arch == 710) {
563: for (i = 0; i < 64; ++i)
564: if (reserved (regs710[i], t))
565: return i;
566: }
567: else if (arch == 720) {
568: for (i = 0; i < 96; ++i)
569: if (reserved (regs720[i], t))
570: return i;
571: }
572: else {
573: errout("'ARCH' statement missing");
574: }
575: return (-1);
576: }
577:
578: int expression (int *t)
579: {
580: int value;
581: int i = *t;
582:
583: value = evaluate (i++);
584: while (i < ntokens) {
585: if (tokens[i].type == '+')
586: value += evaluate (i + 1);
587: else if (tokens[i].type == '-')
588: value -= evaluate (i + 1);
589: else
590: errout ("Unknown identifier");
591: i += 2;
592: }
593: *t = i;
594: return (value);
595: }
596:
597: int evaluate (t)
598: {
599: int value;
600: char *name;
601:
602: if (tokens[t].type) {
603: errout ("Expected an identifier");
604: return (0);
605: }
606: name = tokens[t].name;
607: if (*name >= '0' && *name <= '9')
608: value = number (name);
609: else
610: value = lookup (name);
611: return (value);
612: }
613:
614: int number (char *s)
615: {
616: int value;
617: int n;
618: int radix;
619:
620: radix = 10;
621: if (*s == '0') {
622: ++s;
623: radix = 8;
624: switch (*s) {
625: case 'x':
626: case 'X':
627: radix = 16;
628: break;
629: case 'b':
630: case 'B':
631: radix = 2;
632: }
633: if (radix != 8)
634: ++s;
635: }
636: value = 0;
637: while (*s) {
638: n = *s++;
639: if (n >= '0' && n <= '9')
640: n -= '0';
641: else if (n >= 'a' && n <= 'f')
642: n -= 'a' - 10;
643: else if (n >= 'A' && n <= 'F')
644: n -= 'A' - 10;
645: else {
646: error_line();
647: fprintf (errfp, "*** Expected digit\n", n = 0);
648: }
649: if (n >= radix)
650: errout ("Expected digit");
651: else
652: value = value * radix + n;
653: }
654: return (value);
655: }
656:
657: int lookup (char *name)
658: {
659: int i;
660: struct patchlist *p;
661: size_t len;
662:
663: for (i = 0; i < nsymbols; ++i) {
664: if (strcmp (name, symbols[i].name) == 0) {
665: if ((symbols[i].flags & F_DEFINED) == 0) {
666: p = (struct patchlist *) &symbols[i].patchlist;
667: while (p->next)
668: p = p->next;
669: p->next = (struct patchlist *) malloc (sizeof (struct patchlist));
670: p = p->next;
671: p->next = NULL;
672: p->offset = dsps + 4;
673: }
674: return ((int) symbols[i].value);
675: }
676: }
677: if (nsymbols >= MAXSYMBOLS) {
678: errout ("Symbol table full");
679: return (0);
680: }
681: symbols[nsymbols].type = S_LABEL; /* assume forward reference */
682: symbols[nsymbols].flags = 0;
683: symbols[nsymbols].value = 0;
684: p = (struct patchlist *) malloc (sizeof (struct patchlist));
685: symbols[nsymbols].patchlist = p;
686: p->next = NULL;
687: p->offset = dsps + 4;
688: len = strlen (name) + 1;
689: symbols[nsymbols].name = malloc (len);
690: strlcpy (symbols[nsymbols].name, name, len);
691: ++nsymbols;
692: return (0);
693: }
694:
695: void f_arch (void)
696: {
697: int i, archsave;
698:
699: i = tokenix;
700:
701: archsave = arch;
702: arch = 0;
703: arch = atoi(tokens[i].name);
704: if( arch != 710 && arch != 720) {
705: errout("Unrecognized ARCH");
706: arch = archsave;
707: }
708: }
709:
710: void f_proc (void)
711: {
712: if (tokens[tokenix].type != 0 || tokens[tokenix + 1].type != ':')
713: errout ("Invalid PROC statement");
714: else
715: new_script (tokens[tokenix].name);
716: }
717:
718: void f_pass (void)
719: {
720: errout ("PASS option not implemented");
721: }
722:
723: /*
724: * f_list: process list of symbols for the ENTRY and EXTERNAL directive
725: */
726:
727: void f_list (void)
728: {
729: int i;
730: short type;
731: short flags;
732:
733: type = strcmpi (tokens[tokenix-1].name, "ENTRY") ? S_EXTERNAL : S_LABEL;
734: flags = type == S_LABEL ? F_ENTRY : 0;
735: for (i = tokenix; i < ntokens; ++i) {
736: if (tokens[i].type != 0) {
737: errout ("Expected an identifier");
738: return;
739: }
740: define_symbol (tokens[i].name, 0, type, flags);
741: if (i + 1 < ntokens) {
742: if (tokens[++i].type == ',')
743: continue;
744: errout ("Expected a separator");
745: return;
746: }
747: }
748: }
749:
750: /*
751: * f_define: process list of definitions for ABSOLUTE and RELATIVE directive
752: */
753:
754: void f_define (void)
755: {
756: int i;
757: char *name;
758: unsigned long value;
759: int type;
760:
761: type = strcmpi (tokens[tokenix-1].name, "ABSOLUTE") ? S_RELATIVE : S_ABSOLUTE;
762: i = tokenix;
763: while (i < ntokens) {
764: if (tokens[i].type) {
765: errout ("Expected an identifier");
766: return;
767: }
768: if (tokens[i + 1].type != '=') {
769: errout ("Expected a separator");
770: return;
771: }
772: name = tokens[i].name;
773: i += 2;
774: value = expression (&i);
775: define_symbol (name, value, type, F_DEFINED);
776: }
777: }
778:
779: void store_inst ()
780: {
781: int i = dsps / 4;
782: int l = 8;
783:
784: if ((inst0 & 0xc0000000) == 0xc0000000)
785: l = 12; /* Memory to memory move is 12 bytes */
786: if ((dsps + l) / 4 > MAXINST) {
787: errout ("Instruction table overflow");
788: return;
789: }
790: script[i++] = inst0;
791: script[i++] = inst1;
792: if (l == 12)
793: script[i] = inst2;
794: if (listfp) {
795: fprintf (listfp, "\t%04x: %08x %08x", dsps, inst0, inst1);
796: if (l == 12)
797: fprintf (listfp, " %08x", inst2);
798: fprintf (listfp, "\n");
799: }
800: dsps += l;
801: inst0 = inst1 = inst2 = 0;
802: ++ninsts;
803: }
804:
805: void f_move (void)
806: {
807: if (reserved ("memory", tokenix))
808: memory_to_memory ();
809: else if (reserved ("from", tokenix) || tokens[tokenix+1].type == ',')
810: block_move ();
811: else
812: register_write ();
813: store_inst ();
814: }
815:
816: void f_jump (void)
817: {
818: transfer (0x80000000, 0);
819: }
820:
821: void f_call (void)
822: {
823: transfer (0x88000000, 0);
824: }
825:
826: void f_return (void)
827: {
828: transfer (0x90000000, 1);
829: }
830:
831: void f_int (void)
832: {
833: transfer (0x98000000, 2);
834: }
835:
836: void f_select (void)
837: {
838: int t = tokenix;
839:
840: if (reserved ("atn", t)) {
841: inst0 = 0x01000000;
842: ++t;
843: }
844: select_reselect (t);
845: }
846:
847: void f_reselect (void)
848: {
849: select_reselect (tokenix);
850: }
851:
852: void f_wait (void)
853: {
854: int i = tokenix;
855:
856: inst1 = 0;
857: if (reserved ("disconnect", i)) {
858: inst0 = 0x48000000;
859: }
860: else {
861: if (reserved ("reselect", i))
862: inst0 = 0x50000000;
863: else if (reserved ("select", i))
864: inst0 = 0x50000000;
865: else
866: errout ("Expected SELECT or RESELECT");
867: ++i;
868: if (reserved ("rel", i)) {
869: i += 2;
870: inst1 = evaluate (i) - dsps - 8;
871: inst0 |= 0x04000000;
872: }
873: else
874: inst1 = evaluate (i);
875: }
876: store_inst ();
877: }
878:
879: void f_disconnect (void)
880: {
881: inst0 = 0x48000000;
882: store_inst ();
883: }
884:
885: void f_set (void)
886: {
887: set_clear (0x58000000);
888: }
889:
890: void f_clear (void)
891: {
892: set_clear (0x60000000);
893: }
894:
895: void transfer (int word0, int type)
896: {
897: int i;
898:
899: i = tokenix;
900: inst0 = word0;
901: if (type == 0 && reserved ("rel", i)) {
902: inst1 = evaluate (i + 2) - dsps - 8;
903: i += 3;
904: inst0 |= 0x00800000;
905: }
906: else if (type != 1) {
907: inst1 = evaluate (i);
908: }
909: ++i;
910: if (i >= ntokens) {
911: inst0 |= 0x00080000;
912: store_inst ();
913: return;
914: }
915: if (tokens[i].type != ',')
916: errout ("Expected a separator, ',' assumed");
917: else
918: ++i;
919: if (reserved("when", i))
920: inst0 |= 0x00010000;
921: else if (reserved ("if", i) == 0) {
922: errout ("Expected a reserved word");
923: store_inst ();
924: return;
925: }
926: if (reserved ("not", ++i))
927: ++i;
928: else
929: inst0 |= 0x00080000;
930: if (reserved ("atn", i)) {
931: inst0 |= 0x00020000;
932: ++i;
933: } else if (CheckPhase (i)) {
934: inst0 |= 0x00020000;
935: ++i;
936: }
937: if (i < ntokens && tokens[i].type != ',') {
938: if (inst0 & 0x00020000) {
939: if (inst0 & 0x00080000 && reserved ("and", i)) {
940: ++i;
941: }
942: else if ((inst0 & 0x00080000) == 0 && reserved ("or", i)) {
943: ++i;
944: }
945: else
946: errout ("Expected a reserved word");
947: }
948: inst0 |= 0x00040000 + (evaluate (i++) & 0xff);
949: }
950: if (i < ntokens) {
951: if (tokens[i].type == ',')
952: ++i;
953: else
954: errout ("Expected a separator, ',' assumed");
955: if (reserved ("and", i) && reserved ("mask", i + 1))
956: inst0 |= ((evaluate (i + 2) & 0xff) << 8);
957: else
958: errout ("Expected , AND MASK");
959: }
960: store_inst ();
961: }
962:
963: void select_reselect (int t)
964: {
965: inst0 |= 0x40000000; /* ATN may be set from SELECT */
966: if (reserved ("from", t)) {
967: ++t;
968: inst0 |= 0x02000000 | evaluate (t++);
969: }
970: else
971: inst0 |= (evaluate (t++) & 0xff) << 16;
972: if (tokens[t++].type == ',') {
973: if (reserved ("rel", t)) {
974: inst0 |= 0x04000000;
975: inst1 = evaluate (t + 2) - dsps - 8;
976: }
977: else
978: inst1 = evaluate (t);
979: }
980: else
981: errout ("Expected separator");
982: store_inst ();
983: }
984:
985: void set_clear (unsigned long code)
986: {
987: int i = tokenix;
988: short need_and = 0;
989:
990: inst0 = code;
991: while (i < ntokens) {
992: if (need_and) {
993: if (reserved ("and", i))
994: ++i;
995: else
996: errout ("Expected AND");
997: }
998: if (reserved ("atn", i)) {
999: inst0 |= 0x0008;
1000: ++i;
1001: }
1002: else if (reserved ("ack", i)) {
1003: inst0 |= 0x0040;
1004: ++i;
1005: }
1006: else if (reserved ("target", i)) {
1007: inst0 |= 0x0200;
1008: ++i;
1009: }
1010: else
1011: errout ("Expected ATN, ACK, or TARGET");
1012: need_and = 1;
1013: }
1014: store_inst ();
1015: }
1016:
1017: void block_move ()
1018: {
1019: int t;
1020:
1021: if (reserved ("from", tokenix)) {
1022: inst1 = evaluate (tokenix+1);
1023: inst0 |= 0x10000000 | inst1; /*** ??? to match Zeus script */
1024: tokenix += 2;
1025: }
1026: else {
1027: inst0 |= evaluate (tokenix++); /* count */
1028: tokenix++; /* skip ',' */
1029: if (reserved ("ptr", tokenix)) {
1030: ++ tokenix;
1031: inst0 |= 0x20000000;
1032: }
1033: inst1 = evaluate (tokenix++); /* address */
1034: }
1035: if (tokens[tokenix].type != ',')
1036: errout ("Expected separator");
1037: if (reserved ("when", tokenix + 1)) {
1038: inst0 |= 0x08000000;
1039: CheckPhase (tokenix + 2);
1040: }
1041: else if (reserved ("with", tokenix + 1)) {
1042: CheckPhase (tokenix + 2);
1043: }
1044: else
1045: errout ("Expected WITH or WHEN");
1046: }
1047:
1048: void register_write ()
1049: {
1050: /*
1051: * MOVE reg/data8 TO reg register write
1052: * MOVE reg <op> data8 TO reg register write
1053: */
1054: int op;
1055: int reg;
1056: int data;
1057:
1058: if (reserved ("to", tokenix+1))
1059: op = 0;
1060: else if (tokens[tokenix+1].type == '|')
1061: op = 1;
1062: else if (tokens[tokenix+1].type == '&')
1063: op = 2;
1064: else if (tokens[tokenix+1].type == '+')
1065: op = 3;
1066: else if (tokens[tokenix+1].type == '-')
1067: op = 4;
1068: else
1069: errout ("Unknown register operator");
1070: if (op && reserved ("to", tokenix+3) == 0)
1071: errout ("Register command expected TO");
1072: reg = CheckRegister (tokenix);
1073: if (reg < 0) { /* Not register, must be data */
1074: data = evaluate (tokenix);
1075: if (op)
1076: errout ("Register operator not move");
1077: reg = CheckRegister (tokenix+2);
1078: if (reg < 0)
1079: errout ("Expected register");
1080: inst0 = 0x78000000 | (data << 8) | reg;
1081: #if 0
1082: fprintf (listfp, "Move data to register: %02x %d\n", data, reg);
1083: #endif
1084: }
1085: else if (op) { /* A register read/write operator */
1086: data = evaluate (tokenix+2);
1087: if (op == 4) {
1088: data = -data;
1089: op = 3;
1090: }
1091: inst0 = (data & 0xff) << 8;
1092: data = CheckRegister (tokenix+4);
1093: if (data < 0)
1094: errout ("Expected register");
1095: if (reg != data && reg != 8 && data != 8)
1096: errout ("One register MUST be SBFR");
1097: if (reg == data) { /* A register read/modify/write */
1098: #if 0
1099: fprintf (listfp, "Read/modify register: %02x %d %d\n", inst0 >> 8, op, reg);
1100: #endif
1101: inst0 |= 0x78000000 | (op << 25) | (reg << 16);
1102: }
1103: else { /* A move to/from SFBR */
1104: if (reg == 8) { /* MOVE SFBR <> TO reg */
1105: #if 0
1106: fprintf (listfp, "Move SFBR to register: %02x %d %d\n", inst0 >> 8, op, data);
1107: #endif
1108: inst0 |= 0x68000000 | (op << 25) | (data << 16);
1109: }
1110: else {
1111: #if 0
1112: fprintf (listfp, "Move register to SFBR: %02x %d %d\n", inst0 >> 8, op, reg);
1113: #endif
1114: inst0 |= 0x70000000 | (op << 25) | (reg << 16);
1115: }
1116: }
1117: }
1118: else { /* register to register */
1119: data = CheckRegister (tokenix+2);
1120: if (reg == 8) /* move SFBR to reg */
1121: inst0 = 0x6a000000 | (data << 16);
1122: else if (data == 8) /* move reg to SFBR */
1123: inst0 = 0x72000000 | (reg << 16);
1124: else
1125: errout ("One register must be SFBR");
1126: }
1127: }
1128:
1129: void memory_to_memory ()
1130: {
1131: inst0 = 0xc0000000 + evaluate (tokenix+1);
1132: inst1 = evaluate (tokenix+3);
1133: inst2 = evaluate (tokenix+5);
1134: }
1135:
1136: void error_line()
1137: {
1138: if (errfp != listfp && errfp && err_listed == 0) {
1139: fprintf (errfp, "%3d: %s", lineno, inbuf);
1140: err_listed = 1;
1141: }
1142: }
1143:
1144: char * makefn (base, sub)
1145: char *base;
1146: char *sub;
1147: {
1148: char *fn;
1149: size_t len = strlen (base) + strlen (sub) + 2;
1150:
1151: fn = malloc (len);
1152: strlcpy (fn, base, len);
1153: base = strrchr(fn, '.');
1154: if (base)
1155: *base = 0;
1156: strlcat (fn, ".", len);
1157: strlcat (fn, sub, len);
1158: return (fn);
1159: }
1160:
1161: void usage()
1162: {
1163: fprintf (stderr, "usage: scc sourcfile [options]\n");
1164: exit(1);
1165: }
CVSweb