1 /* $OpenBSD: ncr53cxxx.c,v 1.6 2004/03/12 00:04:57 miod Exp $ */
2 /* $NetBSD: ncr53cxxx.c,v 1.10 2002/04/21 22:40:10 bouyer 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", { -1, 0x22, -1, -1, -1}},
193 {"lcrc", { -1, 0x23, -1, -1, -1}},
194 {"dbc0", {0x24, 0x24, 0x24, 0x24, 0x24}},
195 {"dbc1", {0x25, 0x25, 0x25, 0x25, 0x25}},
196 {"dbc2", {0x26, 0x26, 0x26, 0x26, 0x26}},
197 {"dcmd", {0x27, 0x27, 0x27, 0x27, 0x27}},
198 {"dnad0", {0x28, 0x28, 0x28, 0x28, 0x28}},
199 {"dnad1", {0x29, 0x29, 0x29, 0x29, 0x29}},
200 {"dnad2", {0x2a, 0x2a, 0x2a, 0x2a, 0x2a}},
201 {"dnad3", {0x2b, 0x2b, 0x2b, 0x2b, 0x2b}},
202 {"dsp0", {0x2c, 0x2c, 0x2c, 0x2c, 0x2c}},
203 {"dsp1", {0x2d, 0x2d, 0x2d, 0x2d, 0x2d}},
204 {"dsp2", {0x2e, 0x2e, 0x2e, 0x2e, 0x2e}},
205 {"dsp3", {0x2f, 0x2f, 0x2f, 0x2f, 0x2f}},
206 {"dsps0", {0x30, 0x30, 0x30, 0x30, 0x30}},
207 {"dsps1", {0x31, 0x31, 0x31, 0x31, 0x31}},
208 {"dsps2", {0x32, 0x32, 0x32, 0x32, 0x32}},
209 {"dsps3", {0x33, 0x33, 0x33, 0x33, 0x33}},
210 {"scratch0", { -1, 0x34, -1, -1, -1}},
211 {"scratch1", { -1, 0x35, -1, -1, -1}},
212 {"scratch2", { -1, 0x36, -1, -1, -1}},
213 {"scratch3", { -1, 0x37, -1, -1, -1}},
214 {"scratcha0", { -1, -1, 0x34, 0x34, 0x34}},
215 {"scratcha1", { -1, -1, 0x35, 0x35, 0x35}},
216 {"scratcha2", { -1, -1, 0x36, 0x36, 0x36}},
217 {"scratcha3", { -1, -1, 0x37, 0x37, 0x37}},
218 {"dmode", {0x34, 0x38, 0x38, 0x38, 0x38}},
219 {"dien", {0x39, 0x39, 0x39, 0x39, 0x39}},
220 {"dwt", {0x3a, 0x3a, 0x3a, -1, -1}},
221 {"sbr", { -1, -1, -1, 0x3a, 0x3a}},
222 {"dcntl", {0x3b, 0x3b, 0x3b, 0x3b, 0x3b}},
223 {"addr0", { -1, 0x3c, 0x3c, 0x3c, 0x3c}},
224 {"addr1", { -1, 0x3d, 0x3d, 0x3d, 0x3d}},
225 {"addr2", { -1, 0x3e, 0x3e, 0x3e, 0x3e}},
226 {"addr3", { -1, 0x3f, 0x3f, 0x3f, 0x3f}},
227 {"sien0", { -1, -1, 0x40, 0x40, 0x40}},
228 {"sien1", { -1, -1, 0x41, 0x41, 0x41}},
229 {"sist0", { -1, -1, 0x42, 0x42, 0x42}},
230 {"sist1", { -1, -1, 0x43, 0x43, 0x43}},
231 {"slpar", { -1, -1, 0x44, 0x44, 0x44}},
232 {"swide", { -1, -1, 0x45, -1, 0x45}},
233 {"macntl", { -1, -1, 0x46, 0x46, 0x46}},
234 {"gpcntl", { -1, -1, 0x47, 0x47, 0x47}},
235 {"stime0", { -1, -1, 0x48, 0x48, 0x48}},
236 {"stime1", { -1, -1, 0x49, 0x49, 0x49}},
237 {"respid0", { -1, -1, 0x4a, 0x4a, 0x4a}},
238 {"respid1", { -1, -1, 0x4b, -1, 0x4b}},
239 {"stest0", { -1, -1, 0x4c, 0x4c, 0x4c}},
240 {"stest1", { -1, -1, 0x4d, 0x4d, 0x4d}},
241 {"stest2", { -1, -1, 0x4e, 0x4e, 0x4e}},
242 {"stest3", { -1, -1, 0x4f, 0x4f, 0x4f}},
243 {"sidl0", { -1, -1, 0x50, 0x50, 0x50}},
244 {"sidl1", { -1, -1, 0x51, -1, 0x51}},
245 {"sodl0", { -1, -1, 0x54, 0x54, 0x54}},
246 {"sodl1", { -1, -1, 0x55, -1, 0x55}},
247 {"sbdl0", { -1, -1, 0x58, 0x58, 0x58}},
248 {"sbdl1", { -1, -1, 0x59, -1, 0x59}},
249 {"scratchb0", { -1, -1, 0x5c, 0x5c, 0x5c}},
250 {"scratchb1", { -1, -1, 0x5d, 0x5d, 0x5d}},
251 {"scratchb2", { -1, -1, 0x5e, 0x5e, 0x5e}},
252 {"scratchb3", { -1, -1, 0x5f, 0x5f, 0x5f}},
253 {"scratchc0", { -1, -1, -1, -1, 0x60}},
254 {"scratchc1", { -1, -1, -1, -1, 0x61}},
255 {"scratchc2", { -1, -1, -1, -1, 0x62}},
256 {"scratchc3", { -1, -1, -1, -1, 0x63}},
257 {"scratchd0", { -1, -1, -1, -1, 0x64}},
258 {"scratchd1", { -1, -1, -1, -1, 0x65}},
259 {"scratchd2", { -1, -1, -1, -1, 0x66}},
260 {"scratchd3", { -1, -1, -1, -1, 0x67}},
261 {"scratche0", { -1, -1, -1, -1, 0x68}},
262 {"scratche1", { -1, -1, -1, -1, 0x69}},
263 {"scratche2", { -1, -1, -1, -1, 0x6a}},
264 {"scratche3", { -1, -1, -1, -1, 0x6b}},
265 {"scratchf0", { -1, -1, -1, -1, 0x6c}},
266 {"scratchf1", { -1, -1, -1, -1, 0x6d}},
267 {"scratchf2", { -1, -1, -1, -1, 0x6e}},
268 {"scratchf3", { -1, -1, -1, -1, 0x6f}},
269 {"scratchg0", { -1, -1, -1, -1, 0x70}},
270 {"scratchg1", { -1, -1, -1, -1, 0x71}},
271 {"scratchg2", { -1, -1, -1, -1, 0x72}},
272 {"scratchg3", { -1, -1, -1, -1, 0x73}},
273 {"scratchh0", { -1, -1, -1, -1, 0x74}},
274 {"scratchh1", { -1, -1, -1, -1, 0x75}},
275 {"scratchh2", { -1, -1, -1, -1, 0x7e}},
276 {"scratchh3", { -1, -1, -1, -1, 0x77}},
277 {"scratchi0", { -1, -1, -1, -1, 0x78}},
278 {"scratchi1", { -1, -1, -1, -1, 0x79}},
279 {"scratchi2", { -1, -1, -1, -1, 0x7a}},
280 {"scratchi3", { -1, -1, -1, -1, 0x7b}},
281 {"scratchj0", { -1, -1, -1, -1, 0x7c}},
282 {"scratchj1", { -1, -1, -1, -1, 0x7d}},
283 {"scratchj2", { -1, -1, -1, -1, 0x7e}},
284 {"scratchj3", { -1, -1, -1, -1, 0x7f}},
285 };
286
287 int lineno;
288 int err_listed;
289 int arch;
290 int partial_flag;
291
292 char inbuf[128];
293
294 char *sourcefile;
295 char *outputfile;
296 char *listfile;
297 char *errorfile;
298
299 FILE *infp;
300 FILE *outfp;
301 FILE *listfp;
302 FILE *errfp;
303
304 void setarch(char *);
305 void parse (void);
306 void process (void);
307 void emit_symbols (void);
308 void list_symbols (void);
309 void errout (char *);
310 void define_symbol (char *, u_int32_t, short, short);
311 void patch_label (void);
312 void close_script (void);
313 void new_script (char *);
314 void store_inst (void);
315 int expression (int *);
316 int evaluate (int);
317 int number (char *);
318 int lookup (char *);
319 int reserved (char *, int);
320 int CheckPhase (int);
321 int CheckRegister (int);
322 void transfer (int, int);
323 void select_reselect (int);
324 void set_clear (u_int32_t);
325 void block_move (void);
326 void register_write (void);
327 void memory_to_memory (void);
328 void loadstore (int);
329 void error_line(void);
330 char *makefn(char *, char *);
331 void usage(void);
332
333 int
main(int argc,char * argv[])334 main (int argc, char *argv[])
335 {
336 int i;
337 struct patchlist *p;
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
418 fprintf(outfp, "/*\t$OpenBSD: ncr53cxxx.c,v 1.6 2004/03/12 00:04:57 miod Exp $\t*/\n");
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 fprintf (outfp, "u_int32_t LABELPATCHES[] = {\n");
461 p = patches;
462 while (p) {
463 fprintf (outfp, "\t0x%08x,\n", p->offset / 4);
464 p = p->next;
465 }
466 fprintf (outfp, "};\n\n");
467 }
468 list_symbols ();
469 exit(0);
470 }
471
setarch(char * val)472 void setarch(char *val)
473 {
474 switch (atoi(val)) {
475 case 700:
476 arch = ARCH700;
477 break;
478 case 710:
479 arch = ARCH710;
480 break;
481 case 720:
482 arch = ARCH720;
483 break;
484 case 810:
485 arch = ARCH810;
486 break;
487 case 825:
488 arch = ARCH825;
489 break;
490 default:
491 arch = 0;
492 }
493 }
494
emit_symbols()495 void emit_symbols ()
496 {
497 int i;
498 struct patchlist *p;
499
500 if (nsymbols == 0 || outfp == NULL)
501 return;
502
503 for (i = 0; i < nsymbols; ++i) {
504 char *code;
505 if ((symbols[i].flags & F_DEFINED) == 0 &&
506 symbols[i].type != S_EXTERNAL) {
507 fprintf(stderr, "warning: symbol %s undefined\n",
508 symbols[i].name);
509 }
510 if (symbols[i].type == S_ABSOLUTE)
511 code = "A_";
512 else if (symbols[i].type == S_RELATIVE)
513 code = "R_";
514 else if (symbols[i].type == S_EXTERNAL)
515 code = "E_";
516 else if (symbols[i].flags & F_ENTRY)
517 code = "Ent_";
518 else
519 continue;
520 fprintf (outfp, "#define\t%s%s\t0x%08x\n", code, symbols[i].name,
521 symbols[i].value);
522 if (symbols[i].flags & F_ENTRY || symbols[i].patchlist == NULL)
523 continue;
524 fprintf (outfp, "u_int32_t %s%s_Used[] = {\n", code, symbols[i].name);
525 #if 1
526 p = symbols[i].patchlist;
527 while (p) {
528 fprintf (outfp, "\t0x%08x,\n", p->offset / 4);
529 p = p->next;
530 }
531 #endif
532 fprintf (outfp, "};\n\n");
533 }
534 /* patches ? */
535 }
536
list_symbols()537 void list_symbols ()
538 {
539 int i;
540
541 if (nsymbols == 0 || listfp == NULL)
542 return;
543 fprintf (listfp, "\n\nValue Type Symbol\n");
544 for (i = 0; i < nsymbols; ++i) {
545 fprintf (listfp, "%08x: %-8s %s\n", symbols[i].value,
546 stypes[symbols[i].type], symbols[i].name);
547 }
548 }
549
errout(char * text)550 void errout (char *text)
551 {
552 error_line();
553 fprintf (errfp, "*** %s ***\n", text);
554 }
555
parse()556 void parse ()
557 {
558 char *p = inbuf;
559 char c;
560 char string[64];
561 char *s;
562 size_t len;
563
564 ntokens = tokenix = 0;
565 while (1) {
566 while ((c = *p++) && c != '\n' && (c <= ' ' || c == '\t'))
567 ;
568 if (c == '\n' || c == 0 || c == ';')
569 break;
570 if (ntokens >= MAXTOKENS) {
571 errout ("Token table full");
572 break;
573 }
574 if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
575 (c >= 'A' && c <= 'Z') || c == '$' || c == '_') {
576 s = string;
577 *s++ = c;
578 while (((c = *p) >= '0' && c <= '9') ||
579 (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
580 c == '_' || c == '$') {
581 *s++ = *p++;
582 }
583 *s = 0;
584 len = strlen (string) + 1;
585 tokens[ntokens].name = malloc (len);
586 strlcpy (tokens[ntokens].name, string, len);
587 tokens[ntokens].type = 0;
588 }
589 else {
590 tokens[ntokens].type = c;
591 }
592 ++ntokens;
593 }
594 return;
595 }
596
process()597 void process ()
598 {
599 int i;
600
601 if (tokens[tokenix].type) {
602 error_line();
603 fprintf (errfp, "Error: expected directive, found '%c'\n",
604 tokens[tokenix].type);
605 return;
606 }
607 for (i = 0; directives[i].name; ++i) {
608 if (strcmpi (directives[i].name, tokens[tokenix].name) == 0)
609 break;
610 }
611 if (directives[i].name == NULL) {
612 error_line();
613 fprintf (errfp, "Error: expected directive, found \"%s\"\n",
614 tokens[tokenix].name);
615 return;
616 }
617 if (directives[i].func == NULL) {
618 error_line();
619 fprintf (errfp, "No function for directive \"%s\"\n", tokens[tokenix].name);
620 } else {
621 #if 0
622 fprintf (listfp, "Processing directive \"%s\"\n", directives[i].name);
623 #endif
624 ++tokenix;
625 (*directives[i].func) ();
626 }
627 }
628
define_symbol(char * name,u_int32_t value,short type,short flags)629 void define_symbol (char *name, u_int32_t value, short type, short flags)
630 {
631 int i;
632 struct patchlist *p;
633 size_t len;
634
635 for (i = 0; i < nsymbols; ++i) {
636 if (symbols[i].type == type && strcmp (symbols[i].name, name) == 0) {
637 if (symbols[i].flags & F_DEFINED) {
638 error_line();
639 fprintf (errfp, "*** Symbol \"%s\" multiply defined\n",
640 name);
641 } else {
642 symbols[i].flags |= flags;
643 symbols[i].value = value;
644 p = symbols[i].patchlist;
645 while (p) {
646 if (p->offset > dsps)
647 errout ("Whoops\007");
648 else
649 script[p->offset / 4] += dsps;
650 p = p->next;
651 }
652 }
653 return;
654 }
655 }
656 if (nsymbols >= MAXSYMBOLS) {
657 errout ("Symbol table full");
658 return;
659 }
660 symbols[nsymbols].type = type;
661 symbols[nsymbols].flags = flags;
662 symbols[nsymbols].value = value;
663 symbols[nsymbols].patchlist = NULL;
664 len = strlen (name) + 1;
665 symbols[nsymbols].name = malloc (len);
666 strlcpy (symbols[nsymbols].name, name, len);
667 ++nsymbols;
668 }
669
patch_label(void)670 void patch_label (void)
671 {
672 struct patchlist *p, **h;
673
674 h = &patches;
675 while(*h)
676 h = &(*h)->next;
677 p = (struct patchlist *) malloc (sizeof (struct patchlist));
678 *h = p;
679 p->next = NULL;
680 p->offset = dsps + 4;
681 npatches++;
682 }
683
close_script()684 void close_script ()
685 {
686 int i;
687
688 if (dsps == 0)
689 return;
690 if (outfp) {
691 fprintf (outfp, "const u_int32_t %s[] = {\n", script_name);
692 for (i = 0; i < dsps / 4; i += 2) {
693 fprintf (outfp, "\t0x%08x, 0x%08x", script[i],
694 script[i + 1]);
695 /* check for memory move instruction */
696 if ((script[i] & 0xe0000000) == 0xc0000000)
697 fprintf (outfp, ", 0x%08x,", script[i + 2]);
698 else
699 if ((i + 2) <= dsps / 4) fprintf (outfp, ",\t\t");
700 fprintf (outfp, "\t/* %03x - %3d */\n", i * 4, i * 4);
701 if ((script[i] & 0xe0000000) == 0xc0000000)
702 ++i;
703 }
704 fprintf (outfp, "};\n\n");
705 }
706 dsps = 0;
707 }
708
new_script(char * name)709 void new_script (char *name)
710 {
711 size_t len = strlen (name) + 1;
712
713 close_script ();
714 script_name = malloc (len);
715 strlcpy (script_name, name, len);
716 }
717
reserved(char * string,int t)718 int reserved (char *string, int t)
719 {
720 if (tokens[t].type == 0 && strcmpi (tokens[t].name, string) == 0)
721 return (1);
722 return (0);
723 }
724
CheckPhase(int t)725 int CheckPhase (int t)
726 {
727 int i;
728
729 for (i = 0; i < 8; ++i) {
730 if (reserved (phases[i], t)) {
731 inst0 |= i << 24;
732 return (1);
733 }
734 }
735 return (0);
736 }
737
CheckRegister(int t)738 int CheckRegister (int t)
739 {
740 int i;
741
742 if (arch <= 0) {
743 errout("'ARCH' statement missing");
744 return -1;
745 }
746 for (i = 0; i < (sizeof(regs) / sizeof(regs[0])); i++) {
747 if (regs[i].addr[arch - 1] >= 0 && reserved(regs[i].name, t))
748 return regs[i].addr[arch-1];
749 }
750 return (-1);
751 }
752
expression(int * t)753 int expression (int *t)
754 {
755 int value;
756 int i = *t;
757
758 value = evaluate (i++);
759 while (i < ntokens) {
760 if (tokens[i].type == '+')
761 value += evaluate (i + 1);
762 else if (tokens[i].type == '-')
763 value -= evaluate (i + 1);
764 else
765 errout ("Unknown identifier");
766 i += 2;
767 }
768 *t = i;
769 return (value);
770 }
771
evaluate(t)772 int evaluate (t)
773 {
774 int value;
775 char *name;
776
777 if (tokens[t].type) {
778 errout ("Expected an identifier");
779 return (0);
780 }
781 name = tokens[t].name;
782 if (*name >= '0' && *name <= '9')
783 value = number (name);
784 else
785 value = lookup (name);
786 return (value);
787 }
788
number(char * s)789 int number (char *s)
790 {
791 int value;
792 int n;
793 int radix;
794
795 radix = 10;
796 if (*s == '0') {
797 ++s;
798 radix = 8;
799 switch (*s) {
800 case 'x':
801 case 'X':
802 radix = 16;
803 break;
804 case 'b':
805 case 'B':
806 radix = 2;
807 }
808 if (radix != 8)
809 ++s;
810 }
811 value = 0;
812 while (*s) {
813 n = *s++;
814 if (n >= '0' && n <= '9')
815 n -= '0';
816 else if (n >= 'a' && n <= 'f')
817 n -= 'a' - 10;
818 else if (n >= 'A' && n <= 'F')
819 n -= 'A' - 10;
820 else {
821 error_line();
822 fprintf (errfp, "*** Expected digit\n");
823 n = 0;
824 }
825 if (n >= radix)
826 errout ("Expected digit");
827 else
828 value = value * radix + n;
829 }
830 return (value);
831 }
832
lookup(char * name)833 int lookup (char *name)
834 {
835 int i;
836 struct patchlist *p;
837 size_t len;
838
839 for (i = 0; i < nsymbols; ++i) {
840 if (strcmp (name, symbols[i].name) == 0) {
841 if ((symbols[i].flags & F_DEFINED) == 0) {
842 p = (struct patchlist *) &symbols[i].patchlist;
843 while (p->next)
844 p = p->next;
845 p->next = (struct patchlist *) malloc (sizeof (struct patchlist));
846 p = p->next;
847 p->next = NULL;
848 p->offset = dsps + 4;
849 }
850 return ((int) symbols[i].value);
851 }
852 }
853 if (nsymbols >= MAXSYMBOLS) {
854 errout ("Symbol table full");
855 return (0);
856 }
857 symbols[nsymbols].type = S_LABEL; /* assume forward reference */
858 symbols[nsymbols].flags = 0;
859 symbols[nsymbols].value = 0;
860 p = (struct patchlist *) malloc (sizeof (struct patchlist));
861 symbols[nsymbols].patchlist = p;
862 p->next = NULL;
863 p->offset = dsps + 4;
864 len = strlen (name) + 1;
865 symbols[nsymbols].name = malloc (len);
866 strlcpy (symbols[nsymbols].name, name, len);
867 ++nsymbols;
868 return (0);
869 }
870
f_arch(void)871 void f_arch (void)
872 {
873 int i, archsave;
874
875 i = tokenix;
876
877 archsave = arch;
878 setarch(tokens[i].name);
879 if( arch == 0) {
880 errout("Unrecognized ARCH");
881 arch = archsave;
882 }
883 }
884
f_proc(void)885 void f_proc (void)
886 {
887 if (tokens[tokenix].type != 0 || tokens[tokenix + 1].type != ':')
888 errout ("Invalid PROC statement");
889 else
890 new_script (tokens[tokenix].name);
891 }
892
f_pass(void)893 void f_pass (void)
894 {
895 errout ("PASS option not implemented");
896 }
897
898 /*
899 * f_list: process list of symbols for the ENTRY and EXTERNAL directive
900 */
901
f_list(void)902 void f_list (void)
903 {
904 int i;
905 short type;
906 short flags;
907
908 type = strcmpi (tokens[tokenix-1].name, "ENTRY") ? S_EXTERNAL : S_LABEL;
909 flags = type == S_LABEL ? F_ENTRY : 0;
910 for (i = tokenix; i < ntokens; ++i) {
911 if (tokens[i].type != 0) {
912 errout ("Expected an identifier");
913 return;
914 }
915 define_symbol (tokens[i].name, 0, type, flags);
916 if (i + 1 < ntokens) {
917 if (tokens[++i].type == ',')
918 continue;
919 errout ("Expected a separator");
920 return;
921 }
922 }
923 }
924
925 /*
926 * f_define: process list of definitions for ABSOLUTE and RELATIVE directive
927 */
928
f_define(void)929 void f_define (void)
930 {
931 int i;
932 char *name;
933 u_int32_t value;
934 int type;
935
936 type = strcmpi (tokens[tokenix-1].name, "ABSOLUTE") ? S_RELATIVE : S_ABSOLUTE;
937 i = tokenix;
938 while (i < ntokens) {
939 if (tokens[i].type) {
940 errout ("Expected an identifier");
941 return;
942 }
943 if (tokens[i + 1].type != '=') {
944 errout ("Expected a separator");
945 return;
946 }
947 name = tokens[i].name;
948 i += 2;
949 value = expression (&i);
950 define_symbol (name, value, type, F_DEFINED);
951 }
952 }
953
store_inst()954 void store_inst ()
955 {
956 int i = dsps / 4;
957 int l = 8;
958
959 if ((inst0 & 0xe0000000) == 0xc0000000)
960 l = 12; /* Memory to memory move is 12 bytes */
961 if ((dsps + l) / 4 > MAXINST) {
962 errout ("Instruction table overflow");
963 return;
964 }
965 script[i++] = inst0;
966 script[i++] = inst1;
967 if (l == 12)
968 script[i++] = inst2;
969 if (listfp) {
970 fprintf (listfp, "\t%04x: %08x %08x", dsps, inst0, inst1);
971 if (l == 12)
972 fprintf (listfp, " %08x", inst2);
973 fprintf (listfp, "\n");
974 }
975 dsps += l;
976 inst0 = inst1 = inst2 = 0;
977 ++ninsts;
978 }
979
f_move(void)980 void f_move (void)
981 {
982 if (reserved ("memory", tokenix))
983 memory_to_memory ();
984 else if (reserved ("from", tokenix) || tokens[tokenix+1].type == ',')
985 block_move ();
986 else
987 register_write ();
988 store_inst ();
989 }
990
f_jump(void)991 void f_jump (void)
992 {
993 transfer (0x80000000, 0);
994 }
995
f_call(void)996 void f_call (void)
997 {
998 transfer (0x88000000, 0);
999 }
1000
f_return(void)1001 void f_return (void)
1002 {
1003 transfer (0x90000000, 1);
1004 }
1005
f_int(void)1006 void f_int (void)
1007 {
1008 transfer (0x98000000, 2);
1009 }
1010
f_intfly(void)1011 void f_intfly (void)
1012 {
1013 transfer (0x98100000, 2);
1014 }
1015
f_select(void)1016 void f_select (void)
1017 {
1018 int t = tokenix;
1019
1020 if (reserved ("atn", t)) {
1021 inst0 = 0x01000000;
1022 ++t;
1023 }
1024 select_reselect (t);
1025 }
1026
f_reselect(void)1027 void f_reselect (void)
1028 {
1029 select_reselect (tokenix);
1030 }
1031
f_wait(void)1032 void f_wait (void)
1033 {
1034 int i = tokenix;
1035
1036 inst1 = 0;
1037 if (reserved ("disconnect", i)) {
1038 inst0 = 0x48000000;
1039 }
1040 else {
1041 if (reserved ("reselect", i))
1042 inst0 = 0x50000000;
1043 else if (reserved ("select", i))
1044 inst0 = 0x50000000;
1045 else
1046 errout ("Expected SELECT or RESELECT");
1047 ++i;
1048 if (reserved ("rel", i)) {
1049 #if 0 /* XXX driver will fix relative dsps to absolute */
1050 if (arch < ARCH710) {
1051 errout ("Wrong arch for relative dsps");
1052 return;
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
f_disconnect(void)1067 void f_disconnect (void)
1068 {
1069 inst0 = 0x48000000;
1070 store_inst ();
1071 }
1072
f_set(void)1073 void f_set (void)
1074 {
1075 set_clear (0x58000000);
1076 }
1077
f_clear(void)1078 void f_clear (void)
1079 {
1080 set_clear (0x60000000);
1081 }
1082
f_load(void)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
f_store(void)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
f_nop(void)1109 void f_nop (void)
1110 {
1111 inst0 = 0x80000000;
1112 inst1 = 0x00000000;
1113 store_inst ();
1114 }
1115
loadstore(int i)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
transfer(int word0,int type)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 /* XXX driver will fix relative dsps to absolute */
1163 if (arch < ARCH710) {
1164 errout ("Wrong arch for relative dsps");
1165 return;
1166 }
1167 #endif
1168 inst1 = evaluate (i + 2) - dsps - 8;
1169 i += 4;
1170 inst0 |= 0x00800000;
1171 }
1172 else if (type != 1) {
1173 inst1 = evaluate (i);
1174 ++i;
1175 if (type == 0)
1176 patch_label();
1177 }
1178 if (i >= ntokens) {
1179 inst0 |= 0x00080000;
1180 store_inst ();
1181 return;
1182 }
1183 if (tokens[i].type != ',')
1184 errout ("Expected a separator, ',' assumed");
1185 else
1186 ++i;
1187 if (reserved("when", i))
1188 inst0 |= 0x00010000;
1189 else if (reserved ("if", i) == 0) {
1190 errout ("Expected a reserved word");
1191 store_inst ();
1192 return;
1193 }
1194 i++;
1195 if (reserved("false", i)) {
1196 store_inst ();
1197 return;
1198 }
1199 if (reserved ("not", i))
1200 ++i;
1201 else
1202 inst0 |= 0x00080000;
1203 if (reserved ("atn", i)) {
1204 inst0 |= 0x00020000;
1205 ++i;
1206 } else if (CheckPhase (i)) {
1207 inst0 |= 0x00020000;
1208 ++i;
1209 }
1210 if (i < ntokens && tokens[i].type != ',') {
1211 if (inst0 & 0x00020000) {
1212 if (inst0 & 0x00080000 && reserved ("and", i)) {
1213 ++i;
1214 }
1215 else if ((inst0 & 0x00080000) == 0 && reserved ("or", i)) {
1216 ++i;
1217 }
1218 else
1219 errout ("Expected a reserved word");
1220 }
1221 inst0 |= 0x00040000 + (evaluate (i++) & 0xff);
1222 }
1223 if (i < ntokens) {
1224 if (tokens[i].type == ',')
1225 ++i;
1226 else
1227 errout ("Expected a separator, ',' assumed");
1228 if (reserved ("and", i) && reserved ("mask", i + 1))
1229 inst0 |= ((evaluate (i + 2) & 0xff) << 8);
1230 else
1231 errout ("Expected , AND MASK");
1232 }
1233 store_inst ();
1234 }
1235
select_reselect(int t)1236 void select_reselect (int t)
1237 {
1238 inst0 |= 0x40000000; /* ATN may be set from SELECT */
1239 if (reserved ("from", t)) {
1240 if (arch < ARCH710) {
1241 errout ("Wrong arch for table indirect");
1242 return;
1243 }
1244 ++t;
1245 inst0 |= 0x02000000 | evaluate (t++);
1246 }
1247 else
1248 inst0 |= (evaluate (t++) & 0xff) << 16;
1249 if (tokens[t++].type == ',') {
1250 if (reserved ("rel", t)) {
1251 #if 0 /* XXX driver will fix relative dsps to absolute */
1252 if (arch < ARCH710) {
1253 errout ("Wrong arch for relative dsps");
1254 return;
1255 }
1256 #endif
1257 inst0 |= 0x04000000;
1258 inst1 = evaluate (t + 2) - dsps - 8;
1259 }
1260 else {
1261 inst1 = evaluate (t);
1262 patch_label();
1263 }
1264 }
1265 else
1266 errout ("Expected separator");
1267 store_inst ();
1268 }
1269
set_clear(u_int32_t code)1270 void set_clear (u_int32_t code)
1271 {
1272 int i = tokenix;
1273 short need_and = 0;
1274
1275 inst0 = code;
1276 while (i < ntokens) {
1277 if (need_and) {
1278 if (reserved ("and", i))
1279 ++i;
1280 else
1281 errout ("Expected AND");
1282 }
1283 if (reserved ("atn", i)) {
1284 inst0 |= 0x0008;
1285 ++i;
1286 }
1287 else if (reserved ("ack", i)) {
1288 inst0 |= 0x0040;
1289 ++i;
1290 }
1291 else if (reserved ("target", i)) {
1292 inst0 |= 0x0200;
1293 ++i;
1294 }
1295 else if (reserved ("carry", i)) {
1296 inst0 |= 0x0400;
1297 ++i;
1298 }
1299 else
1300 errout ("Expected ATN, ACK, TARGET or CARRY");
1301 need_and = 1;
1302 }
1303 store_inst ();
1304 }
1305
block_move()1306 void block_move ()
1307 {
1308 if (reserved ("from", tokenix)) {
1309 if (arch < ARCH710) {
1310 errout ("Wrong arch for table indirect");
1311 return;
1312 }
1313 inst1 = evaluate (tokenix+1);
1314 inst0 |= 0x10000000 | inst1; /*** ??? to match Zeus script */
1315 tokenix += 2;
1316 }
1317 else {
1318 inst0 |= evaluate (tokenix++); /* count */
1319 tokenix++; /* skip ',' */
1320 if (reserved ("ptr", tokenix)) {
1321 ++ tokenix;
1322 inst0 |= 0x20000000;
1323 }
1324 inst1 = evaluate (tokenix++); /* address */
1325 }
1326 if (tokens[tokenix].type != ',')
1327 errout ("Expected separator");
1328 if (reserved ("when", tokenix + 1)) {
1329 inst0 |= 0x08000000;
1330 CheckPhase (tokenix + 2);
1331 }
1332 else if (reserved ("with", tokenix + 1)) {
1333 CheckPhase (tokenix + 2);
1334 }
1335 else
1336 errout ("Expected WITH or WHEN");
1337 }
1338
register_write()1339 void register_write ()
1340 {
1341 /*
1342 * MOVE reg/data8 TO reg register write
1343 * MOVE reg <op> data8 TO reg register write
1344 * MOVE reg + data8 TO reg WITH CARRY register write
1345 */
1346 int op;
1347 int reg;
1348 int data;
1349
1350 if (reserved ("to", tokenix+1))
1351 op = 0;
1352 else if (reserved ("shl", tokenix+1))
1353 op = 1;
1354 else if (reserved ("shr", tokenix+1))
1355 op = 5;
1356 else if (tokens[tokenix+1].type == '|')
1357 op = 2;
1358 else if (reserved ("xor", tokenix+1))
1359 op = 3;
1360 else if (tokens[tokenix+1].type == '&')
1361 op = 4;
1362 else if (tokens[tokenix+1].type == '+')
1363 op = 6;
1364 else if (tokens[tokenix+1].type == '-')
1365 op = 8;
1366 else
1367 errout ("Unknown register operator");
1368 switch (op) {
1369 case 2:
1370 case 3:
1371 case 4:
1372 case 6:
1373 case 8:
1374 if (reserved ("to", tokenix+3) == 0)
1375 errout ("Register command expected TO");
1376 default:
1377 }
1378 reg = CheckRegister (tokenix);
1379 if (reg < 0) { /* Not register, must be data */
1380 data = evaluate (tokenix);
1381 if (op)
1382 errout ("Register operator not move");
1383 reg = CheckRegister (tokenix+2);
1384 if (reg < 0)
1385 errout ("Expected register");
1386 inst0 = 0x78000000 | (data << 8) | reg << 16;
1387 #if 0
1388 fprintf (listfp, "Move data to register: %02x %d\n", data, reg);
1389 #endif
1390 } else if (op) {
1391 switch (op) {
1392 case 2:
1393 case 3:
1394 case 4:
1395 case 6:
1396 case 8:
1397 inst0 = 0;
1398 /* A register read/write operator */
1399 if (reserved("sfbr", tokenix+2)) {
1400 if (arch < ARCH825)
1401 errout("wrong arch for add with SFBR");
1402 if (op == 8)
1403 errout("can't substract SFBR");
1404 inst0 |= 0x00800000;
1405 data = 0;
1406 } else
1407 data = evaluate (tokenix+2);
1408 if (tokenix+5 < ntokens) {
1409 if (!reserved("with", tokenix+5) ||
1410 !reserved("carry", tokenix+6)) {
1411 errout("Expected 'WITH CARRY'");
1412 } else if (op != 6) {
1413 errout("'WITH CARRY' only valide "
1414 "with '+'");
1415 }
1416 op = 7;
1417 }
1418 if (op == 8) {
1419 data = -data;
1420 op = 6;
1421 }
1422 inst0 |= (data & 0xff) << 8;
1423 data = CheckRegister (tokenix+4);
1424 break;
1425 default:
1426 data = CheckRegister (tokenix+2);
1427 break;
1428 }
1429 if (data < 0)
1430 errout ("Expected register");
1431 if (reg != data && reg != 8 && data != 8)
1432 errout ("One register MUST be SBFR");
1433 if (reg == data) { /* A register read/modify/write */
1434 #if 0
1435 fprintf (listfp, "Read/modify register: %02x %d %d\n", inst0 >> 8, op, reg);
1436 #endif
1437 inst0 |= 0x78000000 | (op << 24) | (reg << 16);
1438 }
1439 else { /* A move to/from SFBR */
1440 if (reg == 8) { /* MOVE SFBR <> TO reg */
1441 #if 0
1442 fprintf (listfp, "Move SFBR to register: %02x %d %d\n", inst0 >> 8, op, data);
1443 #endif
1444 inst0 |= 0x68000000 | (op << 24) | (data << 16);
1445 }
1446 else {
1447 #if 0
1448 fprintf (listfp, "Move register to SFBR: %02x %d %d\n", inst0 >> 8, op, reg);
1449 #endif
1450 inst0 |= 0x70000000 | (op << 24) | (reg << 16);
1451 }
1452 }
1453 } else { /* register to register */
1454 data = CheckRegister (tokenix+2);
1455 if (data < 0)
1456 errout ("Expected register");
1457 if (reg == 8) /* move SFBR to reg */
1458 inst0 = 0x6a000000 | (data << 16);
1459 else if (data == 8) /* move reg to SFBR */
1460 inst0 = 0x72000000 | (reg << 16);
1461 else
1462 errout ("One register must be SFBR");
1463 }
1464 }
1465
memory_to_memory()1466 void memory_to_memory ()
1467 {
1468 inst0 = 0xc0000000 + evaluate (tokenix+1);
1469 inst1 = evaluate (tokenix+3);
1470 /*
1471 * need to hack dsps, otherwise patch offset will be wrong for
1472 * second pointer
1473 */
1474 dsps += 4;
1475 inst2 = evaluate (tokenix+5);
1476 dsps -= 4;
1477 }
1478
error_line()1479 void error_line()
1480 {
1481 if (errfp != listfp && errfp && err_listed == 0) {
1482 fprintf (errfp, "%3d: %s", lineno, inbuf);
1483 err_listed = 1;
1484 }
1485 }
1486
makefn(base,sub)1487 char * makefn (base, sub)
1488 char *base;
1489 char *sub;
1490 {
1491 char *fn;
1492 size_t len = strlen (base) + strlen (sub) + 2;
1493
1494 fn = malloc (len);
1495 strlcpy (fn, base, len);
1496 base = strrchr(fn, '.');
1497 if (base)
1498 *base = 0;
1499 strlcat (fn, ".", len);
1500 strlcat (fn, sub, len);
1501 return (fn);
1502 }
1503
usage()1504 void usage()
1505 {
1506 fprintf (stderr, "usage: scc sourcfile [options]\n");
1507 exit(1);
1508 }
1509