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