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