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