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