1File: MAIN.C Page 1 1 /* 2 Copyright 1981 3 Alcyon Corporation 4 8716 Production Ave. 5 San Diego, Ca. 92121 6 */ 7 8 char *sccs "@(#)as68 - Nov 12, 1982"; 9 10 /* 11 * a two pass relocatable assembler for the Motorola 68000 microprocessor 12 13 * Bill Allen 14 * Modified by Vicki Hutchison 15 16 * after any of this assembler is recompiled, it must be initialized 17 * before it will execute properly. To initialize, become super user 18 * and execute the command: 19 20 * as68 -i as68init 21 22 * where as68 is the newly compiled version of the assembler. With- 23 * out this initialization, the assembler will not run (probably bus 24 * error). 25 */ 26 27 /* 28 * Revisions : 29 * 30 * Added fix to make location relative equates 31 * correct even if branch optimization occurs. vlh 15-sep-82 32 * Recognizes commands in uppercase. vlh 17-sep-82 33 * Added recognization of upper case directives 34 * which do not have the preceding '.'. vlh 17-sep-82 35 * Added recognizing of ignored directives 36 * IDNT, ORG and MASK2. vlh 17-sep-82 37 * Added new directives XDEF, XREF. vlh 17-sep-82 38 * Added COMLINE and SECTION. vlh 20-sep-82 39 * Added new directive REG. vlh 21-sep-82 40 * Added new directives DCB and OFFSET. vlh 22-sep-82 41 * Recognizes branch extensions and takes 42 * the appropriate action. vlh 22-sep-82 43 * Added assembler directives ifeq, ifne, 44 * ifle, iflt, ifge, ifgt. vlh 23-sep-82 45 * Added character '$' to set of legitimate 46 * characters in a symbol. vlh 23-sep-82 47 * Added new ignored directive OPT. vlh 23-sep-82 48 * Recognizes non-opcodes starting in column 1 49 * as labels. vlh 23-sep-82 50 * Added conditional assembler directives 51 * ifc, ifnc. vlh 27-sep-82 52 * Major reworking of expression handler vlh 1-oct-82 53 * More revisions to expression stacks vlh 4-oct-82 54 * Added the recognition and handling of vlh 26-oct-82 55 * the 'illegal' instruction. 56 * Added handling of the jmp suffixes vlh 26-oct-82 57 * Fixed problem with -p flag and external vlh 27-oct-82 58 * variable listings. 59 * Added checking for legitimate command vlh 28-oct-82 1File: MAIN.C Page 2 60 * suffixes. 61 * Added comma as a legitimate register vlh 28-oct-82 62 * divisor for the REG directive. 63 * Fixed second pass error/instr len problem vlh 28-oct-82 64 * Added checking for invalid bit ranges. vlh 1-nov-82 65 * Added proper 2nd pass handling of the vlh 2-nov-82 66 * '*' symbol (avoid turning jsr to bra). 67 * Fixed first pass guess if operand is vlh 4-nov-82 68 * (rx,rx) instead of d(rx,rx). 69 * Check for appropriate range of 16-bit vlh 5-nov-82 70 * immediate date. 71 * Operand type check for shift/bit manip. vlh 5-nov-82 72 * Turn and/or/eor #xxx,sr/ccr into the vlh 5-nov-82 73 * corresponding immediate instruction. 74 * Generate an error when an illegal pc vlh 10-nov-82 75 * relative ea is specified. 76 */ 77 78 /****************************************************************************/ 79 /* */ 80 /* D R I H a c k s */ 81 /* ----------------- */ 82 /* */ 83 /* The following changes were made to facilitate running as68 under */ 84 /* VMS and CP/M: */ 85 /* */ 86 /* o Added "-f" flag to redirect temp files to another directory */ 87 /* or CP/M floppy drive. */ 88 /* */ 89 /* o Added "-s" flag to redirect symbol table file. */ 90 /* */ 91 /* o Added separate source file with initialization of all */ 92 /* external variables to be compatible with Whitesmith's C. */ 93 /* */ 94 /* o Added "VMS", "UNIX", and "CPM" conditional compilation */ 95 /* switches for these operating systems. */ 96 /* */ 97 /* o Added various listing enhancements so the printed file is */ 98 /* usable on non-UNIX environments. */ 99 /* */ 100 /* o Changed I/O calls to be useable with filter library on V7 */ 101 /* */ 102 /****************************************************************************/ 103 104 105 106 # include "as68.h" 107 char tfilname[80]; /* Temp filename area */ 108 char initfnam[80]; /* Initialization filename area */ 109 #ifdef UNIX 110 char tfilbase[] {"a6AXXXXXX"}; 111 #else 112 char tfilbase[] {"a6xxxxA"}; /* Temp file base name */ 113 #endif 114 char initbase[] {"as68symb.dat"}; /* Init file base name */ 115 #ifdef VMS /* On VMS, use */ 116 char *tdname = ""; /* Temps in same directory */ 117 char *idname = "bin:"; /* Init in the "bin:" directory*/ 118 #endif /********************************/ 1File: MAIN.C Page 3 119 #ifdef UNIX /* */ 120 char *tdname = "/tmp/"; /* UNIX Temp directory */ 121 char *idname = "/lib/"; /* UNIX Init Directory */ 122 #endif /********************************/ 123 #ifdef CPM /* On CP/M, defaults for all. */ 124 char *tdname = ""; /* No temp prefix */ 125 char *idname = ""; /* No init prefix */ 126 #endif /********************************/ 127 128 char ldfn[40]; /*name of the relocatable object file*/ 129 130 int brkln1 077777; /*pass 1 break line number for debugging*/ 131 int opcval; /*opcode*/ 132 int chmvq; 133 134 int hopd(), hend(), send(), horg(), sorg(), hequ(), hreg(); 135 int hds(), sds(); 136 int sdcb(); 137 int hdsect(), hpsect(), sdsect(), spsect(); 138 int hsection(), ssection(), hoffset(); 139 int hent(), hext(); 140 int igrst(); 141 int hbss(), sbss(); 142 int heven(), seven(); 143 int hdc(), sdc(), hdcb(); 144 int hmask2(), hcomline(), hidnt(); 145 int hifeq(), hifne(), hiflt(), hifle(), hifgt(), hifge(), hendc(); 146 int hifnc(), hifc(), hopt(); 147 int hpage(),spage(); 148 int (*p1direct[])() { 149 hopd, /*0*/ 150 hend, /*1*/ 151 hdsect, /*2*/ 152 hpsect, /*3*/ 153 hequ, /*4*/ 154 hequ, /*5 .set same as .equ*/ 155 0, /*6*/ 156 0, /*7*/ 157 hdc, /*8*/ 158 hent, /*9*/ 159 hext, /*10*/ 160 hbss, /*11*/ 161 hds, /*12*/ 162 heven, /*13*/ 163 horg, /*14*/ 164 hmask2, /*15*/ 165 hreg, /*16*/ 166 hdcb, /*17*/ 167 hcomline, /*18*/ 168 hidnt, /*19*/ 169 hoffset, /*20*/ 170 hsection, /*21*/ 171 hifeq, /*22*/ 172 hifne, /*23*/ 173 hiflt, /*24*/ 174 hifle, /*25*/ 175 hifgt, /*26*/ 176 hifge, /*27*/ 177 hendc, /*28*/ 1File: MAIN.C Page 4 178 hifc, /*29*/ 179 hifnc, /*30*/ 180 hopt, /*31*/ 181 hpage, /*32*/ 182 0}; 183 184 int (*p2direct[])() { 185 0, /*0*/ 186 send, /*1*/ 187 sdsect, /*2*/ 188 spsect, /*3*/ 189 0, /*4*/ 190 0, /*5*/ 191 0, /*6*/ 192 0, /*7*/ 193 sdc, /*8*/ 194 0, /*9*/ 195 0, /*10*/ 196 sbss, /*11*/ 197 sds, /*12*/ 198 seven, /*13*/ 199 sorg, /*14*/ 200 0, /*15*/ 201 0, /*16*/ 202 sdcb, /*17*/ 203 sds, /*18 comline same as .ds.b*/ 204 0, /*19*/ 205 0, /*20*/ 206 ssection, /*21*/ 207 0, /*22*/ 208 0, /*23*/ 209 0, /*24*/ 210 0, /*25*/ 211 0, /*26*/ 212 0, /*27*/ 213 0, /*28*/ 214 0, /*29*/ 215 0, /*30*/ 216 0, /*31*/ 217 spage, /*32*/ 218 0}; 219 220 char *ermsg[] { 221 "label redefined", /*1*/ 222 "invalid label", /*2*/ 223 "invalid opcode", /*3*/ 224 "no label for operand", /*4*/ 225 "opcode redefined", /*5*/ 226 "illegal expr", /*6*/ 227 "undefined symbol in equate", /*7*/ 228 0, /*8*/ 229 "invalid first operand", /*9*/ 230 "invalid second operand", /*10*/ 231 "absolute value required", /*11*/ 232 "no code or data allowed in offset", /*12*/ 233 "undefined symbol", /*13*/ 234 "illegal index register", /*14*/ 235 "illegal constant", /*15*/ 236 "illegal extension", /*16*/ /*[vlh]*/ 1File: MAIN.C Page 5 237 "constant required", /*17*/ 238 "illegal format", /*18*/ 239 "illegal string", /*19*/ 240 "illegal addressing mode", /*20*/ 241 0, /*21*/ 242 "illegal relative address", /*22*/ 243 "invalid bit range", /*23*/ 244 "illegal text delimiter", /*24*/ 245 "unexpected endc", /*25*/ 246 "endc expected", /*26*/ 247 "relocation error", /*27*/ 248 "symbol required", /*28*/ 249 "bad use of symbol", /*29*/ 250 "invalid data list", /*30*/ 251 0, /*31*/ 252 "missing )", /*32*/ 253 "register required", /*33*/ 254 "illegal size", /*34*/ 255 "illegal 8-bit displacement", /*35*/ 256 "illegal external", /*36*/ 257 "illegal shift count", /*37*/ 258 "invalid instruction length", /*38*/ 259 "code or data not allowed in bss", /*39*/ 260 "backward assignment to *", /*40*/ 261 "illegal 16-bit displacement", /*41*/ 262 "illegal 16-bit immediate", /*42*/ 263 "illegal 8-bit immediate", /*43*/ 264 0 265 }; 266 267 int endit(); 268 int rubout(); 269 int symcon; 270 char endstr[] "end"; 271 char equstr[] "equ"; 272 char evnstr[] "even"; 273 char orgstr[] "~.yxzorg"; 274 275 int poslab; 276 char tlab1[NAMELEN]; 277 int explmode; /*explicit mode length given*/ 278 279 main(argc,argv) 280 char **argv; 281 { 282 register i, ttmp; 283 284 register xargc; /* Temp copy of argc */ 285 xargc = argc; 286 287 initflg = 0; 288 prtchidx = prtchars; 289 #ifdef UNIX /* Only available with UNIX */ 290 signal(2,rubout); 291 #endif 292 pitix = itbuf; 293 pexti = extbl; 294 ttmp = (STESIZE*SZMT) + 2; 295 bmte = sbrk(ttmp); 1File: MAIN.C Page 6 296 if(((long)bmte) == -1L) 297 { 298 rpterr("Symbol Table Overflow\n"); 299 abort(); 300 } 301 if((long)bmte&1) 302 bmte++; /*make it even*/ 303 emte = bmte + ttmp - 2; /*end of main table*/ 304 if(argc<=1) usage(); 305 i = 1; 306 shortadr = -1; /*short addresses ok*/ 307 while(argv[i][0] == '-') { /*may be print or initialize*/ 308 switch(argv[i++][1]) { 309 310 case 'i': /*initialize the assembler*/ 311 case 'I': 312 initflg++; 313 break; 314 315 case 'p': /*produce a listing*/ 316 case 'P': 317 prtflg++; 318 break; 319 320 case 'u': /*make undefined symbols external*/ 321 case 'U': 322 undflg++; 323 break; 324 325 case 'N': /*no branch optimization*/ 326 case 'n': 327 didorg++; 328 break; 329 330 case 'L': /*long addresses only*/ 331 case 'l': 332 shortadr = 0; 333 break; 334 335 case 'f': /* Change temp files */ 336 case 'F': 337 tdname = argv[i++]; 338 break; 339 340 case 's': /* Change symbol table name */ 341 case 'S': 342 idname = argv[i++]; 343 break; 344 345 default: 346 usage(); 347 } 348 } 349 strcat (tfilname,tdname); /* Build temp filenames */ 350 strcat (tfilname,tfilbase); /* */ 351 /**************************/ 352 #ifdef UNIX /* For UNIX, Need to make */ 353 mktemp (tfilname); /* Unique file name */ 354 #endif /**************************/ 1File: MAIN.C Page 7 355 tfilptr = &tfilname[strlen(tfilname)-1]; /* -> changed char */ 356 #ifdef UNIX 357 tfilptr -= 6; /* Back off PID */ 358 #endif 359 360 strcat (initfnam,idname); /* Build Symbol table filename */ 361 strcat (initfnam,initbase); 362 363 if(i>=argc) usage(); 364 ifn=open(argv[i],0,0); /*open source file*/ 365 sfname = argv[i]; /* remember source filename */ 366 setldfn(argv[i]); /*create relocatable object file name*/ 367 lfn=openfi(ldfn,1); /*open loader file*/ 368 itfn = gettempf(); /*get a temp file for it*/ 369 itfnc = LASTCHTFN; /*remember last char for unlink*/ 370 trbfn = gettempf(); /*temp for text relocation bits*/ 371 trbfnc = LASTCHTFN; 372 dafn = gettempf(); /*temp for data binary*/ 373 dafnc = LASTCHTFN; 374 drbfn = gettempf(); /*temp for data relocation bits*/ 375 drbfnc = LASTCHTFN; 376 if(initflg) { /*initializing te main table*/ 377 lmte=bmte; /*beginning main table*/ 378 cszmt = SZMT; /*current size of main table*/ 379 for(i=0; i<=SZIRT-2; i=+2) { 380 sirt[i] = &sirt[i]; /*initialize the initial ref tables*/ 381 sirt[i+1] = 0; 382 oirt[i] = &oirt[i]; 383 oirt[i+1] = 0; 384 } 385 386 /*make entries in main table for directives*/ 387 mdemt("opd",0); /*opcode definition*/ 388 mdemt(endstr,1); /*end statement*/ 389 mdemt("data",2); /*dsect directive(code DATA based)*/ 390 mdemt("text",3); /*psect directive(code TEXT based)*/ 391 mdemt(equstr,4); /*equate*/ 392 mdemt("set",5); /*.set - same as .equ*/ 393 mdemt("dc",8); /*define byte*/ 394 mdemt("globl",9); /*define global (public) symbols*/ 395 mdemt("xdef",9); /*[vl]define global (public symbols*/ 396 mdemt("xref",9); /*[vl]define global (public) symbols*/ 397 mdemt("comm",10); /*define external symbols*/ 398 mdemt("bss",11); /*block storage based*/ 399 mdemt("ds",12); /*block storage based*/ 400 mdemt(evnstr,13); /*round pc*/ 401 mdemt(orgstr,14); /*internal org for *=n*/ 402 mdemt("org",14); /*[vlh]*/ 403 mdemt("mask2",15); /*[vl] assemble for mask2, ignore*/ 404 mdemt("reg",16); /*[vlh] register equate*/ 405 mdemt("dcb",17); /*[vlh] define block*/ 406 mdemt("comline",18); /*[vlh] command line*/ 407 mdemt("idnt",19); /*[vlh] relocateable id record, ignore*/ 408 mdemt("offset",20); /*[vlh] define offsets*/ 409 mdemt("section",21); /*[vlh] define sections*/ 410 mdemt("ifeq",22); /*[vlh] ca if expr = 0*/ 411 mdemt("ifne",23); /*[vlh] ca if expr != 0*/ 412 mdemt("iflt",24); /*[vlh] ca if expr < 0*/ 413 mdemt("ifle",25); /*[vlh] ca if expr <= 0*/ 1File: MAIN.C Page 8 414 mdemt("ifgt",26); /*[vlh] ca if expr > 0*/ 415 mdemt("ifge",27); /*[vlh] ca if expr >= 0*/ 416 mdemt("endc",28); /*[vlh] end ca*/ 417 mdemt("ifc",29); /*[vlh] ca if string compare*/ 418 mdemt("ifnc",30); /*[vlh] ca if not string compare*/ 419 mdemt("opt",31); /*[vlh] ignored, assemb options*/ 420 mdemt("ttl",31); /* Ignore title op also */ 421 mdemt("page",32); 422 423 } 424 else { /*not initializing*/ 425 getsymtab(); /*read initialized main table*/ 426 } 427 428 rlflg = TEXT; /*code initially TEXT based*/ 429 inoffset = 0; /*[vlh]not in offset mode*/ 430 loctr = 0; /*no generated code*/ 431 ca = 0; /*[vlh]depth of conditional assembly*/ 432 extindx = 0; /*no external symbols yet*/ 433 p2flg = 0; /*pass 1*/ 434 ca_true = 1; /*[vlh]true unless in side false case*/ 435 absln = 1; 436 sbuflen = -1; /*no source yet*/ 437 fchr = gchr(); /*get first char*/ 438 if(!initflg) { /*not initializing*/ 439 pack(orgstr,lmte); 440 orgptr = lemt(oirt,TRUE); 441 pack(endstr,lmte); 442 endptr = lemt(oirt,TRUE); 443 pack(equstr,lmte); 444 equptr = lemt(oirt,TRUE); 445 pack("add",lmte); 446 addptr = lemt(oirt,TRUE); 447 pack("addi",lmte); 448 addiptr = lemt(oirt,TRUE); 449 pack("addq",lmte); 450 addqptr = lemt(oirt,TRUE); 451 pack("sub",lmte); 452 subptr = lemt(oirt,TRUE); 453 pack("subi",lmte); 454 subiptr = lemt(oirt,TRUE); 455 pack("subq",lmte); 456 subqptr = lemt(oirt,TRUE); 457 pack("cmp",lmte); 458 cmpptr = lemt(oirt,TRUE); 459 pack("adda",lmte); 460 addaptr = lemt(oirt,TRUE); 461 pack("cmpa",lmte); 462 cmpaptr = lemt(oirt,TRUE); 463 pack("suba",lmte); 464 subaptr = lemt(oirt,TRUE); 465 pack("cmpm",lmte); 466 cmpmptr = lemt(oirt,TRUE); 467 pack("and",lmte); 468 andptr = lemt(oirt,TRUE); 469 pack("andi",lmte); 470 andiptr = lemt(oirt,TRUE); 471 pack("or",lmte); 472 orptr = lemt(oirt,TRUE); 1File: MAIN.C Page 9 473 pack("ori",lmte); 474 oriptr = lemt(oirt,TRUE); 475 pack("cmpi",lmte); 476 cmpiptr = lemt(oirt,TRUE); 477 pack("eor",lmte); 478 eorptr = lemt(oirt,TRUE); 479 pack("eori",lmte); 480 eoriptr = lemt(oirt,TRUE); 481 pack("move",lmte); 482 moveptr = lemt(oirt,TRUE); 483 pack("moveq",lmte); 484 moveqptr = lemt(oirt,TRUE); 485 pack("exg",lmte); 486 exgptr = lemt(oirt,TRUE); 487 pack("jsr",lmte); 488 jsrptr = lemt(oirt,TRUE); 489 pack("bsr",lmte); 490 bsrptr = lemt(oirt,TRUE); 491 pack("nop",lmte); 492 nopptr = lemt(oirt,TRUE); 493 pack(evnstr,lmte); 494 evenptr = lemt(oirt,TRUE); 495 } 496 mloop(); 497 } 498 499 usage() 500 { 501 rpterr("Usage: as68 [-p] [-u] [-l] [-n] [-f d:] [-s d:] sourcefile\n"); 502 endit(); 503 } 504 505 506 /*main loop*/ 507 mloop() 508 { 509 register i; 510 511 while(fchr!=EOF) { 512 if(absln>=brkln1) /*break for debugging the assembler*/ 513 i=0; 514 fcflg = 0; /*first time thru expr pass one*/ 515 cisit(); /*create it for one statement*/ 516 } 517 opcpt = endptr; 518 hend(); 519 } 520 521 #define NOCODE ((i>=0&&i<6)||i==9||i==11||i==16||(i>=LOW_CA&&i<=HI_CA)) 522 523 /*create intermediate text (it) for one statement*/ 524 /* call with first character of statement in fchr*/ 525 cisit() 526 { 527 528 register int *p1,*p2; 529 register int (*dirop)(); 530 register int i, col1; /*[vlh] col1 labels in col 1...*/ 531 char str[NAMELEN], *l; 1File: MAIN.C Page 10 532 533 ciss1: 534 immed[0] = immed[1] = indir[0] = indir[1] = numcon[0] = 0; 535 numcon[1] = numsym[0] = numsym[1] = numreg[0] = numreg[1]=0; 536 plevel = numops = opdix = explmode = 0; 537 cistop: 538 col1 = 1; 539 if(fchr==EOLC) { 540 fchr = gchr(); 541 goto cistop; 542 } 543 if(fchr==' ') { 544 col1 = 0; 545 igblk(); 546 if(fchr==EOLC) /*blank line*/ 547 goto cistop; 548 peekc = fchr; 549 if (fchr != EOF) fchr = ' '; /* [vlh] catch eof... */ 550 } 551 if(fchr==EOF) return; 552 553 if(fchr=='*') { /*ignore comments*/ 554 fchr = gchr(); 555 if(fchr=='=') { /*relocation counter assignment*/ 556 fchr = gchr(); /*pass the =*/ 557 horg(); /*output constants if not bss*/ 558 } 559 igrst(); 560 fcflg = 0; /*clear expr first time flag for next stmt*/ 561 goto ciss1; 562 } 563 564 /* get the opcode and label*/ 565 566 mode = 'w'; /*word mode*/ 567 igblk(); /*ignore blanks*/ 568 poslab = 1; 569 gterm(TRUE); 570 poslab = 0; 571 if(fchr==':' || fchr=='=') { /*there is a label*/ 572 label: 573 col1 = 0; 574 if(itype!=ITSY) { /*not a symbol*/ 575 uerr(2); 576 lbt[0] = 0; /*no label*/ 577 } 578 else { 579 p2 = &lmte->name[0]; 580 for(p1= &lbt[0]; p1 < &lbt[NAMELEN]; ) { 581 *p1++ = *p2++; 582 } 583 if(fchr==':') fchr=gchr(); /*ignore the colons*/ 584 } 585 labl1: 586 ligblk(); 587 if(fchr == EOF) return; 588 if(fchr == '*') { 589 igrst(); /*comment*/ 590 goto labl1; 1File: MAIN.C Page 11 591 } 592 gterm(TRUE); 593 if(fchr==':' || fchr=='=') { /*another label*/ 594 if(lbt[0]) { 595 savelab(); /*save current label*/ 596 dlabl(); /*define the last one*/ 597 pack(tlab1,lmte); /*restor the old lable*/ 598 } 599 goto label; 600 } 601 } 602 else { 603 lbt[0] = 0; /*no label*/ 604 } 605 igblk(); 606 if(fchr == '=') 607 goto label; 608 if(itype==ITSP) { 609 if(ival.wd2 == '=') { 610 hequ(); 611 return; 612 } 613 } 614 if(itype!=ITSY) { /*not valid opcode*/ 615 goto cisi3; 616 } 617 if (col1) { /* [vlh] could be a label save as is... */ 618 l = &str; 619 strcpy(l,lmte->name,NAMELEN); 620 } 621 if((opcpt=lemt(oirt,TRUE))==lmte) { /*not in opcode table*/ 622 if (col1) { /* [vlh] it's a label... */ 623 strcpy(lmte->name,l,NAMELEN); 624 goto label; 625 } 626 cisi3: 627 if (ca_true) /* [vlh] report error if not in CA false */ 628 xerr(3); 629 igrst(); 630 return; 631 } 632 getmode(); /*look for .b .w or .l mode flag*/ 633 if(opcpt->flags&OPDR) { /* its a directive*/ 634 i = opcpt->vl1; 635 if (!ca_true && (i < LOW_CA || i > HI_CA)) { igrst(); return; } 636 if (inoffset) /* [vlh] */ 637 if (!(NOCODE)) { /* can't generate code in offset */ 638 xerr(12); 639 return; 640 } 641 dirop = p1direct[i]; /*call routine to handle directive*/ 642 (*dirop)(); 643 return; 644 } 645 else if (!ca_true) { /* [vlh] */ 646 igrst(); 647 return; 648 } 649 else if (inoffset) { /* [vlh] */ 1File: MAIN.C Page 12 650 xerr(12); 651 return; 652 } 653 654 opcval = (opcpt->vl1); /*opcode*/ 655 format = (opcpt->flags&OPFF); /*format of this instr*/ 656 if (explmode) 657 if (!modeok()) { xerr(16); return; } 658 dlabl(); /*define label*/ 659 opitb(); /*beginning of statement*/ 660 if(format) 661 opito(); /*may have operands*/ 662 else 663 igrst(); /*only comments*/ 664 format = (opcpt->flags&OPFF); /* may have changed*/ 665 666 667 /*end of statement*/ 668 669 i = calcilen(); 670 stbuf[1].itrl = i; /*assumed instruction length*/ 671 672 stbuf[0].itrl = itwc; /*number of it entries*/ 673 wostb(); /*write out statement buffer*/ 674 loctr =+ i; 675 } 676 677 getmode() 678 { 679 if (fchr=='.') { 680 fchr = gchr(); 681 switch (fchr) { 682 case 'b': 683 case 'B': 684 case 's': 685 case 'S': 686 modelen = 1; 687 mode = BYTE; 688 break; 689 case 'w': 690 case 'W': 691 modelen = 2; 692 mode = WORD; 693 break; 694 case 'l': 695 case 'L': 696 modelen = 4; 697 mode = LONG; 698 break; 699 default: 700 peekc = fchr; 701 fchr = '.'; 702 goto getm1; 703 } 704 explmode++; 705 fchr = gchr(); 706 igblk(); 707 return; 708 } 1File: MAIN.C Page 13 709 getm1: 710 if(opcpt == exgptr) { /*length is long*/ 711 modelen = 4; 712 mode = LONG; 713 } 714 else { 715 mode = WORD; /*default is word*/ 716 modelen = 2; 717 } 718 } 719 720 /* check to be sure specified mode is legal */ 721 modeok() /* [vlh] */ 722 { 723 switch(format) { 724 case 0 : 725 case 14 : 726 case 18 : 727 return(FALSE); 728 case 13 : 729 case 15 : 730 case 20 : 731 case 21 : 732 return(modelen==1?FALSE:TRUE); 733 case 4 : 734 case 25 : 735 return(modelen==1?TRUE:FALSE); 736 case 7 : 737 case 9 : 738 return(modelen==2?FALSE:TRUE); 739 case 5 : 740 case 11 : 741 case 28 : 742 return(modelen==2?TRUE:FALSE); 743 case 6 : 744 return(modelen==4?FALSE:TRUE); 745 case 12 : 746 case 30 : 747 case 22 : 748 case 29 : 749 return(modelen==4?TRUE:FALSE); 750 default : 751 return(TRUE); 752 } 753 } 754 755 /* calculate the instruction length in bytes*/ 756 calcilen() 757 { 758 759 register i,j; 760 register long l; 761 register char *p; 762 763 i = 2; /*all instrs at least 2 bytes*/ 764 765 switch(format) { 766 767 case 20: 1File: MAIN.C Page 14 768 i =+ 2; /*for reg mask*/ 769 case 1: /*two ea's -- one of which may be a reg*/ 770 case 15: 771 case 30: 772 case 26: 773 case 5: 774 case 3: 775 case 21: 776 i =+ lenea(1); 777 case 16: 778 case 24: 779 case 25: 780 case 29: 781 i =+ lenea(0); 782 break; 783 784 case 9: /* [vlh] explicit jmp length... */ 785 if (!explmode) 786 i =+ lenea(0); 787 else 788 return(mode==LONG?6:4); /*[vlh] explicit jmp.? */ 789 break; 790 791 case 7: 792 i =+ (immed[0]) ? 2+lenea(1) : lenea(1); 793 break; 794 795 case 14: 796 case 11: 797 case 19: 798 i =+ 2; /*always 4 bytes*/ 799 break; 800 801 case 6: /*relative branches*/ 802 if(itwc == ITOP1+1) { 803 if(stbuf[ITOP1].itty == ITCN) 804 l = stbuf[ITOP1].itop; 805 else if(stbuf[ITOP1].itty == ITSY) { 806 p = stbuf[ITOP1].itop.ptrw2; 807 if(p->flags&SYDF) 808 l = p->vl1; /*symbol value*/ 809 else 810 goto loffst; 811 } 812 else { 813 goto loffst; 814 } 815 l =- (loctr+2); 816 if(l<=127 && l>=-128) /*8 bit offset*/ 817 break; 818 } 819 loffst: 820 if (!explmode || modelen > 1) /*[vlh] recognize br extensions*/ 821 i =+ 2; /*long offset for branches*/ 822 break; 823 824 case 2: 825 i =+ (mode==LONG?4:2) + lenea(1); 826 break; 1File: MAIN.C Page 15 827 828 case 23: 829 if(immed[0]) 830 i =+ (mode==LONG?4:2); 831 case 17: 832 case 22: 833 i =+ lenea(1); 834 break; 835 836 case 8: 837 if(numops==1) /*memory shift instruction*/ 838 i =+ shiftea(0); 839 break; 840 } 841 842 return(i); 843 } 844 845 /* calc the length of an effective address*/ 846 lenea(lidx) 847 { 848 register i; 849 850 if(immed[lidx]) 851 return(mode==LONG?4:2); 852 return(shiftea(lidx)); 853 } 854 855 shiftea(lidx) 856 { 857 if(indir[lidx]) 858 return((numcon[lidx] || numsym[lidx]) ? 2 : 0); 859 if(numsym[lidx] || numcon[lidx]) 860 return((!shortadr || numcon[lidx]==2) ? 4 : 2); 861 return(0); 862 } 863 864 /* 865 *define a label if there is one to define 866 * call with: 867 * label name in lbt if it exists 868 * else lbt[0] == 0 869 */ 870 dlabl() 871 { 872 register i; 873 874 if(lbt[0]) { /*got a label*/ 875 pack(lbt,lmte); /*put label in main table*/ 876 lblpt=lemt(sirt,FALSE); /*look up label*/ 877 if(lblpt != lmte) { /*symbol entered previously*/ 878 if(lbt[0] == '~') { /*local symbol -- may be duplicate*/ 879 lblpt = lmte; 880 mmte(); 881 } 882 else { 883 if(lblpt->flags&SYXR) { 884 uerr(29); 885 lblpt = 0; 1File: MAIN.C Page 16 886 return; 887 } 888 if((lblpt->flags)&SYDF) { 889 uerr(1); 890 lblpt = 0; 891 return; 892 } 893 } 894 } 895 else { 896 mmte(); /*make label entry in main table*/ 897 } 898 lblpt->flags =| SYDF; /*label is now defined*/ 899 lblpt->flags =| (rlflg==DATA)?SYRA:(rlflg==BSS)?SYBS:SYRO; 900 lblpt->vl1 = loctr; /*label value*/ 901 } 902 else 903 lblpt = 0; 904 } 905 906 /* 907 * output it for operands 908 * gets intput from gterm 909 * puts output in stbuf using itwc as an index 910 * itwc should point at the next entry to be made in stbuf 911 */ 912 opito() 913 { 914 register lopcomma; 915 916 lopcomma = symcon = chmvq = 0; 917 numops++; /*count first operand*/ 918 while(1) { 919 starmul = symcon; /*star is multiply op if flag is set*/ 920 if(fchr=='\'' || fchr=='"') 921 lopcomma = 0; 922 gterm(FALSE); /*get a term*/ 923 if(itwc==ITOP1 && format==CLRFOR && opcval==CLRVAL) 924 chgclr(); 925 opitoo(); /*output it for one operand*/ 926 if(itype==ITSP && ival.wd2==',') { 927 if (plevel==1 && !numcon[opdix]) /* [vlh] */ 928 numcon[opdix] = 1; 929 if(lopcomma) 930 uerr(30); 931 lopcomma++; 932 igblk(); /*ignore blanks for 68000 C compiler*/ 933 } 934 else 935 lopcomma=0; 936 if(ival==EOLC && itype==ITSP) /*end of operands*/ 937 break; 938 if(fchr==EOLC) { 939 fchr=gchr(); 940 break; 941 } 942 } 943 if(chmvq) /*changed move to moveq*/ 944 if(numops!=2 || immed[1] || indir[1] || numcon[1] || numsym[1] || 1File: MAIN.C Page 17 945 numreg[1]>=AREGLO) { 946 stbuf[2].itop.ptrw2 = moveptr; /*change it back*/ 947 opcpt = moveptr; 948 } 949 950 if (stbuf[2].itop.ptrw2==cmpptr) /* [vlh] cmp -> cmpm ?? */ 951 if (numreg[0] && numreg[1] && indir[0] && indir[1]) { 952 stbuf[2].itop.ptrw2 = cmpmptr; 953 opcpt = cmpmptr; 954 } 955 956 if(lopcomma) 957 uerr(30); 958 } 959 960 /* change clr.l An to suba.l An,An*/ 961 chgclr() 962 { 963 register char *p; 964 965 if(itype==ITSY) { /*first op is symbol*/ 966 p = lemt(sirt,FALSE); 967 if(p==lmte) 968 return; 969 if(!(p->flags&SYER) || p->vl1= STMAX) { /*it overflow*/ 1006 rpterr("i.t. overflow\n"); 1007 abort(); 1008 } 1009 pitw->itty = itype; /*type of it entry*/ 1010 1011 /*put symbol in it buffer*/ 1012 if(itype==ITSY) { 1013 sp=lemt(sirt,FALSE); /*look up it main table*/ 1014 pitw->itop.ptrw2 = sp; /*ptr to symbol entry*/ 1015 if(sp==lmte) /*first occurrance*/ 1016 mmte(); 1017 itwc++; /*count entries in it buffer*/ 1018 pitw++; 1019 if(!(sp->flags&SYER)) /*is it a register?*/ 1020 numsym[opdix]++; 1021 else /*yes, a register*/ 1022 numreg[opdix] = sp->vl1; 1023 return; 1024 } 1025 else if(itype == ITCN ) { 1026 if(ival.wd1 && ival.wd1 != -1) 1027 numcon[opdix] = 2; 1028 else if(!numcon[opdix]) 1029 numcon[opdix] = 1; 1030 if(numops == 1) 1031 tryquick(); 1032 } 1033 1034 /* special characters and constants*/ 1035 pitw->itop = ival; 1036 pitw->itrl = reloc; 1037 itwc++; 1038 pitw++; 1039 } 1040 1041 /* change add into addq and sub into subq if possible*/ 1042 tryquick() 1043 { 1044 register char *p; 1045 register long l; 1046 1047 if(fchr!=',' || !immed[0]) 1048 return; 1049 l = ival; 1050 if(itwc != ITOP1+1) { 1051 if(itwc!=ITOP1+2 || stbuf[ITOP1+1].itty!=ITSP || 1052 stbuf[ITOP1+1].itop.wd2 != '-') 1053 return; 1054 l = -l; 1055 } 1056 p = stbuf[2].itop.ptrw2; 1057 if(p==moveptr) { 1058 if(explmode && modelen != 4) /*dont change .w or .b*/ 1059 return; 1060 if(l>=-128 && l<=127) { 1061 stbuf[2].itop.ptrw2 = moveqptr; 1062 opcpt = moveqptr; 1File: MAIN.C Page 19 1063 chmvq++; 1064 } 1065 return; 1066 } 1067 if(l<=0 || l>8) { 1068 return; 1069 } 1070 if(p==addptr || p==addiptr) { 1071 stbuf[2].itop.ptrw2 = opcpt = addqptr; 1072 } 1073 else if(p==subptr || p==subiptr) { 1074 stbuf[2].itop.ptrw2 = opcpt = subqptr; 1075 } 1076 } 1077 1078 strcpy(str1, str2, len) 1079 register char *str1, *str2; 1080 register int len; 1081 { 1082 while (len--) 1083 *str1++ = *str2++; 1084 } 1085 1086 /* index - find the index of a character in a string*/ 1087 /* This is identical to Software Tools index.*/ 1088 index(str,chr) /* returns index of c in str or -1*/ 1089 char *str; /* pointer to string to search*/ 1090 char chr; /* character to search for*/ 1091 { 1092 register char *s; 1093 register int i; 1094 1095 for( s = str, i = 0; *s != '\0'; i++ ) 1096 if( *s++ == chr ) 1097 return(i); 1098 return(-1); 1099 } 1100