xref: /onnv-gate/usr/src/uts/common/io/audio/drv/audioemu10k/dsp/asm10k.c (revision 13093:48f2dbca79a2)
110913Sgdamore@opensolaris.org /*
210913Sgdamore@opensolaris.org  * CDDL HEADER START
310913Sgdamore@opensolaris.org  *
410913Sgdamore@opensolaris.org  * The contents of this file are subject to the terms of the
510913Sgdamore@opensolaris.org  * Common Development and Distribution License (the "License").
610913Sgdamore@opensolaris.org  * You may not use this file except in compliance with the License.
710913Sgdamore@opensolaris.org  *
810913Sgdamore@opensolaris.org  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910913Sgdamore@opensolaris.org  * or http://www.opensolaris.org/os/licensing.
1010913Sgdamore@opensolaris.org  * See the License for the specific language governing permissions
1110913Sgdamore@opensolaris.org  * and limitations under the License.
1210913Sgdamore@opensolaris.org  *
1310913Sgdamore@opensolaris.org  * When distributing Covered Code, include this CDDL HEADER in each
1410913Sgdamore@opensolaris.org  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510913Sgdamore@opensolaris.org  * If applicable, add the following below this CDDL HEADER, with the
1610913Sgdamore@opensolaris.org  * fields enclosed by brackets "[]" replaced with your own identifying
1710913Sgdamore@opensolaris.org  * information: Portions Copyright [yyyy] [name of copyright owner]
1810913Sgdamore@opensolaris.org  *
1910913Sgdamore@opensolaris.org  * CDDL HEADER END
2010913Sgdamore@opensolaris.org  */
2110913Sgdamore@opensolaris.org 
2210913Sgdamore@opensolaris.org /*
23*13093SRoger.Faulkner@Oracle.COM  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2410913Sgdamore@opensolaris.org  */
2510913Sgdamore@opensolaris.org 
2610913Sgdamore@opensolaris.org /*
2710913Sgdamore@opensolaris.org  * Assembler for Emu10k1
2810913Sgdamore@opensolaris.org  */
2910913Sgdamore@opensolaris.org /*
3010913Sgdamore@opensolaris.org  * Copyright (C) 4Front Technologies 1996-2008.
3110913Sgdamore@opensolaris.org  */
3210913Sgdamore@opensolaris.org 
3310913Sgdamore@opensolaris.org #include <stdio.h>
3410913Sgdamore@opensolaris.org #include <stdlib.h>
3510913Sgdamore@opensolaris.org #include <unistd.h>
3610913Sgdamore@opensolaris.org #include <fcntl.h>
3710913Sgdamore@opensolaris.org #include <string.h>
3810913Sgdamore@opensolaris.org #include <stdarg.h>
3910913Sgdamore@opensolaris.org #include <ctype.h>
4010913Sgdamore@opensolaris.org #include <sys/param.h>
4110913Sgdamore@opensolaris.org 
4210913Sgdamore@opensolaris.org #define	MAX_GPR	256
4310913Sgdamore@opensolaris.org #define	MAX_GPR_PARMS	60
4410913Sgdamore@opensolaris.org #define	MAX_CONST_PARMS	128
4510913Sgdamore@opensolaris.org #define	GPR_NAME_SIZE 32
4610913Sgdamore@opensolaris.org 
4710913Sgdamore@opensolaris.org typedef struct {
4810913Sgdamore@opensolaris.org 	char name[GPR_NAME_SIZE];
4910913Sgdamore@opensolaris.org 	unsigned int num;
5010913Sgdamore@opensolaris.org 	int type;
5110913Sgdamore@opensolaris.org 	int def;
5210913Sgdamore@opensolaris.org } gpr_t;
5310913Sgdamore@opensolaris.org 
5410913Sgdamore@opensolaris.org typedef struct {
5510913Sgdamore@opensolaris.org 	unsigned int gpr;
5610913Sgdamore@opensolaris.org 	unsigned int value;
5710913Sgdamore@opensolaris.org } const_t;
5810913Sgdamore@opensolaris.org 
5910913Sgdamore@opensolaris.org typedef struct {
6010913Sgdamore@opensolaris.org 	unsigned int ngpr;
6110913Sgdamore@opensolaris.org 
6210913Sgdamore@opensolaris.org 	gpr_t gpr[MAX_GPR_PARMS];
6310913Sgdamore@opensolaris.org } gpr_info;
6410913Sgdamore@opensolaris.org 
6510913Sgdamore@opensolaris.org typedef struct {
6610913Sgdamore@opensolaris.org 	unsigned int nconst;
6710913Sgdamore@opensolaris.org 
6810913Sgdamore@opensolaris.org 	const_t consts[MAX_CONST_PARMS];
6910913Sgdamore@opensolaris.org } const_info;
7010913Sgdamore@opensolaris.org 
7110913Sgdamore@opensolaris.org typedef struct {
7210913Sgdamore@opensolaris.org 	unsigned int code[1024];
7310913Sgdamore@opensolaris.org 	gpr_info parms;
7410913Sgdamore@opensolaris.org 	const_info consts;
7510913Sgdamore@opensolaris.org 	int	ninit;
7610913Sgdamore@opensolaris.org 	struct {
7710913Sgdamore@opensolaris.org 		uint32_t	gpr;
7810913Sgdamore@opensolaris.org 		uint32_t	value;
7910913Sgdamore@opensolaris.org 		char		name[GPR_NAME_SIZE];
8010913Sgdamore@opensolaris.org 	} init[MAX_GPR];
8110913Sgdamore@opensolaris.org } emu10k1_file;
8210913Sgdamore@opensolaris.org 
8310913Sgdamore@opensolaris.org #define	MAX_NAME	64
8410913Sgdamore@opensolaris.org #define	MAX_SYMBOLS	1024
8510913Sgdamore@opensolaris.org 
8610913Sgdamore@opensolaris.org static int parms_only = 0;
8710913Sgdamore@opensolaris.org static int is_audigy = 0;
8810913Sgdamore@opensolaris.org static int verbose = 0;
8910913Sgdamore@opensolaris.org 
9010913Sgdamore@opensolaris.org static int gpr_base = 0x100;
9110913Sgdamore@opensolaris.org static int input_base = 0x10;
9210913Sgdamore@opensolaris.org static int output_base = 0x20;
9310913Sgdamore@opensolaris.org 
9410913Sgdamore@opensolaris.org static char *progname;
9510913Sgdamore@opensolaris.org 
9610913Sgdamore@opensolaris.org typedef struct {
9710913Sgdamore@opensolaris.org 	char name[MAX_NAME];
9810913Sgdamore@opensolaris.org 	int type;
9910913Sgdamore@opensolaris.org #define	SY_DUMMY	0
10010913Sgdamore@opensolaris.org #define	SY_GPR		1
10110913Sgdamore@opensolaris.org #define	SY_INPUT	2
10210913Sgdamore@opensolaris.org #define	SY_OUTPUT	3
10310913Sgdamore@opensolaris.org #define	SY_CONST	4
10410913Sgdamore@opensolaris.org #define	SY_FX		5
10510913Sgdamore@opensolaris.org #define	SY_ACCUM	6
10610913Sgdamore@opensolaris.org #define	SY_PARM		7
10710913Sgdamore@opensolaris.org 	int arg;
10810913Sgdamore@opensolaris.org } sym_t;
10910913Sgdamore@opensolaris.org 
11010913Sgdamore@opensolaris.org typedef struct {
11110913Sgdamore@opensolaris.org 	char *name;
11210913Sgdamore@opensolaris.org 	int opcode;
11310913Sgdamore@opensolaris.org } instruction_t;
11410913Sgdamore@opensolaris.org 
11510913Sgdamore@opensolaris.org static char remarks[2048] = "";
11610913Sgdamore@opensolaris.org static char *banner =
11710913Sgdamore@opensolaris.org 	"/*\n"
11810913Sgdamore@opensolaris.org 	" * Note: This file was automatically generated by %s\n"
11910913Sgdamore@opensolaris.org 	" * on %s.\n"
12010913Sgdamore@opensolaris.org 	" */\n";
12110913Sgdamore@opensolaris.org 
12210913Sgdamore@opensolaris.org /*
12310913Sgdamore@opensolaris.org  * Instructions.  Each instruction takes 4 arguments, R, A, X, and Y.
12410913Sgdamore@opensolaris.org  */
12510913Sgdamore@opensolaris.org static instruction_t instructions[] = {
12610913Sgdamore@opensolaris.org 	{ "MACS",	0x0},	/* R = A + (X * Y >> 31); saturation */
12710913Sgdamore@opensolaris.org 	{ "MACS1",	0x1},	/* R = A + (-X * Y >> 31); saturation */
12810913Sgdamore@opensolaris.org 	{ "MACW",	0x2},	/* R = A + (X * Y >> 31); wraparound */
12910913Sgdamore@opensolaris.org 	{ "MACW1",	0x3},	/* R = A + (-X * Y >> 31); wraparound */
13010913Sgdamore@opensolaris.org 	{ "MACINTS",	0x4},	/* R = A + (X * Y); saturation */
13110913Sgdamore@opensolaris.org 	{ "MACINTW",	0x5},	/* R = A + (X * Y); wraparound */
13210913Sgdamore@opensolaris.org 	{ "SUM",	0x6},	/* R = A + X + Y; saturation */
13310913Sgdamore@opensolaris.org 	{ "ACC3",	0x6},	/* R = A + X + Y; saturation */
13410913Sgdamore@opensolaris.org 	{ "MACMV",	0x7},	/* R = A, acc += X * Y >> 31 */
13510913Sgdamore@opensolaris.org 	{ "ANDXOR",	0x8},	/* R = (A & X) ^ Y */
13610913Sgdamore@opensolaris.org 	{ "TSTNEG",	0x9},	/* R = (A >= Y) ? X : ~X */
13710913Sgdamore@opensolaris.org 	{ "LIMIT",	0xa},	/* R = (A >= Y) ? X : Y */
13810913Sgdamore@opensolaris.org 	{ "LIMIT1",	0xb},	/* R = (A < Y) ? X : Y */
13910913Sgdamore@opensolaris.org 	{ "LOG",	0xc},	/* R = ... (log?) */
14010913Sgdamore@opensolaris.org 	{ "EXP",	0xd},	/* R = ... (exp?) */
14110913Sgdamore@opensolaris.org 	{ "INTERP",	0xe},	/* R = A + (X * (Y - A) >> 31) */
14210913Sgdamore@opensolaris.org 	{ "SKIP",	0xf},	/* R, CCR, CC_TEST, COUNT */
14310913Sgdamore@opensolaris.org 	{ NULL, 0}
14410913Sgdamore@opensolaris.org };
14510913Sgdamore@opensolaris.org 
14610913Sgdamore@opensolaris.org #define	CHECK_COUNT(tokens, cnt, mincnt, maxcnt)			\
14710913Sgdamore@opensolaris.org 	if (cnt < mincnt) {						\
14810913Sgdamore@opensolaris.org 		error("Too few parameters for '%s' (have %d, min %d)",	\
14910913Sgdamore@opensolaris.org 		    tokens[0], cnt - 1, mincnt - 1);			\
15010913Sgdamore@opensolaris.org 		return;							\
15110913Sgdamore@opensolaris.org 	}								\
15210913Sgdamore@opensolaris.org 	if (cnt > maxcnt) {						\
15310913Sgdamore@opensolaris.org 		error("Too many parameters for '%s' (have %d, max %d)",	\
15410913Sgdamore@opensolaris.org 		    tokens[0], cnt - 1, maxcnt - 1);			\
15510913Sgdamore@opensolaris.org 		return;							\
15610913Sgdamore@opensolaris.org 	}
15710913Sgdamore@opensolaris.org 
15810913Sgdamore@opensolaris.org static sym_t symtab[MAX_SYMBOLS];
15910913Sgdamore@opensolaris.org static int nsyms = 0;
16010913Sgdamore@opensolaris.org 
16110913Sgdamore@opensolaris.org static int lineno = 0, errors = 0;
16210913Sgdamore@opensolaris.org static emu10k1_file fle;
16310913Sgdamore@opensolaris.org static int pc;
16410913Sgdamore@opensolaris.org 
16510913Sgdamore@opensolaris.org static int ngpr = 0;
16610913Sgdamore@opensolaris.org static char *infile;
16710913Sgdamore@opensolaris.org 
16810913Sgdamore@opensolaris.org static int
getaline(FILE * input,char ** tokens)169*13093SRoger.Faulkner@Oracle.COM getaline(FILE *input, char **tokens)
17010913Sgdamore@opensolaris.org {
17110913Sgdamore@opensolaris.org 	char *s, *ls;
17210913Sgdamore@opensolaris.org 	static char *stmt = NULL, *lasts = NULL;
17310913Sgdamore@opensolaris.org 	static char line[4096];
17410913Sgdamore@opensolaris.org 	int cnt, tokcnt;
17510913Sgdamore@opensolaris.org 
17610913Sgdamore@opensolaris.org 	for (;;) {
17710913Sgdamore@opensolaris.org 
17810913Sgdamore@opensolaris.org 		if (stmt == NULL) {
17910913Sgdamore@opensolaris.org 			if (fgets(line, sizeof (line), input) == NULL)
18010913Sgdamore@opensolaris.org 				return (-1);
18110913Sgdamore@opensolaris.org 			lineno++;
18210913Sgdamore@opensolaris.org 
18310913Sgdamore@opensolaris.org 			/*
18410913Sgdamore@opensolaris.org 			 * Special handling for .' comments.  We use
18510913Sgdamore@opensolaris.org 			 * .' as a keyword to ensure that entire
18610913Sgdamore@opensolaris.org 			 * comment makes it through the C preprocessor
18710913Sgdamore@opensolaris.org 			 * unmolested.  We also need to make sure *we*
18810913Sgdamore@opensolaris.org 			 * don't molest it either.  The comment will
18910913Sgdamore@opensolaris.org 			 * be exported to any resulting header,
19010913Sgdamore@opensolaris.org 			 * allowing us to pass through copyright and
19110913Sgdamore@opensolaris.org 			 * other information from the source file to
19210913Sgdamore@opensolaris.org 			 * the resulting header.
19310913Sgdamore@opensolaris.org 			 */
19410913Sgdamore@opensolaris.org 			s = line;
19510913Sgdamore@opensolaris.org 			s += strspn(s, " \t");
19610913Sgdamore@opensolaris.org 			if ((strncmp(s, ".'", 2) == 0) &&
19710913Sgdamore@opensolaris.org 			    (strchr(" \t\n", s[2]) != NULL)) {
19810913Sgdamore@opensolaris.org 				/* chop off trailing new line */
19910913Sgdamore@opensolaris.org 				(void) strtok(line, "\n");
20010913Sgdamore@opensolaris.org 				tokens[0] = s;
20110913Sgdamore@opensolaris.org 				s += 2;
20210913Sgdamore@opensolaris.org 				s += strspn(s, " \t");
20310913Sgdamore@opensolaris.org 				if ((s[0] == '\'') &&
20410913Sgdamore@opensolaris.org 				    (s[strlen(s) - 1] == '\'')) {
20510913Sgdamore@opensolaris.org 					s[strlen(s) - 1] = 0;
20610913Sgdamore@opensolaris.org 					s++;
20710913Sgdamore@opensolaris.org 				}
20810913Sgdamore@opensolaris.org 				tokens[1] = s;
20910913Sgdamore@opensolaris.org 				tokens[0][2] = 0;
21010913Sgdamore@opensolaris.org 				tokens[2] = NULL;
21110913Sgdamore@opensolaris.org 				stmt = NULL;
21210913Sgdamore@opensolaris.org 				return (strlen(tokens[1]) ? 2 : 1);
21310913Sgdamore@opensolaris.org 			}
21410913Sgdamore@opensolaris.org 
21510913Sgdamore@opensolaris.org 			/* strip off any C++ style comments that CPP missed */
21610913Sgdamore@opensolaris.org 			if ((s = strstr(line, "//")) != NULL) {
21710913Sgdamore@opensolaris.org 				*s = NULL;
21810913Sgdamore@opensolaris.org 			}
21910913Sgdamore@opensolaris.org 			stmt = strtok_r(line, ";\n", &lasts);
22010913Sgdamore@opensolaris.org 		} else {
22110913Sgdamore@opensolaris.org 			stmt = strtok_r(NULL, ";\n", &lasts);
22210913Sgdamore@opensolaris.org 		}
22310913Sgdamore@opensolaris.org 
22410913Sgdamore@opensolaris.org 		if (stmt != NULL) {
22510913Sgdamore@opensolaris.org 			break;
22610913Sgdamore@opensolaris.org 		}
22710913Sgdamore@opensolaris.org 	}
22810913Sgdamore@opensolaris.org 
22910913Sgdamore@opensolaris.org 	/*
23010913Sgdamore@opensolaris.org 	 * Ok, we have a statement, lets tokenize it.  For
23110913Sgdamore@opensolaris.org 	 * simplicities sake we convert "OPCODE(arg1, arg2)" into
23210913Sgdamore@opensolaris.org 	 * "OPCODE arg1 arg2".  This means that commas and parens are
23310913Sgdamore@opensolaris.org 	 * treated as whitespace.  This can lead to some really messed
23410913Sgdamore@opensolaris.org 	 * up syntaxes that get assembled properly (such as nested
23510913Sgdamore@opensolaris.org 	 * calls, empty arguments, etc.)  Hopefully people don't abuse
23610913Sgdamore@opensolaris.org 	 * this.
23710913Sgdamore@opensolaris.org 	 */
23810913Sgdamore@opensolaris.org 	ls = NULL;
23910913Sgdamore@opensolaris.org 	s = strtok_r(stmt, " \t\n(),", &ls);
24010913Sgdamore@opensolaris.org 	cnt = 0;
24110913Sgdamore@opensolaris.org 	tokcnt = 0;
24210913Sgdamore@opensolaris.org 	while (cnt < 10) {
24310913Sgdamore@opensolaris.org 		tokens[cnt++] = s;
24410913Sgdamore@opensolaris.org 		if (s != NULL) {
24510913Sgdamore@opensolaris.org 			tokcnt++;
24610913Sgdamore@opensolaris.org 			s = strtok_r(NULL, " \t\n(),", &ls);
24710913Sgdamore@opensolaris.org 		}
24810913Sgdamore@opensolaris.org 	}
24910913Sgdamore@opensolaris.org 	return (tokcnt);
25010913Sgdamore@opensolaris.org }
25110913Sgdamore@opensolaris.org 
25210913Sgdamore@opensolaris.org static void
error(char * msg,...)25310913Sgdamore@opensolaris.org error(char *msg, ...)
25410913Sgdamore@opensolaris.org {
25510913Sgdamore@opensolaris.org 	va_list va;
25610913Sgdamore@opensolaris.org 	char msgbuf[1024];
25710913Sgdamore@opensolaris.org 
25810913Sgdamore@opensolaris.org 	va_start(va, msg);
25910913Sgdamore@opensolaris.org 	(void) vsnprintf(msgbuf, sizeof (msgbuf), msg, va);
26010913Sgdamore@opensolaris.org 	va_end(va);
26110913Sgdamore@opensolaris.org 
26210913Sgdamore@opensolaris.org 	(void) fprintf(stderr, "Error: %s on line %d of %s\n", msgbuf, lineno,
26310913Sgdamore@opensolaris.org 	    infile);
26410913Sgdamore@opensolaris.org 	errors++;
26510913Sgdamore@opensolaris.org }
26610913Sgdamore@opensolaris.org 
26710913Sgdamore@opensolaris.org static sym_t *
find_symbol(char * name)26810913Sgdamore@opensolaris.org find_symbol(char *name)
26910913Sgdamore@opensolaris.org {
27010913Sgdamore@opensolaris.org 	int i;
27110913Sgdamore@opensolaris.org 
27210913Sgdamore@opensolaris.org 	for (i = 0; i < nsyms; i++)
27310913Sgdamore@opensolaris.org 		if (strcmp(symtab[i].name, name) == 0) {
27410913Sgdamore@opensolaris.org 			return (&symtab[i]);
27510913Sgdamore@opensolaris.org 		}
27610913Sgdamore@opensolaris.org 
27710913Sgdamore@opensolaris.org 	return (NULL);
27810913Sgdamore@opensolaris.org }
27910913Sgdamore@opensolaris.org 
28010913Sgdamore@opensolaris.org static void
add_symbol(char * name,int type,int arg)28110913Sgdamore@opensolaris.org add_symbol(char *name, int type, int arg)
28210913Sgdamore@opensolaris.org {
28310913Sgdamore@opensolaris.org 	sym_t *sym;
28410913Sgdamore@opensolaris.org 
28510913Sgdamore@opensolaris.org 	if (nsyms >= MAX_SYMBOLS) {
28610913Sgdamore@opensolaris.org 		error("Symbol table full");
28710913Sgdamore@opensolaris.org 		exit(-1);
28810913Sgdamore@opensolaris.org 	}
28910913Sgdamore@opensolaris.org 
29010913Sgdamore@opensolaris.org 	if (find_symbol(name) != NULL) {
29110913Sgdamore@opensolaris.org 		error("Dublicate symbol '%s'", name);
29210913Sgdamore@opensolaris.org 		return;
29310913Sgdamore@opensolaris.org 	}
29410913Sgdamore@opensolaris.org 
29510913Sgdamore@opensolaris.org 	if (strlen(name) >= MAX_NAME) {
29610913Sgdamore@opensolaris.org 		error("Symbol name '%s' too long", name);
29710913Sgdamore@opensolaris.org 		exit(-1);
29810913Sgdamore@opensolaris.org 	}
29910913Sgdamore@opensolaris.org 
30010913Sgdamore@opensolaris.org 	sym = &symtab[nsyms++];
30110913Sgdamore@opensolaris.org 
30210913Sgdamore@opensolaris.org 	(void) strcpy(sym->name, name);
30310913Sgdamore@opensolaris.org 	sym->type = type;
30410913Sgdamore@opensolaris.org 	sym->arg = arg;
30510913Sgdamore@opensolaris.org }
30610913Sgdamore@opensolaris.org 
30710913Sgdamore@opensolaris.org static void
add_init(uint32_t gpr,uint32_t val,const char * name)30810913Sgdamore@opensolaris.org add_init(uint32_t gpr, uint32_t val, const char *name)
30910913Sgdamore@opensolaris.org {
31010913Sgdamore@opensolaris.org 	int	n;
31110913Sgdamore@opensolaris.org 
31210913Sgdamore@opensolaris.org 	n = fle.ninit;
31310913Sgdamore@opensolaris.org 	if (n >= MAX_GPR) {
31410913Sgdamore@opensolaris.org 		error("Too many GPRs");
31510913Sgdamore@opensolaris.org 		return;
31610913Sgdamore@opensolaris.org 	}
31710913Sgdamore@opensolaris.org 	fle.init[n].gpr = gpr;
31810913Sgdamore@opensolaris.org 	fle.init[n].value = val;
31910913Sgdamore@opensolaris.org 	if (name)
32010913Sgdamore@opensolaris.org 		(void) strlcpy(fle.init[n].name, name,
32110913Sgdamore@opensolaris.org 		    sizeof (fle.init[n].name));
32210913Sgdamore@opensolaris.org 	fle.ninit++;
32310913Sgdamore@opensolaris.org }
32410913Sgdamore@opensolaris.org 
32510913Sgdamore@opensolaris.org static void
compile_gpr(char ** tokens,int cnt)32610913Sgdamore@opensolaris.org compile_gpr(char **tokens, int cnt)
32710913Sgdamore@opensolaris.org {
32810913Sgdamore@opensolaris.org 	CHECK_COUNT(tokens, cnt, 2, 2);
32910913Sgdamore@opensolaris.org 
33010913Sgdamore@opensolaris.org 	if (ngpr >= MAX_GPR)
33110913Sgdamore@opensolaris.org 		error("Too many GPR variables");
33210913Sgdamore@opensolaris.org 
33310913Sgdamore@opensolaris.org 	add_symbol(tokens[1], SY_GPR, gpr_base + ngpr++);
33410913Sgdamore@opensolaris.org }
33510913Sgdamore@opensolaris.org 
33610913Sgdamore@opensolaris.org static void
compile_rem(char ** tokens,int cnt)33710913Sgdamore@opensolaris.org compile_rem(char **tokens, int cnt)
33810913Sgdamore@opensolaris.org {
33910913Sgdamore@opensolaris.org 	int i;
34010913Sgdamore@opensolaris.org 
34110913Sgdamore@opensolaris.org 	(void) strlcat(remarks, " *", sizeof (remarks));
34210913Sgdamore@opensolaris.org 	for (i = 1; i < cnt; i++) {
34310913Sgdamore@opensolaris.org 		(void) strlcat(remarks, " ", sizeof (remarks));
34410913Sgdamore@opensolaris.org 		(void) strlcat(remarks, tokens[i], sizeof (remarks));
34510913Sgdamore@opensolaris.org 	}
34610913Sgdamore@opensolaris.org 	(void) strlcat(remarks, "\n", sizeof (remarks));
34710913Sgdamore@opensolaris.org }
34810913Sgdamore@opensolaris.org 
34910913Sgdamore@opensolaris.org static void
declare_const(unsigned int gpr,char * value)35010913Sgdamore@opensolaris.org declare_const(unsigned int gpr, char *value)
35110913Sgdamore@opensolaris.org {
35210913Sgdamore@opensolaris.org 	int n, intv;
35310913Sgdamore@opensolaris.org 	float v;
35410913Sgdamore@opensolaris.org 
35510913Sgdamore@opensolaris.org 	n = fle.consts.nconst;
35610913Sgdamore@opensolaris.org 
35710913Sgdamore@opensolaris.org 	if (n >= MAX_CONST_PARMS) {
35810913Sgdamore@opensolaris.org 		error("Too many constant parameters");
35910913Sgdamore@opensolaris.org 		return;
36010913Sgdamore@opensolaris.org 	}
36110913Sgdamore@opensolaris.org 
36210913Sgdamore@opensolaris.org 	if (*value == 'I') {
36310913Sgdamore@opensolaris.org 		if (sscanf(&value[1], "%g", &v) != 1) {
36410913Sgdamore@opensolaris.org 			error("Bad floating point value (%s)", value);
36510913Sgdamore@opensolaris.org 			return;
36610913Sgdamore@opensolaris.org 		}
36710913Sgdamore@opensolaris.org 		intv = (int)v;
36810913Sgdamore@opensolaris.org 	} else if (*value == '0' && value[1] == 'x') {
36910913Sgdamore@opensolaris.org 		if (sscanf(&value[2], "%x", (unsigned *)&intv) != 1) {
37010913Sgdamore@opensolaris.org 			error("Bad hexadecimal value (%s)", value);
37110913Sgdamore@opensolaris.org 			return;
37210913Sgdamore@opensolaris.org 		}
37310913Sgdamore@opensolaris.org 	} else {
37410913Sgdamore@opensolaris.org 		if (sscanf(value, "%g", &v) != 1) {
37510913Sgdamore@opensolaris.org 			error("Bad floating point value (%s)", value);
37610913Sgdamore@opensolaris.org 			return;
37710913Sgdamore@opensolaris.org 		}
37810913Sgdamore@opensolaris.org 		intv = (int)(v * 0x7fffffff);
37910913Sgdamore@opensolaris.org 	}
38010913Sgdamore@opensolaris.org 
38110913Sgdamore@opensolaris.org 	fle.consts.consts[n].gpr = gpr;
38210913Sgdamore@opensolaris.org 	fle.consts.consts[n].value = intv;
38310913Sgdamore@opensolaris.org 	fle.consts.nconst = n + 1;
38410913Sgdamore@opensolaris.org 
38510913Sgdamore@opensolaris.org 	add_init(gpr, intv, NULL);
38610913Sgdamore@opensolaris.org }
38710913Sgdamore@opensolaris.org 
38810913Sgdamore@opensolaris.org static void
compile_const(char ** tokens,int cnt)38910913Sgdamore@opensolaris.org compile_const(char **tokens, int cnt)
39010913Sgdamore@opensolaris.org {
39110913Sgdamore@opensolaris.org 	CHECK_COUNT(tokens, cnt, 2, 3);
39210913Sgdamore@opensolaris.org 	char *name = tokens[1];
39310913Sgdamore@opensolaris.org 	char *value = tokens[2] ? tokens[2] : tokens[1];
39410913Sgdamore@opensolaris.org 
39510913Sgdamore@opensolaris.org 	if (ngpr >= MAX_GPR)
39610913Sgdamore@opensolaris.org 		error("Too many GPR variables");
39710913Sgdamore@opensolaris.org 
39810913Sgdamore@opensolaris.org 	declare_const(ngpr, value);
39910913Sgdamore@opensolaris.org 
40010913Sgdamore@opensolaris.org 	add_symbol(name, SY_GPR, gpr_base + ngpr++);
40110913Sgdamore@opensolaris.org }
40210913Sgdamore@opensolaris.org 
40310913Sgdamore@opensolaris.org static void
compile_bool(char ** tokens,int cnt)40410913Sgdamore@opensolaris.org compile_bool(char **tokens, int cnt)
40510913Sgdamore@opensolaris.org {
40610913Sgdamore@opensolaris.org 	char *parm, *def;
40710913Sgdamore@opensolaris.org 	int n, num;
40810913Sgdamore@opensolaris.org 
40910913Sgdamore@opensolaris.org 	CHECK_COUNT(tokens, cnt, 3, 3);
41010913Sgdamore@opensolaris.org 
41110913Sgdamore@opensolaris.org 	parm = tokens[1];
41210913Sgdamore@opensolaris.org 	def = tokens[2];
41310913Sgdamore@opensolaris.org 
41410913Sgdamore@opensolaris.org 	n = fle.parms.ngpr;
41510913Sgdamore@opensolaris.org 	if (n >= MAX_GPR_PARMS) {
41610913Sgdamore@opensolaris.org 		error("Too many GPR parameters");
41710913Sgdamore@opensolaris.org 		return;
41810913Sgdamore@opensolaris.org 	}
41910913Sgdamore@opensolaris.org 
42010913Sgdamore@opensolaris.org 	if (sscanf(def, "%d", &num) != 1) {
42110913Sgdamore@opensolaris.org 		error("Bad integer value near '%s'", def);
42210913Sgdamore@opensolaris.org 		return;
42310913Sgdamore@opensolaris.org 	}
42410913Sgdamore@opensolaris.org 
42510913Sgdamore@opensolaris.org 	(void) strcpy(fle.parms.gpr[n].name, parm);
42610913Sgdamore@opensolaris.org 	fle.parms.gpr[n].num = ngpr;
42710913Sgdamore@opensolaris.org 	fle.parms.gpr[n].def = num;
42810913Sgdamore@opensolaris.org 	fle.parms.ngpr = n + 1;
42910913Sgdamore@opensolaris.org 
43010913Sgdamore@opensolaris.org 	add_init(ngpr, num, parm);
43110913Sgdamore@opensolaris.org 
43210913Sgdamore@opensolaris.org 	add_symbol(parm, SY_PARM, gpr_base + ngpr++);
43310913Sgdamore@opensolaris.org }
43410913Sgdamore@opensolaris.org 
43510913Sgdamore@opensolaris.org static void
compile_mono(char ** tokens,int cnt)43610913Sgdamore@opensolaris.org compile_mono(char **tokens, int cnt)
43710913Sgdamore@opensolaris.org {
43810913Sgdamore@opensolaris.org 	char *parm, *def;
43910913Sgdamore@opensolaris.org 	int n, num;
44010913Sgdamore@opensolaris.org 	char tmp[128];
44110913Sgdamore@opensolaris.org 
44210913Sgdamore@opensolaris.org 	CHECK_COUNT(tokens, cnt, 3, 3);
44310913Sgdamore@opensolaris.org 
44410913Sgdamore@opensolaris.org 	parm = tokens[1];
44510913Sgdamore@opensolaris.org 	def = tokens[2];
44610913Sgdamore@opensolaris.org 
44710913Sgdamore@opensolaris.org 	n = fle.parms.ngpr;
44810913Sgdamore@opensolaris.org 	if (n >= MAX_GPR_PARMS) {
44910913Sgdamore@opensolaris.org 		error("Too many GPR parameters");
45010913Sgdamore@opensolaris.org 		return;
45110913Sgdamore@opensolaris.org 	}
45210913Sgdamore@opensolaris.org 
45310913Sgdamore@opensolaris.org 	if (sscanf(def, "%d", &num) != 1) {
45410913Sgdamore@opensolaris.org 		error("Bad integer value near '%s'", def);
45510913Sgdamore@opensolaris.org 		return;
45610913Sgdamore@opensolaris.org 	}
45710913Sgdamore@opensolaris.org 
45810913Sgdamore@opensolaris.org 	(void) strcpy(fle.parms.gpr[n].name, parm);
45910913Sgdamore@opensolaris.org 	fle.parms.gpr[n].num = ngpr;
46010913Sgdamore@opensolaris.org 	fle.parms.gpr[n].def = num;
46110913Sgdamore@opensolaris.org 	fle.parms.ngpr = n + 1;
46210913Sgdamore@opensolaris.org 
46310913Sgdamore@opensolaris.org 	add_init(ngpr, num, parm);
46410913Sgdamore@opensolaris.org 
46510913Sgdamore@opensolaris.org 	add_symbol(parm, SY_PARM, gpr_base + ngpr++);
46610913Sgdamore@opensolaris.org }
46710913Sgdamore@opensolaris.org 
46810913Sgdamore@opensolaris.org static void
compile_stereo(char ** tokens,int cnt)46910913Sgdamore@opensolaris.org compile_stereo(char **tokens, int cnt)
47010913Sgdamore@opensolaris.org {
47110913Sgdamore@opensolaris.org 	char *parm, *def;
47210913Sgdamore@opensolaris.org 	int n, num;
47310913Sgdamore@opensolaris.org 	char tmp[128];
47410913Sgdamore@opensolaris.org 
47510913Sgdamore@opensolaris.org 	CHECK_COUNT(tokens, cnt, 3, 3);
47610913Sgdamore@opensolaris.org 
47710913Sgdamore@opensolaris.org 	parm = tokens[1];
47810913Sgdamore@opensolaris.org 	def = tokens[2];
47910913Sgdamore@opensolaris.org 
48010913Sgdamore@opensolaris.org 	n = fle.parms.ngpr;
48110913Sgdamore@opensolaris.org 	if (n >= MAX_GPR_PARMS) {
48210913Sgdamore@opensolaris.org 		error("Too many GPR parameters");
48310913Sgdamore@opensolaris.org 		return;
48410913Sgdamore@opensolaris.org 	}
48510913Sgdamore@opensolaris.org 
48610913Sgdamore@opensolaris.org 	if (sscanf(def, "%d", &num) != 1) {
48710913Sgdamore@opensolaris.org 		error("Bad integer value near '%s'", def);
48810913Sgdamore@opensolaris.org 		return;
48910913Sgdamore@opensolaris.org 	}
49010913Sgdamore@opensolaris.org 
49110913Sgdamore@opensolaris.org 	(void) strcpy(fle.parms.gpr[n].name, parm);
49210913Sgdamore@opensolaris.org 	fle.parms.gpr[n].num = ngpr;
49310913Sgdamore@opensolaris.org 	fle.parms.gpr[n].def = num | (num << 8);
49410913Sgdamore@opensolaris.org 	fle.parms.ngpr = n + 1;
49510913Sgdamore@opensolaris.org 
49610913Sgdamore@opensolaris.org 	add_init(ngpr, num, parm);
49710913Sgdamore@opensolaris.org 	add_init(ngpr + 1, num, NULL);
49810913Sgdamore@opensolaris.org 
49910913Sgdamore@opensolaris.org 	(void) sprintf(tmp, "%s_L", parm);
50010913Sgdamore@opensolaris.org 	add_symbol(tmp, SY_PARM, gpr_base + ngpr++);
50110913Sgdamore@opensolaris.org 	(void) sprintf(tmp, "%s_R", parm);
50210913Sgdamore@opensolaris.org 	add_symbol(tmp, SY_PARM, gpr_base + ngpr++);
50310913Sgdamore@opensolaris.org }
50410913Sgdamore@opensolaris.org 
50510913Sgdamore@opensolaris.org static void
compile_input(char ** tokens,int cnt)50610913Sgdamore@opensolaris.org compile_input(char **tokens, int cnt)
50710913Sgdamore@opensolaris.org {
50810913Sgdamore@opensolaris.org 	int num;
50910913Sgdamore@opensolaris.org 
51010913Sgdamore@opensolaris.org 	CHECK_COUNT(tokens, cnt, 3, 3);
51110913Sgdamore@opensolaris.org 
51210913Sgdamore@opensolaris.org 	if (sscanf(tokens[2], "%d", &num) != 1) {
51310913Sgdamore@opensolaris.org 		error("Bad integer value near '%s'", tokens[2]);
51410913Sgdamore@opensolaris.org 		return;
51510913Sgdamore@opensolaris.org 	}
51610913Sgdamore@opensolaris.org 
51710913Sgdamore@opensolaris.org 	add_symbol(tokens[1], SY_INPUT, input_base + num);
51810913Sgdamore@opensolaris.org }
51910913Sgdamore@opensolaris.org 
52010913Sgdamore@opensolaris.org static void
compile_send(char ** tokens,int cnt)52110913Sgdamore@opensolaris.org compile_send(char **tokens, int cnt)
52210913Sgdamore@opensolaris.org {
52310913Sgdamore@opensolaris.org 	int num;
52410913Sgdamore@opensolaris.org 
52510913Sgdamore@opensolaris.org 	CHECK_COUNT(tokens, cnt, 3, 3);
52610913Sgdamore@opensolaris.org 
52710913Sgdamore@opensolaris.org 	if (sscanf(tokens[2], "%d", &num) != 1) {
52810913Sgdamore@opensolaris.org 		error("Bad integer near '%s'", tokens[2]);
52910913Sgdamore@opensolaris.org 		return;
53010913Sgdamore@opensolaris.org 	}
53110913Sgdamore@opensolaris.org 
53210913Sgdamore@opensolaris.org 	add_symbol(tokens[1], SY_FX, num);
53310913Sgdamore@opensolaris.org }
53410913Sgdamore@opensolaris.org 
53510913Sgdamore@opensolaris.org static void
compile_output(char ** tokens,int cnt)53610913Sgdamore@opensolaris.org compile_output(char **tokens, int cnt)
53710913Sgdamore@opensolaris.org {
53810913Sgdamore@opensolaris.org 	int num;
53910913Sgdamore@opensolaris.org 
54010913Sgdamore@opensolaris.org 	CHECK_COUNT(tokens, cnt, 3, 3);
54110913Sgdamore@opensolaris.org 
54210913Sgdamore@opensolaris.org 	if (sscanf(tokens[2], "%d", &num) != 1) {
54310913Sgdamore@opensolaris.org 		error("Bad integer value near '%s'", tokens[2]);
54410913Sgdamore@opensolaris.org 		return;
54510913Sgdamore@opensolaris.org 	}
54610913Sgdamore@opensolaris.org 
54710913Sgdamore@opensolaris.org 	add_symbol(tokens[1], SY_OUTPUT, output_base + num);
54810913Sgdamore@opensolaris.org }
54910913Sgdamore@opensolaris.org 
55010913Sgdamore@opensolaris.org static void
compile_directive(char ** tokens,int cnt)55110913Sgdamore@opensolaris.org compile_directive(char **tokens, int cnt)
55210913Sgdamore@opensolaris.org {
55310913Sgdamore@opensolaris.org 	if (strcmp(tokens[0], ".gpr") == 0) {
55410913Sgdamore@opensolaris.org 		compile_gpr(tokens, cnt);
55510913Sgdamore@opensolaris.org 		return;
55610913Sgdamore@opensolaris.org 	}
55710913Sgdamore@opensolaris.org 
55810913Sgdamore@opensolaris.org 	if (strcmp(tokens[0], ".const") == 0) {
55910913Sgdamore@opensolaris.org 		compile_const(tokens, cnt);
56010913Sgdamore@opensolaris.org 		return;
56110913Sgdamore@opensolaris.org 	}
56210913Sgdamore@opensolaris.org 
56310913Sgdamore@opensolaris.org 	if (strcmp(tokens[0], ".stereo") == 0) {
56410913Sgdamore@opensolaris.org 		compile_stereo(tokens, cnt);
56510913Sgdamore@opensolaris.org 		return;
56610913Sgdamore@opensolaris.org 	}
56710913Sgdamore@opensolaris.org 
56810913Sgdamore@opensolaris.org 	if (strcmp(tokens[0], ".mono") == 0) {
56910913Sgdamore@opensolaris.org 		compile_mono(tokens, cnt);
57010913Sgdamore@opensolaris.org 		return;
57110913Sgdamore@opensolaris.org 	}
57210913Sgdamore@opensolaris.org 
57310913Sgdamore@opensolaris.org 	if (strcmp(tokens[0], ".bool") == 0) {
57410913Sgdamore@opensolaris.org 		compile_bool(tokens, cnt);
57510913Sgdamore@opensolaris.org 		return;
57610913Sgdamore@opensolaris.org 	}
57710913Sgdamore@opensolaris.org 
57810913Sgdamore@opensolaris.org 	if (strcmp(tokens[0], ".input") == 0) {
57910913Sgdamore@opensolaris.org 		compile_input(tokens, cnt);
58010913Sgdamore@opensolaris.org 		return;
58110913Sgdamore@opensolaris.org 	}
58210913Sgdamore@opensolaris.org 
58310913Sgdamore@opensolaris.org 	if (strcmp(tokens[0], ".send") == 0) {
58410913Sgdamore@opensolaris.org 		compile_send(tokens, cnt);
58510913Sgdamore@opensolaris.org 		return;
58610913Sgdamore@opensolaris.org 	}
58710913Sgdamore@opensolaris.org 
58810913Sgdamore@opensolaris.org 	if (strcmp(tokens[0], ".output") == 0) {
58910913Sgdamore@opensolaris.org 		compile_output(tokens, cnt);
59010913Sgdamore@opensolaris.org 		return;
59110913Sgdamore@opensolaris.org 	}
59210913Sgdamore@opensolaris.org 
59310913Sgdamore@opensolaris.org 	if (strcmp(tokens[0], ".rem") == 0) {
59410913Sgdamore@opensolaris.org 		compile_rem(tokens, cnt);
59510913Sgdamore@opensolaris.org 		return;
59610913Sgdamore@opensolaris.org 	}
59710913Sgdamore@opensolaris.org 	if (strcmp(tokens[0], ".'") == 0) {
59810913Sgdamore@opensolaris.org 		compile_rem(tokens, cnt);
59910913Sgdamore@opensolaris.org 		return;
60010913Sgdamore@opensolaris.org 	}
60110913Sgdamore@opensolaris.org 
60210913Sgdamore@opensolaris.org 	error("Unknown directive '%s'", tokens[0]);
60310913Sgdamore@opensolaris.org }
60410913Sgdamore@opensolaris.org 
60510913Sgdamore@opensolaris.org static void
compile_asm(char ** tokens,int cnt)60610913Sgdamore@opensolaris.org compile_asm(char **tokens, int cnt)
60710913Sgdamore@opensolaris.org {
60810913Sgdamore@opensolaris.org 	char *parms[4];
60910913Sgdamore@opensolaris.org 	sym_t *symbols[4];
61010913Sgdamore@opensolaris.org #define	EMIT(o, r, a, x, y) \
61110913Sgdamore@opensolaris.org 	fle.code[pc*2] =  ((x) << 10) | (y);			\
61210913Sgdamore@opensolaris.org 	fle.code[pc*2+1] = ((o) << 20) | ((r) << 10) | a; pc++
61310913Sgdamore@opensolaris.org #define	EMIT_AUDIGY(o, r, a, x, y) \
61410913Sgdamore@opensolaris.org 	fle.code[pc*2] =  ((x) << 12) | (y);			\
61510913Sgdamore@opensolaris.org 	fle.code[pc*2+1] = ((o) << 24) | ((r) << 12) | a; pc++
61610913Sgdamore@opensolaris.org 
61710913Sgdamore@opensolaris.org 	int i, n = 0, nerr = 0;
61810913Sgdamore@opensolaris.org 	int ninputs = 0;
61910913Sgdamore@opensolaris.org 
62010913Sgdamore@opensolaris.org 	CHECK_COUNT(tokens, cnt, 5, 5);
62110913Sgdamore@opensolaris.org 
62210913Sgdamore@opensolaris.org 	for (i = 0; i < 4; i++) {
62310913Sgdamore@opensolaris.org 		if ((symbols[i] = find_symbol(tokens[i+1])) == NULL) {
62410913Sgdamore@opensolaris.org 			(void) fprintf(stderr, "%s\n", tokens[i+1]);
62510913Sgdamore@opensolaris.org 			nerr++;
62610913Sgdamore@opensolaris.org 			error("Undefined symbol '%s'", tokens[i + 1]);
62710913Sgdamore@opensolaris.org 			continue;
62810913Sgdamore@opensolaris.org 		}
62910913Sgdamore@opensolaris.org 
63010913Sgdamore@opensolaris.org 		if (symbols[i]->type == SY_INPUT)
63110913Sgdamore@opensolaris.org 			ninputs++;
63210913Sgdamore@opensolaris.org 
63310913Sgdamore@opensolaris.org 		if (symbols[i]->type == SY_ACCUM && i != 1)
63410913Sgdamore@opensolaris.org 			error("Bad usage of 'accum' operand.");
63510913Sgdamore@opensolaris.org 	}
63610913Sgdamore@opensolaris.org 
63710913Sgdamore@opensolaris.org 	if (nerr > 0)
63810913Sgdamore@opensolaris.org 		return;
63910913Sgdamore@opensolaris.org 
64010913Sgdamore@opensolaris.org 	if (ninputs > 1) {
64110913Sgdamore@opensolaris.org 		error("Attempt to access more than one input "
64210913Sgdamore@opensolaris.org 		    "GPRs by the same instruction");
64310913Sgdamore@opensolaris.org 	}
64410913Sgdamore@opensolaris.org 
64510913Sgdamore@opensolaris.org 	for (i = 0; instructions[i].name != NULL; i++)
64610913Sgdamore@opensolaris.org 		if (strcasecmp(tokens[0], instructions[i].name) == 0)  {
64710913Sgdamore@opensolaris.org 
64810913Sgdamore@opensolaris.org 			if (is_audigy) {
64910913Sgdamore@opensolaris.org 				EMIT_AUDIGY(instructions[i].opcode,
65010913Sgdamore@opensolaris.org 				    symbols[0]->arg,
65110913Sgdamore@opensolaris.org 				    symbols[1]->arg,
65210913Sgdamore@opensolaris.org 				    symbols[2]->arg,
65310913Sgdamore@opensolaris.org 				    symbols[3]->arg);
65410913Sgdamore@opensolaris.org 			} else {
65510913Sgdamore@opensolaris.org 				EMIT(instructions[i].opcode,
65610913Sgdamore@opensolaris.org 				    symbols[0]->arg,
65710913Sgdamore@opensolaris.org 				    symbols[1]->arg,
65810913Sgdamore@opensolaris.org 				    symbols[2]->arg,
65910913Sgdamore@opensolaris.org 				    symbols[3]->arg);
66010913Sgdamore@opensolaris.org 			}
66110913Sgdamore@opensolaris.org 
66210913Sgdamore@opensolaris.org 			return;
66310913Sgdamore@opensolaris.org 		}
66410913Sgdamore@opensolaris.org 
66510913Sgdamore@opensolaris.org 	error("Unrecognized instruction '%s'", tokens[0]);
66610913Sgdamore@opensolaris.org }
66710913Sgdamore@opensolaris.org 
66810913Sgdamore@opensolaris.org static void
init_compiler(void)66910913Sgdamore@opensolaris.org init_compiler(void)
67010913Sgdamore@opensolaris.org {
67110913Sgdamore@opensolaris.org 	char tmp[100];
67210913Sgdamore@opensolaris.org 	int i;
67310913Sgdamore@opensolaris.org 
67410913Sgdamore@opensolaris.org 	(void) memset(&fle, 0, sizeof (fle));
67510913Sgdamore@opensolaris.org 	/*
67610913Sgdamore@opensolaris.org 	 * Initialize few predefined GPR parameter registers. These
67710913Sgdamore@opensolaris.org 	 * definitions have to be in sync with the GPR_* macros in
67810913Sgdamore@opensolaris.org 	 * <sblive.h>.
67910913Sgdamore@opensolaris.org 	 */
68010913Sgdamore@opensolaris.org 
68110913Sgdamore@opensolaris.org 	/*
68210913Sgdamore@opensolaris.org 	 * Make sure we start at gpr id 2 for now; 0 and 1 may be used
68310913Sgdamore@opensolaris.org 	 * differently.
68410913Sgdamore@opensolaris.org 	 */
68510913Sgdamore@opensolaris.org 	add_symbol("NULL", SY_DUMMY, gpr_base + ngpr++);
68610913Sgdamore@opensolaris.org 	add_symbol("NULL_", SY_DUMMY, gpr_base + ngpr++);
68710913Sgdamore@opensolaris.org 
68810913Sgdamore@opensolaris.org 	pc = 0;
68910913Sgdamore@opensolaris.org 
69010913Sgdamore@opensolaris.org 	if (is_audigy) {
69110913Sgdamore@opensolaris.org 		/* Initialize the code array with NOPs (AUDIGY) */
69210913Sgdamore@opensolaris.org 		for (i = 0; i < 512; i++) {
69310913Sgdamore@opensolaris.org 			fle.code[i * 2 + 0] = (0xc0 << 12) | 0xc0;
69410913Sgdamore@opensolaris.org 			fle.code[i * 2 + 1] =
69510913Sgdamore@opensolaris.org 			    (0x06 << 24) | (0xc0 << 12) | 0xc0;
69610913Sgdamore@opensolaris.org 		}
69710913Sgdamore@opensolaris.org 
69810913Sgdamore@opensolaris.org 		for (i = 0; i < 32; i++) {
69910913Sgdamore@opensolaris.org 			(void) sprintf(tmp, "fx%d", i);
70010913Sgdamore@opensolaris.org 			add_symbol(tmp, SY_FX, i);
70110913Sgdamore@opensolaris.org 		}
70210913Sgdamore@opensolaris.org 	} else {
70310913Sgdamore@opensolaris.org 		/* Initialize the code array with NOPs (LIVE) */
70410913Sgdamore@opensolaris.org 		for (i = 0; i < 512; i++) {
70510913Sgdamore@opensolaris.org 			fle.code[i * 2 + 0] = 0x10040;
70610913Sgdamore@opensolaris.org 			fle.code[i * 2 + 1] = 0x610040;
70710913Sgdamore@opensolaris.org 		}
70810913Sgdamore@opensolaris.org 
70910913Sgdamore@opensolaris.org 		for (i = 0; i < 16; i++) {
71010913Sgdamore@opensolaris.org 			(void) sprintf(tmp, "fx%d", i);
71110913Sgdamore@opensolaris.org 			add_symbol(tmp, SY_FX, i);
71210913Sgdamore@opensolaris.org 		}
71310913Sgdamore@opensolaris.org 	}
71410913Sgdamore@opensolaris.org 
71510913Sgdamore@opensolaris.org 	/*
71610913Sgdamore@opensolaris.org 	 * Constants
71710913Sgdamore@opensolaris.org 	 */
71810913Sgdamore@opensolaris.org 
71910913Sgdamore@opensolaris.org 	if (is_audigy) {
72010913Sgdamore@opensolaris.org 		/* Audigy symbols */
72110913Sgdamore@opensolaris.org 		add_symbol("0", SY_CONST, 0x0c0);
72210913Sgdamore@opensolaris.org 		add_symbol("1", SY_CONST, 0x0c1);
72310913Sgdamore@opensolaris.org 		add_symbol("2", SY_CONST, 0x0c2);
72410913Sgdamore@opensolaris.org 		add_symbol("3", SY_CONST, 0x0c3);
72510913Sgdamore@opensolaris.org 		add_symbol("4", SY_CONST, 0x0c4);
72610913Sgdamore@opensolaris.org 		add_symbol("8", SY_CONST, 0x0c5);
72710913Sgdamore@opensolaris.org 		add_symbol("16", SY_CONST, 0x0c6);
72810913Sgdamore@opensolaris.org 		add_symbol("32", SY_CONST, 0x0c7);
72910913Sgdamore@opensolaris.org 		add_symbol("256", SY_CONST, 0x0c8);
73010913Sgdamore@opensolaris.org 		add_symbol("65536", SY_CONST, 0x0c9);
73110913Sgdamore@opensolaris.org 
73210913Sgdamore@opensolaris.org 		add_symbol("2048", SY_CONST, 0x0ca);
73310913Sgdamore@opensolaris.org 		add_symbol("0x800", SY_CONST, 0x0ca);
73410913Sgdamore@opensolaris.org 
73510913Sgdamore@opensolaris.org 		add_symbol("2^28", SY_CONST, 0x0cb);
73610913Sgdamore@opensolaris.org 		add_symbol("0x10000000", SY_CONST, 0x0cb);
73710913Sgdamore@opensolaris.org 
73810913Sgdamore@opensolaris.org 		add_symbol("2^29", SY_CONST, 0x0cc);
73910913Sgdamore@opensolaris.org 		add_symbol("0x20000000", SY_CONST, 0x0cc);
74010913Sgdamore@opensolaris.org 
74110913Sgdamore@opensolaris.org 		add_symbol("2^30", SY_CONST, 0x0cd);
74210913Sgdamore@opensolaris.org 		add_symbol("0x40000000", SY_CONST, 0x0cd);
74310913Sgdamore@opensolaris.org 
74410913Sgdamore@opensolaris.org 		add_symbol("2^31", SY_CONST, 0x0ce);
74510913Sgdamore@opensolaris.org 		add_symbol("0x80000000", SY_CONST, 0x0ce);
74610913Sgdamore@opensolaris.org 
74710913Sgdamore@opensolaris.org 		add_symbol("0x7fffffff", SY_CONST, 0x0cf);
74810913Sgdamore@opensolaris.org 
74910913Sgdamore@opensolaris.org 		add_symbol("0xffffffff", SY_CONST, 0x0d0);
75010913Sgdamore@opensolaris.org 		add_symbol("-1", SY_CONST, 0x0d0);
75110913Sgdamore@opensolaris.org 
75210913Sgdamore@opensolaris.org 		add_symbol("0xfffffffe", SY_CONST, 0x0d1);
75310913Sgdamore@opensolaris.org 		add_symbol("-2", SY_CONST, 0x0d1);
75410913Sgdamore@opensolaris.org 
75510913Sgdamore@opensolaris.org 		add_symbol("0xc0000000", SY_CONST, 0x0d2);
75610913Sgdamore@opensolaris.org 
75710913Sgdamore@opensolaris.org 		add_symbol("0x4f1bbcdc", SY_CONST, 0x0d3);
75810913Sgdamore@opensolaris.org 
75910913Sgdamore@opensolaris.org 		add_symbol("0x5a7ef9db", SY_CONST, 0x0d4);
76010913Sgdamore@opensolaris.org 
76110913Sgdamore@opensolaris.org 		add_symbol("0x100000", SY_CONST, 0x0d5);
76210913Sgdamore@opensolaris.org 		add_symbol("accum", SY_ACCUM, 0x0d6);
76310913Sgdamore@opensolaris.org 		add_symbol("CCR", SY_CONST, 0x0d7);
76410913Sgdamore@opensolaris.org 
76510913Sgdamore@opensolaris.org 		add_symbol("noise_L", SY_CONST, 0x0d8);
76610913Sgdamore@opensolaris.org 		add_symbol("noise_R", SY_CONST, 0x0d9);
76710913Sgdamore@opensolaris.org 		add_symbol("IRQREQ", SY_CONST, 0x0da);
76810913Sgdamore@opensolaris.org 	} else {
76910913Sgdamore@opensolaris.org 		/* SB Live symbols */
77010913Sgdamore@opensolaris.org 		add_symbol("0", SY_CONST, 0x040);
77110913Sgdamore@opensolaris.org 		add_symbol("1", SY_CONST, 0x041);
77210913Sgdamore@opensolaris.org 		add_symbol("2", SY_CONST, 0x042);
77310913Sgdamore@opensolaris.org 		add_symbol("3", SY_CONST, 0x043);
77410913Sgdamore@opensolaris.org 		add_symbol("4", SY_CONST, 0x044);
77510913Sgdamore@opensolaris.org 		add_symbol("8", SY_CONST, 0x045);
77610913Sgdamore@opensolaris.org 		add_symbol("16", SY_CONST, 0x046);
77710913Sgdamore@opensolaris.org 		add_symbol("32", SY_CONST, 0x047);
77810913Sgdamore@opensolaris.org 		add_symbol("256", SY_CONST, 0x048);
77910913Sgdamore@opensolaris.org 		add_symbol("65536", SY_CONST, 0x049);
78010913Sgdamore@opensolaris.org 
78110913Sgdamore@opensolaris.org 		add_symbol("2^23", SY_CONST, 0x04a);
78210913Sgdamore@opensolaris.org 		add_symbol("0x80000", SY_CONST, 0x04a);
78310913Sgdamore@opensolaris.org 
78410913Sgdamore@opensolaris.org 		add_symbol("2^28", SY_CONST, 0x04b);
78510913Sgdamore@opensolaris.org 		add_symbol("0x10000000", SY_CONST, 0x04b);
78610913Sgdamore@opensolaris.org 
78710913Sgdamore@opensolaris.org 		add_symbol("2^29", SY_CONST, 0x04c);
78810913Sgdamore@opensolaris.org 		add_symbol("0x20000000", SY_CONST, 0x04c);
78910913Sgdamore@opensolaris.org 
79010913Sgdamore@opensolaris.org 		add_symbol("2^30", SY_CONST, 0x04d);
79110913Sgdamore@opensolaris.org 		add_symbol("0x40000000", SY_CONST, 0x04d);
79210913Sgdamore@opensolaris.org 
79310913Sgdamore@opensolaris.org 		add_symbol("2^31", SY_CONST, 0x04e);
79410913Sgdamore@opensolaris.org 		add_symbol("0x80000000", SY_CONST, 0x04e);
79510913Sgdamore@opensolaris.org 
79610913Sgdamore@opensolaris.org 		add_symbol("0x7fffffff", SY_CONST, 0x04f);
79710913Sgdamore@opensolaris.org 
79810913Sgdamore@opensolaris.org 		add_symbol("0xffffffff", SY_CONST, 0x050);
79910913Sgdamore@opensolaris.org 		add_symbol("-1", SY_CONST, 0x050);
80010913Sgdamore@opensolaris.org 
80110913Sgdamore@opensolaris.org 		add_symbol("0xfffffffe", SY_CONST, 0x051);
80210913Sgdamore@opensolaris.org 		add_symbol("-2", SY_CONST, 0x051);
80310913Sgdamore@opensolaris.org 
80410913Sgdamore@opensolaris.org 		add_symbol("accum", SY_ACCUM, 0x056);
80510913Sgdamore@opensolaris.org 		add_symbol("CCR", SY_CONST, 0x057);
80610913Sgdamore@opensolaris.org 
80710913Sgdamore@opensolaris.org 		add_symbol("noise_L", SY_CONST, 0x058);
80810913Sgdamore@opensolaris.org 		add_symbol("noise_R", SY_CONST, 0x059);
80910913Sgdamore@opensolaris.org 		add_symbol("IRQREQ", SY_CONST, 0x05a);
81010913Sgdamore@opensolaris.org 	}
81110913Sgdamore@opensolaris.org }
81210913Sgdamore@opensolaris.org 
81310913Sgdamore@opensolaris.org static void
produce_map(char * name)81410913Sgdamore@opensolaris.org produce_map(char *name)
81510913Sgdamore@opensolaris.org {
81610913Sgdamore@opensolaris.org 	char fname[1024];
81710913Sgdamore@opensolaris.org 	int i;
81810913Sgdamore@opensolaris.org 	FILE *f;
81910913Sgdamore@opensolaris.org 
82010913Sgdamore@opensolaris.org 	if ((f = fopen(name, "w")) == NULL) {
82110913Sgdamore@opensolaris.org 		perror(name);
82210913Sgdamore@opensolaris.org 		return;
82310913Sgdamore@opensolaris.org 	}
82410913Sgdamore@opensolaris.org 
82510913Sgdamore@opensolaris.org 	(void) fprintf(f, "%d\n", pc);
82610913Sgdamore@opensolaris.org 
82710913Sgdamore@opensolaris.org 	for (i = 0; i < nsyms; i++) {
82810913Sgdamore@opensolaris.org 		(void) fprintf(f, "%04x %x %s\n",
82910913Sgdamore@opensolaris.org 		    symtab[i].arg, symtab[i].type, symtab[i].name);
83010913Sgdamore@opensolaris.org 	}
83110913Sgdamore@opensolaris.org 
83210913Sgdamore@opensolaris.org 	(void) fclose(f);
83310913Sgdamore@opensolaris.org 	if (verbose) {
83410913Sgdamore@opensolaris.org 		(void) fprintf(stderr,
83510913Sgdamore@opensolaris.org 		    "No errors detected - Map written to %s\n", name);
83610913Sgdamore@opensolaris.org 	}
83710913Sgdamore@opensolaris.org }
83810913Sgdamore@opensolaris.org 
83910913Sgdamore@opensolaris.org static void
produce_output(char * fname)84010913Sgdamore@opensolaris.org produce_output(char *fname)
84110913Sgdamore@opensolaris.org {
84210913Sgdamore@opensolaris.org 	int fd;
84310913Sgdamore@opensolaris.org 
84410913Sgdamore@opensolaris.org 	if ((fd = creat(fname, 0644)) == -1) {
84510913Sgdamore@opensolaris.org 		perror(fname);
84610913Sgdamore@opensolaris.org 		exit(-1);
84710913Sgdamore@opensolaris.org 	}
84810913Sgdamore@opensolaris.org 
84910913Sgdamore@opensolaris.org 	if (write(fd, &fle, sizeof (fle)) != sizeof (fle)) {
85010913Sgdamore@opensolaris.org 		perror(fname);
85110913Sgdamore@opensolaris.org 		exit(-1);
85210913Sgdamore@opensolaris.org 	}
85310913Sgdamore@opensolaris.org 
85410913Sgdamore@opensolaris.org 	if (verbose) {
85510913Sgdamore@opensolaris.org 		(void) fprintf(stderr,
85610913Sgdamore@opensolaris.org 		    "No errors detected - Binary written to %s\n",
85710913Sgdamore@opensolaris.org 		    fname);
85810913Sgdamore@opensolaris.org 	}
85910913Sgdamore@opensolaris.org 
86010913Sgdamore@opensolaris.org 	(void) close(fd);
86110913Sgdamore@opensolaris.org }
86210913Sgdamore@opensolaris.org 
86310913Sgdamore@opensolaris.org static void
produce_header(char * fname,char * prefix)86410913Sgdamore@opensolaris.org produce_header(char *fname, char *prefix)
86510913Sgdamore@opensolaris.org {
86610913Sgdamore@opensolaris.org 	FILE *f;
86710913Sgdamore@opensolaris.org 	char *s;
86810913Sgdamore@opensolaris.org 	char sname[MAXPATHLEN + 1];
86910913Sgdamore@opensolaris.org 	char dname[MAXPATHLEN + 1];
87010913Sgdamore@opensolaris.org 	int i;
87110913Sgdamore@opensolaris.org 	clock_t now;
87210913Sgdamore@opensolaris.org 	char when[128];
87310913Sgdamore@opensolaris.org 
87410913Sgdamore@opensolaris.org 	/* get basename */
87510913Sgdamore@opensolaris.org 	if (prefix == NULL) {
87610913Sgdamore@opensolaris.org 		s = strrchr(fname, '/');
87710913Sgdamore@opensolaris.org 		s = (s == NULL) ? fname : s + 1;
87810913Sgdamore@opensolaris.org 	} else {
87910913Sgdamore@opensolaris.org 		s = prefix;
88010913Sgdamore@opensolaris.org 	}
88110913Sgdamore@opensolaris.org 	(void) strlcpy(sname, s, sizeof (sname));
88210913Sgdamore@opensolaris.org 
88310913Sgdamore@opensolaris.org 	/* strip off any extension */
88410913Sgdamore@opensolaris.org 	s = strchr(sname, '.');
88510913Sgdamore@opensolaris.org 	if (s != NULL) {
88610913Sgdamore@opensolaris.org 		*s = 0;
88710913Sgdamore@opensolaris.org 	}
88810913Sgdamore@opensolaris.org 	if ((f = fopen(fname, "w")) == NULL) {
88910913Sgdamore@opensolaris.org 		perror(fname);
89010913Sgdamore@opensolaris.org 		return;
89110913Sgdamore@opensolaris.org 	}
89210913Sgdamore@opensolaris.org 
89310913Sgdamore@opensolaris.org 	if (remarks[0] != 0) {
89410913Sgdamore@opensolaris.org 		(void) fprintf(f, "/*\n%s */\n", remarks);
89510913Sgdamore@opensolaris.org 	}
89610913Sgdamore@opensolaris.org 	now = time(NULL);
89710913Sgdamore@opensolaris.org 	strftime(when, sizeof (when), "%c", localtime(&now));
89810913Sgdamore@opensolaris.org 	(void) fprintf(f, banner, progname, when);
89910913Sgdamore@opensolaris.org 
90010913Sgdamore@opensolaris.org 	(void) strlcpy(dname, prefix ? prefix : sname, sizeof (dname));
90110913Sgdamore@opensolaris.org 	for (i = 0; dname[i]; i++) {
90210913Sgdamore@opensolaris.org 		dname[i] = toupper(dname[i]);
90310913Sgdamore@opensolaris.org 		if (!isalnum(dname[i])) {
90410913Sgdamore@opensolaris.org 			dname[i] = '_';
90510913Sgdamore@opensolaris.org 		}
90610913Sgdamore@opensolaris.org 	}
90710913Sgdamore@opensolaris.org 
90810913Sgdamore@opensolaris.org 	for (i = 0; i < fle.parms.ngpr; i++) {
90910913Sgdamore@opensolaris.org 		(void) fprintf(f, "#define\t%s_%s\t\t%d\n",
91010913Sgdamore@opensolaris.org 		    dname, fle.parms.gpr[i].name, fle.parms.gpr[i].num);
91110913Sgdamore@opensolaris.org 	}
91210913Sgdamore@opensolaris.org 
91310913Sgdamore@opensolaris.org 	(void) fprintf(f, "\n");
91410913Sgdamore@opensolaris.org 
91510913Sgdamore@opensolaris.org 	if (parms_only)
91610913Sgdamore@opensolaris.org 		goto done;
91710913Sgdamore@opensolaris.org 
91810913Sgdamore@opensolaris.org 	(void) fprintf(f, "uint32_t %s_code[] = {\n", sname);
91910913Sgdamore@opensolaris.org 
92010913Sgdamore@opensolaris.org 	for (i = 0; i < pc * 2; i++) {
92110913Sgdamore@opensolaris.org 		if (i == 0) {
92210913Sgdamore@opensolaris.org 			(void) fprintf(f, "\t0x%08xU", fle.code[i]);
92310913Sgdamore@opensolaris.org 		} else if ((i % 4) == 0) {
92410913Sgdamore@opensolaris.org 			(void) fprintf(f, ",\n\t0x%08xU", fle.code[i]);
92510913Sgdamore@opensolaris.org 		} else {
92610913Sgdamore@opensolaris.org 			(void) fprintf(f, ", 0x%08xU", fle.code[i]);
92710913Sgdamore@opensolaris.org 		}
92810913Sgdamore@opensolaris.org 	}
92910913Sgdamore@opensolaris.org 	(void) fprintf(f, "\n};\n");
93010913Sgdamore@opensolaris.org 
93110913Sgdamore@opensolaris.org 	(void) fprintf(f, "uint32_t %s_ninit = %d;\n", sname, fle.ninit);
93210913Sgdamore@opensolaris.org 	(void) fprintf(f, "uint32_t %s_init[] = {\n", sname);
93310913Sgdamore@opensolaris.org 
93410913Sgdamore@opensolaris.org 	for (i = 0; i < fle.ninit; i++) {
93510913Sgdamore@opensolaris.org 		if (fle.init[i].name[0]) {
93610913Sgdamore@opensolaris.org 			(void) fprintf(f, "\t%u, 0x%x%s,\t/* %s */\n",
93710913Sgdamore@opensolaris.org 			    fle.init[i].gpr, fle.init[i].value,
93810913Sgdamore@opensolaris.org 			    fle.init[i].value >= 0x80000000U ? "U" : "",
93910913Sgdamore@opensolaris.org 			    fle.init[i].name);
94010913Sgdamore@opensolaris.org 		} else {
94110913Sgdamore@opensolaris.org 			(void) fprintf(f, "\t%u, 0x%x%s,\n",
94210913Sgdamore@opensolaris.org 			    fle.init[i].gpr, fle.init[i].value,
94310913Sgdamore@opensolaris.org 			    fle.init[i].value >= 0x80000000U ? "U" : "");
94410913Sgdamore@opensolaris.org 		}
94510913Sgdamore@opensolaris.org 	}
94610913Sgdamore@opensolaris.org 	(void) fprintf(f, "};\n");
94710913Sgdamore@opensolaris.org 
94810913Sgdamore@opensolaris.org done:
94910913Sgdamore@opensolaris.org 	(void) fclose(f);
95010913Sgdamore@opensolaris.org 	if (verbose) {
95110913Sgdamore@opensolaris.org 		(void) fprintf(stderr,
95210913Sgdamore@opensolaris.org 		    "No errors detected - Header written to %s\n",
95310913Sgdamore@opensolaris.org 		    fname);
95410913Sgdamore@opensolaris.org 	}
95510913Sgdamore@opensolaris.org }
95610913Sgdamore@opensolaris.org 
95710913Sgdamore@opensolaris.org int
main(int argc,char * argv[])95810913Sgdamore@opensolaris.org main(int argc, char *argv[])
95910913Sgdamore@opensolaris.org {
96010913Sgdamore@opensolaris.org 	char line[4096], *p, *s, *outfile;
96110913Sgdamore@opensolaris.org 	char *iline;
96210913Sgdamore@opensolaris.org 	int i;
96310913Sgdamore@opensolaris.org 	FILE *input;
96410913Sgdamore@opensolaris.org 	char *tokens[10];
96510913Sgdamore@opensolaris.org 	int tokcnt;
96610913Sgdamore@opensolaris.org 	char *mapfile = NULL;
96710913Sgdamore@opensolaris.org 	char *header = NULL;
96810913Sgdamore@opensolaris.org 	char *prefix = NULL;
96910913Sgdamore@opensolaris.org 
97010913Sgdamore@opensolaris.org 	outfile = NULL;
97110913Sgdamore@opensolaris.org 	infile = NULL;
97210913Sgdamore@opensolaris.org 	input = NULL;
97310913Sgdamore@opensolaris.org 	progname = argv[0];
97410913Sgdamore@opensolaris.org 
97510913Sgdamore@opensolaris.org 	while ((i = getopt(argc, argv, "m:h:o:i:P:021v")) != EOF) {
97610913Sgdamore@opensolaris.org 		switch (i) {
97710913Sgdamore@opensolaris.org 		case 'o':
97810913Sgdamore@opensolaris.org 			outfile = optarg;
97910913Sgdamore@opensolaris.org 			break;
98010913Sgdamore@opensolaris.org 		case 'i':
98110913Sgdamore@opensolaris.org 			infile = strdup(optarg);
98210913Sgdamore@opensolaris.org 			break;
98310913Sgdamore@opensolaris.org 		case 'm':
98410913Sgdamore@opensolaris.org 			mapfile = optarg;
98510913Sgdamore@opensolaris.org 			break;
98610913Sgdamore@opensolaris.org 		case 'P':
98710913Sgdamore@opensolaris.org 			prefix = optarg;
98810913Sgdamore@opensolaris.org 			break;
98910913Sgdamore@opensolaris.org 		case 'h':
99010913Sgdamore@opensolaris.org 			header = optarg;
99110913Sgdamore@opensolaris.org 			break;
99210913Sgdamore@opensolaris.org 		case '0':
99310913Sgdamore@opensolaris.org 			parms_only = 1;
99410913Sgdamore@opensolaris.org 			break;
99510913Sgdamore@opensolaris.org 		case '2':
99610913Sgdamore@opensolaris.org 			is_audigy = 1;
99710913Sgdamore@opensolaris.org 			break;
99810913Sgdamore@opensolaris.org 		case '1':
99910913Sgdamore@opensolaris.org 			is_audigy = 0;
100010913Sgdamore@opensolaris.org 			break;
100110913Sgdamore@opensolaris.org 		case 'v':
100210913Sgdamore@opensolaris.org 			verbose++;
100310913Sgdamore@opensolaris.org 			break;
100410913Sgdamore@opensolaris.org 		default:
100510913Sgdamore@opensolaris.org 			(void) fprintf(stderr,
100610913Sgdamore@opensolaris.org 			    "usage: %s [-m <map>] [-h <header>] "
100710913Sgdamore@opensolaris.org 			    "[-o <binary>] [-i <source>] [-2|-1]",
100810913Sgdamore@opensolaris.org 			    progname);
100910913Sgdamore@opensolaris.org 			exit(-1);
101010913Sgdamore@opensolaris.org 			break;
101110913Sgdamore@opensolaris.org 		}
101210913Sgdamore@opensolaris.org 	}
101310913Sgdamore@opensolaris.org 
101410913Sgdamore@opensolaris.org 	if ((outfile == NULL) && (mapfile == NULL) && (header == NULL)) {
101510913Sgdamore@opensolaris.org 		outfile = "dsp.bin";
101610913Sgdamore@opensolaris.org 	}
101710913Sgdamore@opensolaris.org 
101810913Sgdamore@opensolaris.org 	if (infile) {
101910913Sgdamore@opensolaris.org 		input = fopen(infile, "r");
102010913Sgdamore@opensolaris.org 		if (input == NULL) {
102110913Sgdamore@opensolaris.org 			perror(infile);
102210913Sgdamore@opensolaris.org 			exit(-1);
102310913Sgdamore@opensolaris.org 		}
102410913Sgdamore@opensolaris.org 	} else {
102510913Sgdamore@opensolaris.org 		infile = strdup("<stdin>");
102610913Sgdamore@opensolaris.org 		input = stdin;
102710913Sgdamore@opensolaris.org 	}
102810913Sgdamore@opensolaris.org 
102910913Sgdamore@opensolaris.org 	if (is_audigy) {
103010913Sgdamore@opensolaris.org 		gpr_base = 0x400;
103110913Sgdamore@opensolaris.org 		input_base = 0x40;
103210913Sgdamore@opensolaris.org 		output_base = 0x60;
103310913Sgdamore@opensolaris.org 		if (verbose)
103410913Sgdamore@opensolaris.org 			(void) fprintf(stderr, "Compiling for SB Audigy\n");
103510913Sgdamore@opensolaris.org 	} else {
103610913Sgdamore@opensolaris.org 		if (verbose)
103710913Sgdamore@opensolaris.org 			(void) fprintf(stderr, "Compiling for SB Live\n");
103810913Sgdamore@opensolaris.org 	}
103910913Sgdamore@opensolaris.org 
104010913Sgdamore@opensolaris.org 	init_compiler();
104110913Sgdamore@opensolaris.org 
1042*13093SRoger.Faulkner@Oracle.COM 	while ((tokcnt = getaline(input, tokens)) != -1) {
104310913Sgdamore@opensolaris.org 		/* skip empty lines */
104410913Sgdamore@opensolaris.org 		if (tokcnt == 0) {
104510913Sgdamore@opensolaris.org 			continue;
104610913Sgdamore@opensolaris.org 		}
104710913Sgdamore@opensolaris.org 
104810913Sgdamore@opensolaris.org 		if (strcmp(tokens[0], "#") == 0) {
104910913Sgdamore@opensolaris.org 			int	num;
105010913Sgdamore@opensolaris.org 			if ((tokcnt >= 3) &&
105110913Sgdamore@opensolaris.org 			    (sscanf(tokens[1], "%d", &num) == 1)) {
105210913Sgdamore@opensolaris.org 				lineno = num;
105310913Sgdamore@opensolaris.org 				free(infile);
105410913Sgdamore@opensolaris.org 				infile = strdup(tokens[2]);
105510913Sgdamore@opensolaris.org 				/* we don't want to count the # directive */
105610913Sgdamore@opensolaris.org 				lineno--;
105710913Sgdamore@opensolaris.org 			}
105810913Sgdamore@opensolaris.org 
105910913Sgdamore@opensolaris.org 			/* unknown # directive? muddle on... */
106010913Sgdamore@opensolaris.org 			continue;
106110913Sgdamore@opensolaris.org 		}
106210913Sgdamore@opensolaris.org 		if (*tokens[0] == '.') {
106310913Sgdamore@opensolaris.org 			compile_directive(tokens, tokcnt);
106410913Sgdamore@opensolaris.org 		} else {
106510913Sgdamore@opensolaris.org 			compile_asm(tokens, tokcnt);
106610913Sgdamore@opensolaris.org 		}
106710913Sgdamore@opensolaris.org 	}
106810913Sgdamore@opensolaris.org 
106910913Sgdamore@opensolaris.org 	if (lineno < 1) {
107010913Sgdamore@opensolaris.org 		error("Empty input");
107110913Sgdamore@opensolaris.org 	}
107210913Sgdamore@opensolaris.org 
107310913Sgdamore@opensolaris.org 	if (errors == 0) {
107410913Sgdamore@opensolaris.org 		if (verbose) {
107510913Sgdamore@opensolaris.org 			(void) fprintf(stderr,
107610913Sgdamore@opensolaris.org 			    "%d instructions out of 512 assembled\n", pc);
107710913Sgdamore@opensolaris.org 		}
107810913Sgdamore@opensolaris.org 
107910913Sgdamore@opensolaris.org 		if (outfile)
108010913Sgdamore@opensolaris.org 			produce_output(outfile);
108110913Sgdamore@opensolaris.org 		if (mapfile)
108210913Sgdamore@opensolaris.org 			produce_map(mapfile);
108310913Sgdamore@opensolaris.org 		if (header)
108410913Sgdamore@opensolaris.org 			produce_header(header, prefix);
108510913Sgdamore@opensolaris.org 	}
108610913Sgdamore@opensolaris.org 
108710913Sgdamore@opensolaris.org 	if (errors > 0) {
108810913Sgdamore@opensolaris.org 		(void) fprintf(stderr, "%d errors - compile failed\n", errors);
108910913Sgdamore@opensolaris.org 		exit(-1);
109010913Sgdamore@opensolaris.org 	}
109110913Sgdamore@opensolaris.org 
109210913Sgdamore@opensolaris.org 	return (0);
109310913Sgdamore@opensolaris.org }
1094