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