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