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