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