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