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