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