1File: MISC.C Page 1 1 /* 2 Copyright 1981 3 Alcyon Corporation 4 8716 Production Ave. 5 San Diego, Ca. 92121 6 */ 7 8 /* pass 2 miscellaneous routines */ 9 #include "as68.h" 10 int p2gi(); 11 12 long stlen; 13 int stdofd 1; 14 char tfilname[]; 15 int ins[], rlbits[], f2mode[]; 16 int udfct, ftudp, pline, prsp; 17 18 clrea(ap) 19 struct op *ap; 20 { 21 register struct op *p; 22 23 p = ap; 24 p->ea = p->len = p->xmod = p->drlc = 0; p->con = 0; 25 p->ext = p->idx = -1; 26 } 27 28 /* 29 * get one operand effective adddress (operand until , or EOS) 30 * returns: 31 * opnd[opn].ea set to effective address mode bits 32 * opnd[opn].len set to # bytes for operand 33 * opnd[opn].con set to constant part of ea 34 * opnd[opn].ext set to external symbol # if any 35 * opnd[opn].idx set to index register if any 36 * opnd[opn].drlc set to effective address relocation mode 37 * opnd[opn].xmod set to index register addressing mode (word or long) 38 */ 39 getea(opn) 40 { 41 register i,disp; 42 register struct op *p; 43 register int t; 44 45 p = &opnd[opn]; 46 disp = 0; 47 clrea(p); 48 if(ckitc(pitw,(int)'#')) { 49 p->len = (modelen==1) ? 2 : modelen; 50 p->ea = IMM; 51 pitw++; 52 goto dosimp; 53 } 54 if(ckitc(pitw,(int)'(')) { 55 geteal1: 56 pitw++; 57 if((i=getrgs()) == PC) { /*pc relative*/ 58 p->ea = 072; /*set mode & register bits*/ 59 p->len = 2; 1File: MISC.C Page 2 60 } 61 else { 62 if(i != -1) /*last was some type of register*/ 63 pitw--; /*havent used it yet*/ 64 if((i=getareg()) < 0) { /*not a reg # next*/ 65 if(disp || getreg()!=-1) { 66 uerr(14); /*illegal index reg*/ 67 return; 68 } 69 pitw--; 70 goto dosimp; /*must be expression in ()*/ 71 } 72 p->ea = i&7; /*put in a reg #*/ 73 } 74 if(ckitc(pitw,(int)',')) { /*must be index reg #*/ 75 do_ireg(p,i); 76 return; 77 } 78 ckrparen(); 79 if(i != PC) { 80 if(!disp && ckitc(pitw,(int)'+')) { 81 pitw++; 82 p->ea =| INDINC; 83 } 84 else if(disp) { /*indirect with displacement*/ 85 p->ea =| INDDISP; 86 p->len = 2; 87 } 88 else 89 p->ea =| INDIRECT; 90 } 91 ckeop(9+opn); 92 return; 93 } 94 if(ckitc(pitw,(int)'-')) { /*predecrement maybe*/ 95 pitw++; 96 if(ckitc(pitw,(int)'(')) { /*must be*/ 97 pitw++; 98 if((i = getareg()) < 0) { /*not valid a reg*/ 99 pitw =- 2; /*must be negative expr*/ 100 goto dosimp; 101 } 102 p->ea = i|DECIND; 103 ckrparen(); 104 ckeop(9+opn); 105 return; 106 } 107 pitw--; 108 } 109 dosimp: /*simple addr or imm expr*/ 110 if(i=gspreg()) { 111 t = ins[0]; 112 if(i==PC || (i==USP && t!=MOVE)) 113 uerr(20); 114 if(i==SR || i==CCR) { 115 if(t!=AND&&t!=OR&&t!=EOR&&t!=ANDI&&t!=ORI&&t!=EORI&&t!=MOVE) 116 uerr(20); 117 } 118 p->idx = i; 1File: MISC.C Page 3 119 ckeop(9+opn); 120 return; 121 } 122 if((i=getreg()) >= 0) { /*register direct*/ 123 p->ea = i; 124 if(modelen==1 && i>=AREGLO && i<=AREGHI) 125 uerr(20); 126 ckeop(9+opn); 127 return; 128 } 129 expr(&p2gi); 130 if(pitw < pnite) /*expr passes one token*/ 131 pitw--; 132 if(extflg) { 133 p->ext = extref; 134 extflg = 0; 135 } 136 p->con = ival; 137 p->drlc = reloc; /*relocation factor*/ 138 if(ckitc(pitw,(int)'(')) { 139 disp++; 140 goto geteal1; 141 } 142 if(!p->ea) { /*memory address*/ 143 if(shortadr && (!ival.wd1 || ival.wd1== -1)) { /*16-bit addrs*/ 144 p->ea = SADDR; 145 p->len = 2; 146 } 147 else { 148 p->ea = LADDR; 149 p->len = 4; 150 } 151 } 152 ckeop(9+opn); 153 } 154 155 do_ireg(p,i,opn) 156 struct op *p; 157 int i, opn; 158 { 159 pitw++; 160 p->idx = getreg(); 161 if(p->idx<0 || p->idx>AREGHI) 162 uerr(14); 163 p->len = 2; 164 if(!ckitc(pitw,')')) { 165 p->xmod = getrgs() - 20; 166 if(p->xmod<0 || p->xmod>1) { 167 uerr(34); 168 p->xmod = 0; 169 } 170 } 171 ckrparen(); 172 ckeop(9+opn); 173 if(i==PC) 174 p->ea =+ 1; 175 else 176 p->ea =| INDINX; 177 } 1File: MISC.C Page 4 178 179 /* 180 * get an A register specification 181 * call with: 182 * pitw pointing to reg operand 183 * returns: 184 * -1 if not vaid A reg 185 * A reg # if valid 186 * also updates pitw if valid 187 */ 188 getareg() 189 { 190 register i; 191 192 i = getreg(); 193 if(i>=AREGLO && i<=AREGHI) { 194 return(i&7); 195 } 196 else { 197 if(i != -1) 198 pitw--; 199 return(-1); 200 } 201 } 202 203 /* 204 * get any register specification 205 * call with : 206 * pitw pointing at operand 207 * returns: 208 * register # with pitw updated 209 * -1 if not valid register 210 */ 211 getreg() 212 { 213 register i; 214 215 i = getrgs(); 216 if(i>=0 && i<=AREGHI) 217 return(i); 218 else { 219 if(i != -1) 220 pitw--; 221 return(-1); 222 } 223 } 224 225 /*get any register specification*/ 226 getrgs() 227 { 228 register char *i; 229 230 if(pitw->itty == ITSY) { 231 i = pitw->itop.ptrw2; /*symbol ptr*/ 232 if(i->flags&SYER) { 233 pitw++; 234 return((int)i->vl1.wd2); /*register #*/ 235 } 236 } 1File: MISC.C Page 5 237 return(-1); 238 } 239 240 /* check for a right paren as the next char*/ 241 /* output error msg if not found*/ 242 ckrparen() 243 { 244 if(ckitc(pitw,(int)')')) /*found it*/ 245 pitw++; 246 else 247 uerr(32); 248 } 249 250 /* 251 * check intermedate text item for special character 252 * call with: 253 * pointer to desired item in stbuf 254 * character to check for 255 * returns: 256 * 0 => no match 257 * 1 => match 258 */ 259 ckitc(ckpt,cksc) 260 char *ckpt; 261 { 262 if(ckpt >= pnite || ckpt->itty != ITSP || ckpt->itop.wd2 != cksc) 263 return(0); 264 return(1); 265 } 266 267 /* 268 * read intermediate text for one statement 269 * returns: 270 * intermediate text in stbuf 271 */ 272 ristb() 273 { 274 register riix; 275 register short *pi; 276 register int i; 277 278 do { 279 riix = stbuf[0].itrl; 280 pi = &stbuf[0]; 281 for(i=0; i<(sizeof stbuf[0])/(sizeof *pi); i++) { 282 *pi++ = doitrd(); 283 } 284 if(stbuf[0].itty != ITBS) { /*best be beginning of statement */ 285 printf("it sync error itty=%x\n",stbuf[0].itty); 286 if( stbuf[0].itty == 0) 287 return(0); 288 abort(); 289 } 290 291 /* get the rest of the statement it*/ 292 riix = stbuf[0].itrl & 0377; /*unsigned byte*/ 293 riix--; /*already got first entry*/ 294 while(riix--) { 295 for(i=0; i<(sizeof stbuf[0])/(sizeof *pi); i++) { 1File: MISC.C Page 6 296 *pi++ = doitrd(); 297 } 298 } 299 } while(stbuf[1].itrl == -1); /* eliminated instr, read next one */ 300 return(1); 301 } 302 303 int errno; 304 int nitleft; /* # of shorts left in itbuf */ 305 306 doitrd() 307 { 308 register short i; 309 310 if(pitix < itbuf || pitix > &itbuf[ITBSZ]) { 311 printf("doitrd: buffer botch pitix=%lx itbuf=%lx end=%lx\n", 312 pitix,itbuf,&itbuf[ITBSZ]); 313 endit(); 314 } 315 316 if(nitleft <= 0) 317 { 318 pitix = itbuf; 319 if((i=read(itfn,itbuf,sizeof itbuf)) != sizeof itbuf) { 320 fprintf(stderr,"it read error i=%d errno=%o itoffset=%ld\n", 321 i,errno,itoffset); 322 abort(); 323 } 324 nitleft = ITBSZ; 325 } 326 i = *pitix; 327 nitleft--; 328 itoffset += sizeof *pitix; 329 pitix++; 330 return(i); 331 } 332 333 /* 334 * check for end of operand 335 * call with 336 * error number if this is not end of operand 337 */ 338 ckeop(uen) 339 { 340 if(pitw>=pnite) /*end of all operands*/ 341 return(1); 342 if(!ckitc(pitw,(int)',')) { /*not end of stmt must be op,op*/ 343 uerr(uen); 344 return(0); 345 } 346 return(1); 347 } 348 349 /* output symbol table to file*/ 350 osymt() 351 { 352 register char **sx1; 353 register char *p; 354 register i; 1File: MISC.C Page 7 355 register j; 356 int symcmp(); 357 stlen = 0; 358 if(extindx) { /*output external symbols first*/ 359 sx1 = extbl; 360 for(i=0;iflags&(SYXR|SYIN)) 366 continue; 367 osyme(p); 368 } 369 if(prtflg) 370 { 371 xline = LPP; 372 page(); /* Pop to next Page */ 373 printf("S y m b o l T a b l e\n\n"); 374 xline++; /* Bump Line count */ 375 j = ((lmte-bmte)/STESIZE); /* # elements */ 376 qsort(bmte,j,STESIZE,symcmp); /* Sort the symbols 1st */ 377 j = 0; /* Now count symbols / line*/ 378 for(p=bmte; p 3) 381 { 382 printf("\n"); 383 page(); 384 j = 0; 385 } 386 j += psyme(p); 387 } 388 } 389 } 390 symcmp(a,b) 391 register char *a; 392 register char *b; 393 { 394 return(strncmp(a,b,NAMELEN)); 395 } 396 /* make all undefined symbols external*/ 397 fixunds() 398 { 399 register char **sx1, **sx2; 400 401 /* loop thru symbol initial reference table*/ 402 for(sx1= sirt; sx1<&sirt[SZIRT-1]; sx1 =+ 2) { 403 if(*(sx2 = sx1+1)==0) /* this chain is empty*/ 404 continue; 405 406 /* symbols on one chain*/ 407 sx2 = *sx2; /*first entry on this chain*/ 408 while(1) { 409 if(!(sx2->flags&SYDF)) { /*not defined*/ 410 if(undflg || sx2->flags&SYGL) { /*all or globals*/ 411 sx2->flags = sx2->flags|SYDF|SYXR; 412 mkextidx(sx2); 413 } 1File: MISC.C Page 8 414 } 415 if(sx2 == *sx1) /*end of chain*/ 416 break; 417 sx2 = sx2->tlnk; /*next entry in chain*/ 418 } 419 } 420 } 421 422 /* 423 * output symbols in a form to be read by a debugger 424 * call with pointer to symbol table entry 425 * prints all undefined symbols 426 */ 427 osyme(aosypt) 428 struct symtab *aosypt; 429 { 430 register struct symtab *osypt; 431 register char *p1; 432 register int i; 433 register short *ps1; 434 435 osypt = aosypt; /*pointer to symbol table entry*/ 436 if(!prtflg && !(osypt->flags&SYDF)) { /*undefined symbol*/ 437 pudfs(osypt); /*print undefined*/ 438 return; 439 } 440 441 442 stlen =+ 14; /*one more symbol out*/ 443 444 /*output symbol to loader file*/ 445 ps1 = &(osypt->name[0]); 446 for(i=0; iflags,&lbuf); /* output symbol flags */ 451 if(osypt->flags&SYXR) { /*external symbol*/ 452 #ifndef PDP11 453 putw(0,&lbuf); 454 putw(osypt->vl1.wd1,&lbuf); 455 #else /* Only for PDP-11 UNIX */ 456 putw(osypt->vl1.wd1,&lbuf); 457 putw(0,&lbuf); 458 #endif 459 } 460 else { 461 #ifndef PDP11 /* 68K and vax only */ 462 putw(osypt->vl1.wd1,&lbuf); /*upper half symbol value*/ 463 putw(osypt->vl1.wd2,&lbuf); /*lower symbol value*/ 464 #else /* PDP-11 ONLY!!!!! */ 465 putw(osypt->vl1.wd2,&lbuf); /* Upper half of value */ 466 putw(osypt->vl1.wd1,&lbuf); /* lower half */ 467 #endif 468 } 469 } 470 471 /* 472 * print undefined symbols 1File: MISC.C Page 9 473 * call with 474 * pointer to undefined symbol 475 */ 476 pudfs(udspt) 477 struct symtab *udspt; 478 { 479 nerror++; 480 if(!ftudp) { /*first time thru*/ 481 if(xline > (LPP-10)) xline = LPP; 482 page(); 483 printf("\n&& UNDEFINED SYMBOLS &&\n"); 484 xline++; 485 ftudp++; 486 udfct=0; /*no symbols on this line*/ 487 } 488 489 printf("%8s ",&(udspt->name[0])); 490 if(udfct++ > 6) { 491 printf("\n"); 492 udfct=0; 493 } 494 } 495 496 psyme(osypt) 497 register struct symtab *osypt; 498 { 499 register char *p1; 500 501 if(((osypt->flags & SYER) != 0) || (osypt->flags&SYIN)) 502 return(0); 503 504 p1 = &(osypt->name[0]); 505 while(p1 < &osypt->name[NAMELEN]) 506 { 507 if(*p1) 508 putchar(*p1); 509 else 510 putchar(' '); 511 p1++; 512 } 513 printf(" "); 514 if(osypt->flags&SYXR) 515 { 516 printf("******** EXT "); 517 return(1); 518 } 519 520 if(osypt->flags&SYDF) 521 { 522 523 puthex(osypt->vl1.wd1,4); 524 puthex(osypt->vl1.wd2,4); 525 if(osypt->flags&SYRA) /*print relocation factor*/ 526 printf(" DATA "); 527 else if(osypt->flags&SYRO) 528 printf(" TEXT "); 529 else if(osypt->flags&SYBS) 530 printf(" BSS "); 531 else printf(" ABS "); 1File: MISC.C Page 10 532 } 533 534 else 535 { 536 nerror++; 537 printf("*UNDEFINED* "); 538 } 539 return(1); 540 } 541 542 543 /* 544 * output source and object listing 545 * call with 546 * 2 => print address and binary code only 547 * 1 => object in ins[] and instr type in format 548 * 0 => print address only 549 */ 550 print(pflag) 551 { 552 register i,j; 553 register int *pi; 554 555 if( !prtflg ) return; /*no printing desired*/ 556 if(fchr==EOF) return; /*end of source file*/ 557 558 i = instrlen; instrlen = 1; /*to print preceeding lines*/ 559 while(plinep2absln || pflag==2) { 593 putchar('\n'); /*end of line*/ 594 } 595 else { 596 prtline(0); 597 if(fchr==EOF) return; 598 putchar('\n'); 599 fchr=gchr(); 600 pline++; 601 } 602 } 603 #ifdef BLIVOT /* This was so horrible ... */ 604 /*print one line aligning source output*/ 605 prtline(flg) 606 { 607 register i; 608 register col, blcnt; 609 610 if(fchr=='*' || flg) { /*comment*/ 611 while(fchr!=EOLC && fchr!=EOF) { 612 putchar(fchr); 613 fchr = gchr(); 614 } 615 return; 616 } 617 col = 1; 618 blcnt = 0; 619 while(1) { 620 if(fchr==EOLC || fchr==EOF) 621 return; 622 if(fchr==' '&& blcnt<3) { 623 i= (++blcnt == 3) ? 017 : 7; 624 while(col&i) { 625 putchar(' '); 626 col++; 627 } 628 while(fchr==' ') 629 fchr=gchr(); 630 if(fchr==EOLC || fchr==EOF) 631 return; 632 } 633 putchar(fchr); 634 fchr=gchr(); 635 col++; 636 } 637 } 638 #else 639 prtline(flg) /* What you see in the editor is what you get on the listing*/ 640 { 641 while(fchr != EOLC && fchr != EOF) 642 { 643 putchar(fchr); 644 fchr = gchr(); 645 } 646 } 647 #endif 648 /* 649 * Heading print routine 1File: MISC.C Page 12 650 */ 651 page() 652 { 653 if((prtflg == 0) || (++xline < LPP)) return; 654 printf("\014C P / M 6 8 0 0 0 A s s e m b l e r\t\t%s\t\tPage%4d\n", 655 "Revision 02.03",++xpage); 656 printf("Source File: %s\n\n",sfname); 657 xline = 3; 658 } 659 660 661 int hibytflg[4], hibytw[4]; 662 663 outbyte(bv,br) 664 { 665 if(hibytflg[rlflg]) { 666 outword(hibytw[rlflg]|(bv&0xff),br); 667 hibytflg[rlflg] = 0; 668 } 669 else { 670 hibytw[rlflg] = bv<<8; 671 hibytflg[rlflg]++; 672 } 673 } 674 675 outword(val,rb) 676 { 677 switch(rlflg) { 678 679 case TEXT: 680 putw(val,&lbuf); 681 putw(rb,&tbuf); 682 break; 683 684 case DATA: 685 putw(val,&dabuf); 686 putw(rb,&drbuf); 687 break; 688 689 case BSS: 690 uerr(39); 691 break; 692 693 default: 694 rpterr("& outword: bad rlflg\n"); 695 abort(); 696 } 697 } 698 699 outinstr() 700 { 701 register i; 702 register int *p1, *p2; 703 704 i = instrlen>>1; 705 p1 = ins; 706 p2 = rlbits; 707 while(i--) { 708 outword(*p1++, *p2++); 1File: MISC.C Page 13 709 } 710 } 711 712 /* copy data bits from temporary file to loader file*/ 713 cpdata() 714 { 715 myfflush(&lbuf); 716 myfflush(&dabuf); 717 docp(dafn,dafnc,savelc[DATA]); 718 } 719 720 /* copy text then data relocation bits from temporary file to loader file*/ 721 cprlbits() 722 { 723 myfflush(&lbuf); 724 myfflush(&drbuf); 725 docp(trbfn, trbfnc,savelc[TEXT]); 726 docp(drbfn, drbfnc,savelc[DATA]); 727 } 728 729 /* 730 * copy one of the temporary files to the loader file 731 * call with: 732 * file descriptor of the temporary file 733 * last char of the temporary file name 734 * length to copy 735 */ 736 docp(cfn,cfnc,length) 737 long length; 738 { 739 register i; 740 register j; 741 close(cfn); 742 LASTCHTFN = cfnc; 743 cfn = openfi(tfilname,0); 744 /* while((i=read(cfn,itbuf,512)) > 0) { */ 745 while(length > 0) 746 { 747 if(length > 512) 748 j = 512; 749 else 750 j = length; 751 752 if((i=read(cfn,itbuf,j)) != j) 753 { 754 printf("& Read Error On Intermediate File: %s\n", 755 tfilname); 756 abort(); 757 } 758 759 if(write(lfn,itbuf,i) != i) { 760 rpterr("& Object file write error\n"); 761 abort(); 762 } 763 length -= j; 764 } 765 } 766 767 /* print one word in hex*/ 1File: MISC.C Page 14 768 puthex(v,l) 769 { 770 register i,j,k; 771 772 j = 12; 773 for(i=0; i>j)&017; 775 k =+ (k >= 10) ? ('A'-10) : '0'; 776 putchar(k); 777 j =- 4; 778 } 779 } 780 781 /* check for a control operand*/ 782 controlea(ap) 783 struct op *ap; 784 { 785 register i; 786 787 i = ap->ea&070; 788 if(i==INDIRECT || i==INDDISP || i==INDINX) 789 return(1); 790 if(i==070) { 791 if((ap->ea&7) <= 3) 792 return(1); 793 } 794 return(0); 795 } 796 797 ckcomma() 798 { 799 if(ckitc(pitw,',')) { /*next token a comma*/ 800 pitw++; 801 return(1); 802 } 803 return(0); 804 } 805 806 /* 807 * generate any necessary additional words for the effective address 808 * call with: 809 * pins pointing to next available word in ins[] 810 * prlb pointing to next available word in rlbits[] 811 * argument is ptr to op structure 812 * 813 * returns: 814 * appropriate words in ins[] and rlbits[] for operand 815 * pins and prlb updated. 816 */ 817 doea(apea) 818 struct op *apea; 819 { 820 register i,j; 821 register struct op *p; 822 823 p = apea; 824 switch((p->ea>>3)&7) { /* ea mode bits*/ 825 826 default: /*no more words*/ 1File: MISC.C Page 15 827 return; 828 829 case 5: /* d(An)*/ 830 dodisp(p); 831 return; 832 833 case 6: /* d(An,Ri)*/ 834 dindx: 835 if (p->con > 127L || p->con < -128L) { 836 uerr(35); 837 } 838 i = (p->con.wd2&0377) | (p->idx<<12) | (p->xmod<<11); 839 if(p->drlc != ABS) 840 uerr(27); 841 *pins++ = i; 842 *prlb++ = DABS; 843 instrlen =+ 2; 844 return; 845 846 case 7: /*xxx.W, xxx.L, or #xxx*/ 847 switch(p->ea&7) { 848 849 case 1: /* xxx.L*/ 850 doupper(p); 851 p->con.wd1 = 0; /*clear for dodisp check*/ 852 853 case 0: /* xxx.W*/ 854 dodisp(p); 855 return; 856 857 case 2: /*d(PC)*/ 858 case 3: /*d(PC,Ri.X)*/ 859 if(p->drlc != ABS) { 860 if(p->drlc != rlflg) /*not same reloc base*/ 861 uerr(27); 862 p->con =- (loctr+instrlen); 863 p->drlc = ABS; 864 } 865 if((p->ea&7) == 3) /*d(PC,Ri.X)*/ 866 goto dindx; 867 dodisp(p); 868 return; 869 870 case 4: /* #xxx*/ 871 chkimm(p); /*check for valid length*/ 872 if(modelen == 4) { /*instr mode is long*/ 873 doupper(p); 874 p->con.wd1 = 0; /*clear for dodisp check*/ 875 } 876 dodisp(p); 877 return; 878 } 879 } 880 } 881 882 dodisp(ap) 883 struct op *ap; 884 { 885 register struct op *p; 1File: MISC.C Page 16 886 887 p = ap; 888 *pins++ = p->con.wd2; /*displacement*/ 889 if(p->con.wd1 && p->con.wd1 != -1) 890 uerr(41); /*invalid 16-bit disp*/ 891 *prlb++ = (p->ext != -1) ? (p->ext<<3)|EXTVAR : p->drlc; 892 instrlen =+ 2; 893 } 894 895 doupper(p) 896 struct op *p; 897 { 898 *pins++ = p->con.wd1; /*upper half of long addr or constant*/ 899 *prlb++ = LUPPER; 900 instrlen =+ 2; 901 } 902 903 /* 904 * build a format 1 (add, sub, and, etc) instr 905 * call with: 906 * register # 907 * mode bits 908 * ptr to operand structure for effective address 909 */ 910 makef1(arreg, armode, apea) 911 struct op *apea; 912 { 913 register i,j; 914 register struct op *p; 915 916 p = apea; 917 ins[0] =| (arreg<<9); /*put in reg #*/ 918 ins[0] =| armode; /*instr mode bits*/ 919 ins[0] =| p->ea; /*put in effective addr bits*/ 920 doea(p); /*may be more words in ea*/ 921 } 922 923 /* generate an immediate instr*/ 924 genimm() 925 { 926 ins[0] =| (f2mode[modelen] | opnd[1].ea); 927 if(modelen == 4) { 928 doupper(&opnd[0]); 929 opnd[0].con.wd1 = 0; /*clear for dodisp check*/ 930 } 931 chkimm(&opnd[0]); /*check for valid immed length*/ 932 dodisp(&opnd[0]); 933 doea(&opnd[1]); 934 } 935 936 chkimm(ap) 937 struct op *ap; 938 { 939 register struct op *p; 940 941 p=ap; 942 if(modelen == 2) { /*word*/ 943 if(p->con.wd1 && p->con.wd1!=-1) 944 uerr(42); 1File: MISC.C Page 17 945 } 946 else if(modelen == 1) { /*byte*/ 947 if(p->con.wd1 && p->con.wd1!=-1) 948 uerr(43); 949 if(p->con.wd2>255 || p->con.wd2<=-256) 950 uerr(43); 951 } 952 } 953 954 /* try to make a normal instr into an immediate instr*/ 955 makeimm() 956 { 957 if(opnd[0].ea != IMM) 958 return(0); 959 if(!dataalt(&opnd[1])) 960 return(0); 961 if(opcpt == addptr) 962 opcpt = addiptr; 963 else if(opcpt == andptr) 964 opcpt = andiptr; 965 else if(opcpt == orptr) 966 opcpt = oriptr; 967 else if(opcpt == subptr) 968 opcpt = subiptr; 969 else if(opcpt == cmpptr) 970 opcpt = cmpiptr; 971 else if(opcpt == eorptr) 972 opcpt = eoriptr; 973 else 974 return(0); 975 ins[0] = opcpt->vl1.wd2; 976 format = (opcpt->flags)&OPFF; 977 genimm(); 978 return(1); 979 } 980 981 ckbytea() 982 { 983 if(modelen==1 && !dataea(&opnd[0])) 984 uerr(20); /*byte mod not allowed*/ 985 } 986 987 /* get a special register token (CCR, SR, or USP)*/ 988 gspreg() 989 { 990 register i; 991 992 i = getrgs(); 993 if(i>AREGHI) 994 return(i); 995 if(i != -1) 996 pitw--; 997 return(0); 998 } 999 1000 /* 1001 * check an operand for a special register 1002 * call with: 1003 * ptr to operand struct 1File: MISC.C Page 18 1004 * special register value 1005 */ 1006 cksprg(ap,v1) 1007 struct op *ap; 1008 { 1009 if(ap->ea) 1010 return(0); 1011 if(ap->idx == v1) 1012 return(1); 1013 return(0); 1014 } 1015 1016 /* check for operand as any special register*/ 1017 anysprg(ap) 1018 struct op *ap; 1019 { 1020 if(ap->ea) 1021 return(0); 1022 if(ap->idx>=CCR && ap->idx<=USP) 1023 return(1); 1024 return(0); 1025 } 1026 1027 /* copy opnd 0 to opnd 1*/ 1028 cpop01() 1029 { 1030 opnd[1].ea = opnd[0].ea; 1031 opnd[1].len = opnd[0].len; 1032 opnd[1].con = opnd[0].con; 1033 opnd[1].drlc = opnd[0].drlc; 1034 opnd[1].ext = opnd[0].ext; 1035 opnd[1].idx = opnd[0].idx; 1036 opnd[1].xmod = opnd[0].xmod; 1037 } 1038 1039 cksize(ap) /* [vlh] try to check displacement range */ 1040 struct op *ap; 1041 { 1042 long value; 1043 1044 if ((ap->ea&070) != 070) return; 1045 value = (ap->con>0 && ap->con&0100000) ? -(ap->con&~0100000) : ap->con; 1046 if (modelen == 1) { 1047 if (value < -128L || value > 127L) /* 8 bits */ 1048 uerr(35); 1049 } 1050 else if (modelen == 2) 1051 if (value > 32767L || value < -32768L) /* 16 bits */ 1052 uerr(41); 1053 } 1054 1055 ccr_or_sr() /* [vlh] */ 1056 { 1057 if(opnd[1].idx==CCR) 1058 modelen = 1; /*byte mode only*/ 1059 else /* [vlh] SR */ 1060 if (modelen != 2) { 1061 modelen = 2; 1062 uerr(34); 1File: MISC.C Page 19 1063 } 1064 cksize(&opnd[0]); 1065 ins[0] =| IMM | f2mode[modelen]; 1066 dodisp(&opnd[0]); 1067 } 1068 1069 get2ops() 1070 { 1071 getea(0); /*get first effective address*/ 1072 if(!ckcomma()) { 1073 uerr(10); 1074 return(1); /*no second op*/ 1075 } 1076 getea(1); /*get second effective address*/ 1077 return(0); 1078 }