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