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