4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
27 * Assembler for Emu10k1
30 * Copyright (C) 4Front Technologies 1996-2008.
40 #include <sys/param.h>
43 #define MAX_GPR_PARMS 60
44 #define MAX_CONST_PARMS 128
45 #define GPR_NAME_SIZE 32
48 char name
[GPR_NAME_SIZE
];
62 gpr_t gpr
[MAX_GPR_PARMS
];
68 const_t consts
[MAX_CONST_PARMS
];
72 unsigned int code
[1024];
79 char name
[GPR_NAME_SIZE
];
84 #define MAX_SYMBOLS 1024
86 static int parms_only
= 0;
87 static int is_audigy
= 0;
88 static int verbose
= 0;
90 static int gpr_base
= 0x100;
91 static int input_base
= 0x10;
92 static int output_base
= 0x20;
94 static char *progname
;
115 static char remarks
[2048] = "";
116 static char *banner
=
118 " * Note: This file was automatically generated by %s\n"
123 * Instructions. Each instruction takes 4 arguments, R, A, X, and Y.
125 static instruction_t instructions
[] = {
126 { "MACS", 0x0}, /* R = A + (X * Y >> 31); saturation */
127 { "MACS1", 0x1}, /* R = A + (-X * Y >> 31); saturation */
128 { "MACW", 0x2}, /* R = A + (X * Y >> 31); wraparound */
129 { "MACW1", 0x3}, /* R = A + (-X * Y >> 31); wraparound */
130 { "MACINTS", 0x4}, /* R = A + (X * Y); saturation */
131 { "MACINTW", 0x5}, /* R = A + (X * Y); wraparound */
132 { "SUM", 0x6}, /* R = A + X + Y; saturation */
133 { "ACC3", 0x6}, /* R = A + X + Y; saturation */
134 { "MACMV", 0x7}, /* R = A, acc += X * Y >> 31 */
135 { "ANDXOR", 0x8}, /* R = (A & X) ^ Y */
136 { "TSTNEG", 0x9}, /* R = (A >= Y) ? X : ~X */
137 { "LIMIT", 0xa}, /* R = (A >= Y) ? X : Y */
138 { "LIMIT1", 0xb}, /* R = (A < Y) ? X : Y */
139 { "LOG", 0xc}, /* R = ... (log?) */
140 { "EXP", 0xd}, /* R = ... (exp?) */
141 { "INTERP", 0xe}, /* R = A + (X * (Y - A) >> 31) */
142 { "SKIP", 0xf}, /* R, CCR, CC_TEST, COUNT */
146 #define CHECK_COUNT(tokens, cnt, mincnt, maxcnt) \
147 if (cnt < mincnt) { \
148 error("Too few parameters for '%s' (have %d, min %d)", \
149 tokens[0], cnt - 1, mincnt - 1); \
152 if (cnt > maxcnt) { \
153 error("Too many parameters for '%s' (have %d, max %d)", \
154 tokens[0], cnt - 1, maxcnt - 1); \
158 static sym_t symtab
[MAX_SYMBOLS
];
159 static int nsyms
= 0;
161 static int lineno
= 0, errors
= 0;
162 static emu10k1_file fle
;
169 getaline(FILE *input
, char **tokens
)
172 static char *stmt
= NULL
, *lasts
= NULL
;
173 static char line
[4096];
179 if (fgets(line
, sizeof (line
), input
) == NULL
)
184 * Special handling for .' comments. We use
185 * .' as a keyword to ensure that entire
186 * comment makes it through the C preprocessor
187 * unmolested. We also need to make sure *we*
188 * don't molest it either. The comment will
189 * be exported to any resulting header,
190 * allowing us to pass through copyright and
191 * other information from the source file to
192 * the resulting header.
195 s
+= strspn(s
, " \t");
196 if ((strncmp(s
, ".'", 2) == 0) &&
197 (strchr(" \t\n", s
[2]) != NULL
)) {
198 /* chop off trailing new line */
199 (void) strtok(line
, "\n");
202 s
+= strspn(s
, " \t");
203 if ((s
[0] == '\'') &&
204 (s
[strlen(s
) - 1] == '\'')) {
205 s
[strlen(s
) - 1] = 0;
212 return (strlen(tokens
[1]) ? 2 : 1);
215 /* strip off any C++ style comments that CPP missed */
216 if ((s
= strstr(line
, "//")) != NULL
) {
219 stmt
= strtok_r(line
, ";\n", &lasts
);
221 stmt
= strtok_r(NULL
, ";\n", &lasts
);
230 * Ok, we have a statement, lets tokenize it. For
231 * simplicities sake we convert "OPCODE(arg1, arg2)" into
232 * "OPCODE arg1 arg2". This means that commas and parens are
233 * treated as whitespace. This can lead to some really messed
234 * up syntaxes that get assembled properly (such as nested
235 * calls, empty arguments, etc.) Hopefully people don't abuse
239 s
= strtok_r(stmt
, " \t\n(),", &ls
);
246 s
= strtok_r(NULL
, " \t\n(),", &ls
);
253 error(char *msg
, ...)
259 (void) vsnprintf(msgbuf
, sizeof (msgbuf
), msg
, va
);
262 (void) fprintf(stderr
, "Error: %s on line %d of %s\n", msgbuf
, lineno
,
268 find_symbol(char *name
)
272 for (i
= 0; i
< nsyms
; i
++)
273 if (strcmp(symtab
[i
].name
, name
) == 0) {
281 add_symbol(char *name
, int type
, int arg
)
285 if (nsyms
>= MAX_SYMBOLS
) {
286 error("Symbol table full");
290 if (find_symbol(name
) != NULL
) {
291 error("Dublicate symbol '%s'", name
);
295 if (strlen(name
) >= MAX_NAME
) {
296 error("Symbol name '%s' too long", name
);
300 sym
= &symtab
[nsyms
++];
302 (void) strcpy(sym
->name
, name
);
308 add_init(uint32_t gpr
, uint32_t val
, const char *name
)
314 error("Too many GPRs");
317 fle
.init
[n
].gpr
= gpr
;
318 fle
.init
[n
].value
= val
;
320 (void) strlcpy(fle
.init
[n
].name
, name
,
321 sizeof (fle
.init
[n
].name
));
326 compile_gpr(char **tokens
, int cnt
)
328 CHECK_COUNT(tokens
, cnt
, 2, 2);
331 error("Too many GPR variables");
333 add_symbol(tokens
[1], SY_GPR
, gpr_base
+ ngpr
++);
337 compile_rem(char **tokens
, int cnt
)
341 (void) strlcat(remarks
, " *", sizeof (remarks
));
342 for (i
= 1; i
< cnt
; i
++) {
343 (void) strlcat(remarks
, " ", sizeof (remarks
));
344 (void) strlcat(remarks
, tokens
[i
], sizeof (remarks
));
346 (void) strlcat(remarks
, "\n", sizeof (remarks
));
350 declare_const(unsigned int gpr
, char *value
)
355 n
= fle
.consts
.nconst
;
357 if (n
>= MAX_CONST_PARMS
) {
358 error("Too many constant parameters");
363 if (sscanf(&value
[1], "%g", &v
) != 1) {
364 error("Bad floating point value (%s)", value
);
368 } else if (*value
== '0' && value
[1] == 'x') {
369 if (sscanf(&value
[2], "%x", (unsigned *)&intv
) != 1) {
370 error("Bad hexadecimal value (%s)", value
);
374 if (sscanf(value
, "%g", &v
) != 1) {
375 error("Bad floating point value (%s)", value
);
378 intv
= (int)(v
* 0x7fffffff);
381 fle
.consts
.consts
[n
].gpr
= gpr
;
382 fle
.consts
.consts
[n
].value
= intv
;
383 fle
.consts
.nconst
= n
+ 1;
385 add_init(gpr
, intv
, NULL
);
389 compile_const(char **tokens
, int cnt
)
391 CHECK_COUNT(tokens
, cnt
, 2, 3);
392 char *name
= tokens
[1];
393 char *value
= tokens
[2] ? tokens
[2] : tokens
[1];
396 error("Too many GPR variables");
398 declare_const(ngpr
, value
);
400 add_symbol(name
, SY_GPR
, gpr_base
+ ngpr
++);
404 compile_bool(char **tokens
, int cnt
)
409 CHECK_COUNT(tokens
, cnt
, 3, 3);
415 if (n
>= MAX_GPR_PARMS
) {
416 error("Too many GPR parameters");
420 if (sscanf(def
, "%d", &num
) != 1) {
421 error("Bad integer value near '%s'", def
);
425 (void) strcpy(fle
.parms
.gpr
[n
].name
, parm
);
426 fle
.parms
.gpr
[n
].num
= ngpr
;
427 fle
.parms
.gpr
[n
].def
= num
;
428 fle
.parms
.ngpr
= n
+ 1;
430 add_init(ngpr
, num
, parm
);
432 add_symbol(parm
, SY_PARM
, gpr_base
+ ngpr
++);
436 compile_mono(char **tokens
, int cnt
)
441 CHECK_COUNT(tokens
, cnt
, 3, 3);
447 if (n
>= MAX_GPR_PARMS
) {
448 error("Too many GPR parameters");
452 if (sscanf(def
, "%d", &num
) != 1) {
453 error("Bad integer value near '%s'", def
);
457 (void) strcpy(fle
.parms
.gpr
[n
].name
, parm
);
458 fle
.parms
.gpr
[n
].num
= ngpr
;
459 fle
.parms
.gpr
[n
].def
= num
;
460 fle
.parms
.ngpr
= n
+ 1;
462 add_init(ngpr
, num
, parm
);
464 add_symbol(parm
, SY_PARM
, gpr_base
+ ngpr
++);
468 compile_stereo(char **tokens
, int cnt
)
474 CHECK_COUNT(tokens
, cnt
, 3, 3);
480 if (n
>= MAX_GPR_PARMS
) {
481 error("Too many GPR parameters");
485 if (sscanf(def
, "%d", &num
) != 1) {
486 error("Bad integer value near '%s'", def
);
490 (void) strcpy(fle
.parms
.gpr
[n
].name
, parm
);
491 fle
.parms
.gpr
[n
].num
= ngpr
;
492 fle
.parms
.gpr
[n
].def
= num
| (num
<< 8);
493 fle
.parms
.ngpr
= n
+ 1;
495 add_init(ngpr
, num
, parm
);
496 add_init(ngpr
+ 1, num
, NULL
);
498 (void) sprintf(tmp
, "%s_L", parm
);
499 add_symbol(tmp
, SY_PARM
, gpr_base
+ ngpr
++);
500 (void) sprintf(tmp
, "%s_R", parm
);
501 add_symbol(tmp
, SY_PARM
, gpr_base
+ ngpr
++);
505 compile_input(char **tokens
, int cnt
)
509 CHECK_COUNT(tokens
, cnt
, 3, 3);
511 if (sscanf(tokens
[2], "%d", &num
) != 1) {
512 error("Bad integer value near '%s'", tokens
[2]);
516 add_symbol(tokens
[1], SY_INPUT
, input_base
+ num
);
520 compile_send(char **tokens
, int cnt
)
524 CHECK_COUNT(tokens
, cnt
, 3, 3);
526 if (sscanf(tokens
[2], "%d", &num
) != 1) {
527 error("Bad integer near '%s'", tokens
[2]);
531 add_symbol(tokens
[1], SY_FX
, num
);
535 compile_output(char **tokens
, int cnt
)
539 CHECK_COUNT(tokens
, cnt
, 3, 3);
541 if (sscanf(tokens
[2], "%d", &num
) != 1) {
542 error("Bad integer value near '%s'", tokens
[2]);
546 add_symbol(tokens
[1], SY_OUTPUT
, output_base
+ num
);
550 compile_directive(char **tokens
, int cnt
)
552 if (strcmp(tokens
[0], ".gpr") == 0) {
553 compile_gpr(tokens
, cnt
);
557 if (strcmp(tokens
[0], ".const") == 0) {
558 compile_const(tokens
, cnt
);
562 if (strcmp(tokens
[0], ".stereo") == 0) {
563 compile_stereo(tokens
, cnt
);
567 if (strcmp(tokens
[0], ".mono") == 0) {
568 compile_mono(tokens
, cnt
);
572 if (strcmp(tokens
[0], ".bool") == 0) {
573 compile_bool(tokens
, cnt
);
577 if (strcmp(tokens
[0], ".input") == 0) {
578 compile_input(tokens
, cnt
);
582 if (strcmp(tokens
[0], ".send") == 0) {
583 compile_send(tokens
, cnt
);
587 if (strcmp(tokens
[0], ".output") == 0) {
588 compile_output(tokens
, cnt
);
592 if (strcmp(tokens
[0], ".rem") == 0) {
593 compile_rem(tokens
, cnt
);
596 if (strcmp(tokens
[0], ".'") == 0) {
597 compile_rem(tokens
, cnt
);
601 error("Unknown directive '%s'", tokens
[0]);
605 compile_asm(char **tokens
, int cnt
)
608 #define EMIT(o, r, a, x, y) \
609 fle.code[pc*2] = ((x) << 10) | (y); \
610 fle.code[pc*2+1] = ((o) << 20) | ((r) << 10) | a; pc++
611 #define EMIT_AUDIGY(o, r, a, x, y) \
612 fle.code[pc*2] = ((x) << 12) | (y); \
613 fle.code[pc*2+1] = ((o) << 24) | ((r) << 12) | a; pc++
618 CHECK_COUNT(tokens
, cnt
, 5, 5);
620 for (i
= 0; i
< 4; i
++) {
621 if ((symbols
[i
] = find_symbol(tokens
[i
+1])) == NULL
) {
622 (void) fprintf(stderr
, "%s\n", tokens
[i
+1]);
624 error("Undefined symbol '%s'", tokens
[i
+ 1]);
628 if (symbols
[i
]->type
== SY_INPUT
)
631 if (symbols
[i
]->type
== SY_ACCUM
&& i
!= 1)
632 error("Bad usage of 'accum' operand.");
639 error("Attempt to access more than one input "
640 "GPRs by the same instruction");
643 for (i
= 0; instructions
[i
].name
!= NULL
; i
++)
644 if (strcasecmp(tokens
[0], instructions
[i
].name
) == 0) {
647 EMIT_AUDIGY(instructions
[i
].opcode
,
653 EMIT(instructions
[i
].opcode
,
663 error("Unrecognized instruction '%s'", tokens
[0]);
672 (void) memset(&fle
, 0, sizeof (fle
));
674 * Initialize few predefined GPR parameter registers. These
675 * definitions have to be in sync with the GPR_* macros in
680 * Make sure we start at gpr id 2 for now; 0 and 1 may be used
683 add_symbol("NULL", SY_DUMMY
, gpr_base
+ ngpr
++);
684 add_symbol("NULL_", SY_DUMMY
, gpr_base
+ ngpr
++);
689 /* Initialize the code array with NOPs (AUDIGY) */
690 for (i
= 0; i
< 512; i
++) {
691 fle
.code
[i
* 2 + 0] = (0xc0 << 12) | 0xc0;
692 fle
.code
[i
* 2 + 1] =
693 (0x06 << 24) | (0xc0 << 12) | 0xc0;
696 for (i
= 0; i
< 32; i
++) {
697 (void) sprintf(tmp
, "fx%d", i
);
698 add_symbol(tmp
, SY_FX
, i
);
701 /* Initialize the code array with NOPs (LIVE) */
702 for (i
= 0; i
< 512; i
++) {
703 fle
.code
[i
* 2 + 0] = 0x10040;
704 fle
.code
[i
* 2 + 1] = 0x610040;
707 for (i
= 0; i
< 16; i
++) {
708 (void) sprintf(tmp
, "fx%d", i
);
709 add_symbol(tmp
, SY_FX
, i
);
719 add_symbol("0", SY_CONST
, 0x0c0);
720 add_symbol("1", SY_CONST
, 0x0c1);
721 add_symbol("2", SY_CONST
, 0x0c2);
722 add_symbol("3", SY_CONST
, 0x0c3);
723 add_symbol("4", SY_CONST
, 0x0c4);
724 add_symbol("8", SY_CONST
, 0x0c5);
725 add_symbol("16", SY_CONST
, 0x0c6);
726 add_symbol("32", SY_CONST
, 0x0c7);
727 add_symbol("256", SY_CONST
, 0x0c8);
728 add_symbol("65536", SY_CONST
, 0x0c9);
730 add_symbol("2048", SY_CONST
, 0x0ca);
731 add_symbol("0x800", SY_CONST
, 0x0ca);
733 add_symbol("2^28", SY_CONST
, 0x0cb);
734 add_symbol("0x10000000", SY_CONST
, 0x0cb);
736 add_symbol("2^29", SY_CONST
, 0x0cc);
737 add_symbol("0x20000000", SY_CONST
, 0x0cc);
739 add_symbol("2^30", SY_CONST
, 0x0cd);
740 add_symbol("0x40000000", SY_CONST
, 0x0cd);
742 add_symbol("2^31", SY_CONST
, 0x0ce);
743 add_symbol("0x80000000", SY_CONST
, 0x0ce);
745 add_symbol("0x7fffffff", SY_CONST
, 0x0cf);
747 add_symbol("0xffffffff", SY_CONST
, 0x0d0);
748 add_symbol("-1", SY_CONST
, 0x0d0);
750 add_symbol("0xfffffffe", SY_CONST
, 0x0d1);
751 add_symbol("-2", SY_CONST
, 0x0d1);
753 add_symbol("0xc0000000", SY_CONST
, 0x0d2);
755 add_symbol("0x4f1bbcdc", SY_CONST
, 0x0d3);
757 add_symbol("0x5a7ef9db", SY_CONST
, 0x0d4);
759 add_symbol("0x100000", SY_CONST
, 0x0d5);
760 add_symbol("accum", SY_ACCUM
, 0x0d6);
761 add_symbol("CCR", SY_CONST
, 0x0d7);
763 add_symbol("noise_L", SY_CONST
, 0x0d8);
764 add_symbol("noise_R", SY_CONST
, 0x0d9);
765 add_symbol("IRQREQ", SY_CONST
, 0x0da);
767 /* SB Live symbols */
768 add_symbol("0", SY_CONST
, 0x040);
769 add_symbol("1", SY_CONST
, 0x041);
770 add_symbol("2", SY_CONST
, 0x042);
771 add_symbol("3", SY_CONST
, 0x043);
772 add_symbol("4", SY_CONST
, 0x044);
773 add_symbol("8", SY_CONST
, 0x045);
774 add_symbol("16", SY_CONST
, 0x046);
775 add_symbol("32", SY_CONST
, 0x047);
776 add_symbol("256", SY_CONST
, 0x048);
777 add_symbol("65536", SY_CONST
, 0x049);
779 add_symbol("2^23", SY_CONST
, 0x04a);
780 add_symbol("0x80000", SY_CONST
, 0x04a);
782 add_symbol("2^28", SY_CONST
, 0x04b);
783 add_symbol("0x10000000", SY_CONST
, 0x04b);
785 add_symbol("2^29", SY_CONST
, 0x04c);
786 add_symbol("0x20000000", SY_CONST
, 0x04c);
788 add_symbol("2^30", SY_CONST
, 0x04d);
789 add_symbol("0x40000000", SY_CONST
, 0x04d);
791 add_symbol("2^31", SY_CONST
, 0x04e);
792 add_symbol("0x80000000", SY_CONST
, 0x04e);
794 add_symbol("0x7fffffff", SY_CONST
, 0x04f);
796 add_symbol("0xffffffff", SY_CONST
, 0x050);
797 add_symbol("-1", SY_CONST
, 0x050);
799 add_symbol("0xfffffffe", SY_CONST
, 0x051);
800 add_symbol("-2", SY_CONST
, 0x051);
802 add_symbol("accum", SY_ACCUM
, 0x056);
803 add_symbol("CCR", SY_CONST
, 0x057);
805 add_symbol("noise_L", SY_CONST
, 0x058);
806 add_symbol("noise_R", SY_CONST
, 0x059);
807 add_symbol("IRQREQ", SY_CONST
, 0x05a);
812 produce_map(char *name
)
817 if ((f
= fopen(name
, "w")) == NULL
) {
822 (void) fprintf(f
, "%d\n", pc
);
824 for (i
= 0; i
< nsyms
; i
++) {
825 (void) fprintf(f
, "%04x %x %s\n",
826 symtab
[i
].arg
, symtab
[i
].type
, symtab
[i
].name
);
831 (void) fprintf(stderr
,
832 "No errors detected - Map written to %s\n", name
);
837 produce_output(char *fname
)
841 if ((fd
= creat(fname
, 0644)) == -1) {
846 if (write(fd
, &fle
, sizeof (fle
)) != sizeof (fle
)) {
852 (void) fprintf(stderr
,
853 "No errors detected - Binary written to %s\n",
861 produce_header(char *fname
, char *prefix
)
865 char sname
[MAXPATHLEN
+ 1];
866 char dname
[MAXPATHLEN
+ 1];
872 if (prefix
== NULL
) {
873 s
= strrchr(fname
, '/');
874 s
= (s
== NULL
) ? fname
: s
+ 1;
878 (void) strlcpy(sname
, s
, sizeof (sname
));
880 /* strip off any extension */
881 s
= strchr(sname
, '.');
885 if ((f
= fopen(fname
, "w")) == NULL
) {
890 if (remarks
[0] != 0) {
891 (void) fprintf(f
, "/*\n%s */\n", remarks
);
894 strftime(when
, sizeof (when
), "%c", localtime(&now
));
895 (void) fprintf(f
, banner
, progname
, when
);
897 (void) strlcpy(dname
, prefix
? prefix
: sname
, sizeof (dname
));
898 for (i
= 0; dname
[i
]; i
++) {
899 dname
[i
] = toupper(dname
[i
]);
900 if (!isalnum(dname
[i
])) {
905 for (i
= 0; i
< fle
.parms
.ngpr
; i
++) {
906 (void) fprintf(f
, "#define\t%s_%s\t\t%d\n",
907 dname
, fle
.parms
.gpr
[i
].name
, fle
.parms
.gpr
[i
].num
);
910 (void) fprintf(f
, "\n");
915 (void) fprintf(f
, "uint32_t %s_code[] = {\n", sname
);
917 for (i
= 0; i
< pc
* 2; i
++) {
919 (void) fprintf(f
, "\t0x%08xU", fle
.code
[i
]);
920 } else if ((i
% 4) == 0) {
921 (void) fprintf(f
, ",\n\t0x%08xU", fle
.code
[i
]);
923 (void) fprintf(f
, ", 0x%08xU", fle
.code
[i
]);
926 (void) fprintf(f
, "\n};\n");
928 (void) fprintf(f
, "uint32_t %s_ninit = %d;\n", sname
, fle
.ninit
);
929 (void) fprintf(f
, "uint32_t %s_init[] = {\n", sname
);
931 for (i
= 0; i
< fle
.ninit
; i
++) {
932 if (fle
.init
[i
].name
[0]) {
933 (void) fprintf(f
, "\t%u, 0x%x%s,\t/* %s */\n",
934 fle
.init
[i
].gpr
, fle
.init
[i
].value
,
935 fle
.init
[i
].value
>= 0x80000000U
? "U" : "",
938 (void) fprintf(f
, "\t%u, 0x%x%s,\n",
939 fle
.init
[i
].gpr
, fle
.init
[i
].value
,
940 fle
.init
[i
].value
>= 0x80000000U
? "U" : "");
943 (void) fprintf(f
, "};\n");
948 (void) fprintf(stderr
,
949 "No errors detected - Header written to %s\n",
955 main(int argc
, char *argv
[])
962 char *mapfile
= NULL
;
971 while ((i
= getopt(argc
, argv
, "m:h:o:i:P:021v")) != EOF
) {
977 infile
= strdup(optarg
);
1001 (void) fprintf(stderr
,
1002 "usage: %s [-m <map>] [-h <header>] "
1003 "[-o <binary>] [-i <source>] [-2|-1]",
1010 if ((outfile
== NULL
) && (mapfile
== NULL
) && (header
== NULL
)) {
1011 outfile
= "dsp.bin";
1015 input
= fopen(infile
, "r");
1016 if (input
== NULL
) {
1021 infile
= strdup("<stdin>");
1030 (void) fprintf(stderr
, "Compiling for SB Audigy\n");
1033 (void) fprintf(stderr
, "Compiling for SB Live\n");
1038 while ((tokcnt
= getaline(input
, tokens
)) != -1) {
1039 /* skip empty lines */
1044 if (strcmp(tokens
[0], "#") == 0) {
1046 if ((tokcnt
>= 3) &&
1047 (sscanf(tokens
[1], "%d", &num
) == 1)) {
1050 infile
= strdup(tokens
[2]);
1051 /* we don't want to count the # directive */
1055 /* unknown # directive? muddle on... */
1058 if (*tokens
[0] == '.') {
1059 compile_directive(tokens
, tokcnt
);
1061 compile_asm(tokens
, tokcnt
);
1066 error("Empty input");
1071 (void) fprintf(stderr
,
1072 "%d instructions out of 512 assembled\n", pc
);
1076 produce_output(outfile
);
1078 produce_map(mapfile
);
1080 produce_header(header
, prefix
);
1084 (void) fprintf(stderr
, "%d errors - compile failed\n", errors
);