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