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