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