home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / dev / cross / tms32010 / x320.c < prev   
C/C++ Source or Header  |  1992-09-02  |  16KB  |  680 lines

  1. /* TMS320 Cross Assembler release 1.0 */
  2.  
  3. #include <libraries/dosextens.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7.  
  8. /* mnemonic table definition */
  9.  
  10. char    *mntable[]=    {
  11.                 "ABS", "ADD", "ADDH", "ADDS", "AND", "AORG","APAC",
  12.                 "B", "BANZ", "BGEZ", "BGZ", "BIOZ","BLEZ",
  13.                 "BLZ", "BNZ", "BV", "BZ", "CALA", "CALL", "DATA",
  14.                 "DINT", "DMOV", "EINT", "END", "EQU", "IN", "LAC",
  15.                 "LACK", "LAR", "LARK", "LARP", "LDP", "LDPK", "LST",
  16.                 "LT",  "LTA", "LTD", "MAR", "MPY", "MPYK",
  17.                 "NOP", "OR", "OUT", "PAC", "POP", "PUSH",
  18.                 "RET", "ROVM", "SACH", "SACL", "SAR", "SOVM",
  19.                 "SPAC", "SST", "SUB", "SUBC", "SUBH", "SUBS",
  20.                 "TBLR", "TBLW", "XOR", "ZAC", "ZALH", "ZALS"
  21.             };
  22.  
  23. /* instruction type table definition */
  24.  
  25. unsigned char    tytable[]=    {
  26.                     0, 9, 5, 5, 5, 14, 0, 10, 10, 10, 10,
  27.                     10, 10, 10, 10, 10, 10, 0, 10, 11, 0, 5,
  28.                     0, 15, 13, 8, 9, 2, 6, 3, 1, 5, 1, 5,
  29.                     5, 5, 5, 5, 5, 4, 0, 5, 8, 0,
  30.                     0, 0, 0, 0, 7, 5, 6, 0, 0, 5,
  31.                     9, 5, 5, 5, 5, 5, 5, 0, 5, 5
  32.                 };
  33.  
  34. /* opcode table definition */
  35.  
  36. unsigned short    optable[]=    {
  37.                     0x7F88, 0x0000, 0x6000, 0x6100, 0x7900, 0, 0x7F8F,
  38.                     0xF900, 0xF400, 0xFD00, 0xFC00, 0xF600, 0xFB00,
  39.                     0xFA00, 0xFE00, 0xF500, 0xFF00, 0x7F8C, 0xF800, 0,
  40.                     0x7F81, 0x6900, 0x7F82, 0, 0, 0x4000, 0x2000, 0x7E00,
  41.                     0x3800, 0x7000, 0x6880, 0x6F00, 0x6E00, 0x7B00,
  42.                     0x6A00, 0x6C00, 0x6B00, 0x6800, 0x6D00, 0x8000,
  43.                     0x7F80, 0x7A00, 0x4800, 0x7F8E, 0x7F9D, 0x7F9C,
  44.                     0x7F8D, 0x7F8A, 0x5800, 0x5000, 0x3000, 0x7F8B,
  45.                     0x7F90, 0x7C00, 0x1000, 0x6400, 0x6200, 0x6300,
  46.                     0x6700, 0x7D00, 0x7800, 0x7F89, 0x6500, 0x6600
  47.                 };
  48.  
  49. /* Predefined labels definition */
  50.  
  51. char *pdlab[]= {
  52.             "AR0", "AR1", "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7"
  53.         };
  54.         
  55. unsigned long pdadd[]=    {
  56.                 0, 1, 0, 1, 2, 3, 4, 5, 6, 7
  57.             };
  58.  
  59. /* opcode info structure definition */
  60.  
  61. struct    OpInfo    {
  62.             unsigned char Type;
  63.             unsigned short OpCode;
  64.         };
  65.  
  66. /* label table structure definition */
  67.  
  68. struct    LabTab    {
  69.             char Label[10];
  70.             unsigned long Address;
  71.         };
  72.  
  73. /* functions declaration */
  74.  
  75. void Copyright(void);
  76. char *getword(char *);
  77. void incpc(void);
  78. long getnum(char *);
  79. char *getop(char *);
  80.  
  81. /* constants declaration */
  82.  
  83. #define MAXBUF 128
  84. #define LINEBUF 256
  85. #define TABLEN 64
  86. #define MAXLAB 256
  87. #define PDLABS 10
  88.  
  89. /* variables declaration */
  90.  
  91. struct OpInfo *opinfo;
  92. struct LabTab labtab[MAXLAB];
  93. char filein[MAXBUF], fileout[MAXBUF], linebuf[LINEBUF], auxbuf[LINEBUF];
  94. char *labptr[MAXLAB], *pointer;
  95. unsigned short indx;
  96. FILE *fi, *fo;
  97. unsigned long PC;
  98. long value;
  99. int Ops;
  100.  
  101. main(argc, argv)
  102.  
  103. int argc;
  104. char *argv[];
  105.  
  106. {
  107.  
  108. char c;
  109. int i=1, j, lineno;
  110. struct LabTab auxlab;
  111. long word;
  112. BOOL xref=FALSE, link=FALSE;
  113.  
  114.     Copyright();
  115.     if(argc==1) {
  116. badusage:    printf("Usage: %s [-xL] filename [filename]\n",argv[0]);
  117.         puts("\tx: generates cross reference listing to stdout.");
  118.         puts("\tL: calls L320 after assembly, linking to hex.");
  119.         exit(1);
  120.     }
  121.     if(*argv[i]=='-') {
  122.         for(j=0;j<strlen(argv[i]++);j++)
  123.             switch(*argv[i]) {
  124.                 case 'L':
  125.                     link=TRUE;
  126.                     break;
  127.                 case 'x':
  128.                     xref=TRUE;
  129.                     break;
  130.                 default:
  131.                     goto badusage;
  132.             }
  133.         i++;
  134.         argc--;
  135.     }
  136.     if(!(--argc))
  137.         goto badusage;
  138.     strcpy(filein,argv[i]);
  139.     strcpy(fileout,filein);
  140.     if(--argc)
  141.         strcpy(fileout,argv[++i]);
  142.     strcat(fileout,".obj");
  143.     if(!(fi=fopen(filein,"r"))) {
  144.         printf("Can't open file %s for input\n",filein);
  145.         exit(1);
  146.     }
  147.     if(!(fo=fopen(fileout,"w"))) {
  148.         printf("Can't open file %s for output\n",fileout);
  149.         fclose(fi);
  150.         exit(1);
  151.     }
  152.     
  153. /* Predefined labels storage */
  154.     
  155.     for(indx=0;indx<PDLABS;indx++) {
  156.         strcpy(labtab[indx].Label,pdlab[indx]);
  157.         labtab[indx].Address=pdadd[indx];
  158.     }
  159.  
  160. /* Start first pass */
  161.  
  162.     PC=0;
  163.     lineno=0;
  164.     while(fgets(linebuf,sizeof(linebuf),fi)) {
  165.         pointer=linebuf;
  166.         lineno++;
  167.         auxbuf[0]=0;
  168.         strtok(linebuf,";");        /* strip out comments */
  169.         if(!(isseppp(linebuf[0]))) {        /* label found */
  170.             strcpy(auxbuf,linebuf);
  171.             for(i=0;(i<(LINEBUF-1))&&(!(issep(linebuf[i])));i++,pointer++);
  172.             auxbuf[i]=0;
  173.             if(!(i=stlabel(auxbuf))) {
  174.                 printf("*** LABEL ALREADY DEFINED *** at line %d :%s\nLabel: %s\n",lineno,linebuf,auxbuf);
  175.                 goto error;
  176.             }
  177.             if(i==-1) {
  178.                 printf("*** OUT OF SYMBOL SPACE *** at line %d :%s\nLabel: %s\n",lineno,linebuf,auxbuf);
  179.                 goto error;
  180.             }
  181.         }
  182.         if(pointer=getword(pointer)) {
  183.             if((i=findopc(pointer))==-1) {  /* not an opcode */
  184. synterr:            printf("*** SYNTAX ERROR *** at line %d :%s\nUnknown mnemonic: %s\n",lineno,linebuf,pointer);
  185.                 goto error;
  186.             }
  187.             switch(opinfo->Type) { 
  188.                 case 14:        /* handle AORG directive */
  189.                     if(Ops!=1)
  190.                         goto synterr2;
  191.                     if(!(eval(pointer,NULL)))
  192.                         goto synterr2;
  193.                     PC=(unsigned long) value;
  194.                     break;
  195.                 case 13:        /* resolve EQU directive */
  196.                         if(Ops!=1)
  197.                         goto synterr2;
  198.                         if(!eval(pointer,NULL))
  199.                             printf("*** UNKNOWN LABEL *** at line %d :%s\nLabel: %s\n",lineno,linebuf,pointer);
  200.                         labtab[indx-1].Address=value;
  201.                         break;
  202.                 case 11:        /* handle multioperand DATA directive */
  203.                     if(!Ops)
  204.                         goto synterr2;
  205.                     PC+=Ops;    /* increment PC */
  206.                     break;
  207.             }
  208.             incpc();
  209.         }
  210.     }
  211.     if(xref) {
  212.         puts("\nCross Reference Listing:");
  213.         puts("-----------------------\n");
  214.         for(i=0;i<indx;i++)
  215.             printf("\tLabel: %s, address: 0x%04X\n",labtab[i].Label,labtab[i].Address);
  216.         puts("");    
  217.         }
  218.         
  219. /* Start second pass */
  220.  
  221.     rewind(fi);
  222.     PC=0;
  223.     lineno=0;
  224.     while(fgets(linebuf,sizeof(linebuf),fi)) {
  225.         pointer=linebuf;
  226.         lineno++;
  227.         strtok(linebuf,";");            /* strip out comments */
  228.         if(!(isseppp(linebuf[0])))        /* skip labels */
  229.             for(i=0;(i<(LINEBUF-1))&&(!(issep(linebuf[i])));i++,pointer++);
  230.         if(pointer=getword(pointer)) {
  231.             if((i=findopc(pointer))==-1) {  /* not an opcode */
  232.                 goto synterr;
  233.             }
  234.             switch(opinfo->Type) {
  235.                 
  236.                 case 14: 
  237.                     if(Ops!=1)
  238.                         goto synterr2;
  239.                     if(!(eval(pointer,NULL))) {
  240. synterr2:                    printf("*** SYNTAX ERROR *** at line %d :%s\nBad operand: %s\n",lineno,linebuf,pointer);
  241.                         goto error;
  242.                     }
  243.                     PC=(unsigned long) value;
  244.                     break;
  245.                 case 0:
  246.                     if(Ops)
  247.                         goto synterr2;
  248.                     fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode);
  249.                     break;
  250.                 case 1:
  251.                     if(Ops!=1)
  252.                         goto synterr2;
  253.                     if(!eval(pointer,NULL))
  254.                         goto synterr2;
  255.                     if((value>1)||(value<0))
  256.                         goto synterr2;
  257.                     fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode|value);
  258.                     break;
  259.                 case 2:
  260.                     if(Ops!=1)
  261.                         goto synterr2;
  262.                     if(!eval(pointer,NULL))
  263.                         goto synterr2;
  264.                     if((value>255)||(value<-127))
  265.                         goto synterr2;
  266.                     fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode|value);
  267.                     break;
  268.                 case 3:
  269.                     if(Ops!=2)
  270.                         goto synterr2;
  271.                     if(!evalops(pointer,NULL))    /* 1st operand */
  272.                         goto synterr2;
  273.                     if((value>1)||(value<0))
  274.                         goto synterr2;
  275.                     word=opinfo->OpCode|(value<<8);
  276.                     if(!evalops(NULL,NULL))    /* 2nd operand */
  277.                         goto synterr2;
  278.                     if((value>255)||(value<-127))
  279.                         goto synterr2;
  280.                     fprintf(fo,"%04X\n%04X\n",PC,word|value);
  281.                     break;
  282.                 case 4:
  283.                     if(Ops!=1)
  284.                         goto synterr2;
  285.                     if(!eval(pointer,NULL))
  286.                         goto synterr2;
  287.                     if((value>8191)||(value<-4095))
  288.                         goto synterr2;
  289.                     fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode|value);
  290.                     break;
  291.                 case 5: 
  292.                     if((!Ops)||(Ops>2))
  293.                         goto synterr2;
  294.                     if((i=evalops(pointer,TRUE))==-1) {    /* get first operand and */
  295.                         word=value;            /* check for indirect addressing */
  296.                         if(Ops==2) {        /* check for new AR */
  297.                             if(!evalops(NULL,NULL)) 
  298.                                 goto synterr2;
  299.                             if((value>1)||(value<0))
  300.                                 goto synterr2;
  301.                             word=word&0xfff7|value;
  302.                         }
  303.                     }
  304.                     else {                /* first operand is direct addressing */
  305.                         if (Ops!=1) 
  306.                             goto synterr2;
  307.                         if(!i) 
  308.                             goto synterr2;
  309.                         if((value>127)||(value<0))
  310.                             goto synterr2;
  311.                         word=value;
  312.                     }
  313.                     fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode|word);
  314.                     break;
  315.                 case 6:
  316.                     if((Ops<2)||(Ops>3))
  317.                         goto synterr2;
  318.                     if(!evalops(pointer,NULL))
  319.                         goto synterr2;
  320.                     if((value>1)||(value<0))
  321.                         goto synterr2;
  322.                     word=value<<8;
  323.                     if((i=evalops(NULL,TRUE))==-1) {
  324.                         word=word|value;
  325.                         if(Ops==3) {
  326.                             if(!evalops(NULL,NULL)) 
  327.                                 goto synterr2;
  328.                             if((value>1)||(value<0))
  329.                                 goto synterr2;
  330.                             word=word&0xfff7|value;
  331.                         }
  332.                     }
  333.                     else {
  334.                         if (Ops!=2)
  335.                             goto synterr2;
  336.                         if(!i)
  337.                             goto synterr2;
  338.                         if((value>127)||(value<0))
  339.                             goto synterr2;
  340.                         word=word|value;
  341.                     }
  342.                     fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode|word);
  343.                     break;
  344.                 case 7:
  345.                     if((!Ops)||(Ops>3))
  346.                         goto synterr2;
  347.                     if((i=evalops(pointer,TRUE))==-1) {
  348.                         word=value;
  349.                         if(Ops>1) {
  350.                             if(!evalops(NULL,NULL)) 
  351.                                 goto synterr2;
  352.                             if((value)&&(value!=1)&&(value!=4))
  353.                                 goto synterr2;
  354.                             word=word|(value<<8);
  355.                             if(Ops==3) {
  356.                                 if(!evalops(NULL,NULL)) 
  357.                                     goto synterr2;
  358.                                 if((value>1)||(value<0))
  359.                                     goto synterr2;
  360.                                 word=word&0xfff7|value;
  361.                             }
  362.                         }
  363.                     }
  364.                     else {
  365.                         if (Ops!=2)
  366.                             goto synterr2;
  367.                         if(!i)
  368.                             goto synterr2;
  369.                         if((value>127)||(value<0))
  370.                             goto synterr2;
  371.                         word=value;
  372.                         if(!evalops(NULL,NULL)) 
  373.                             goto synterr2;
  374.                         if((value)&&(value!=1)&&(value!=4))
  375.                             goto synterr2;
  376.                         word=word|(value<<8);
  377.                     }
  378.                     fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode|word);
  379.                     break;
  380.                 case 8:
  381.                     if((!Ops)||(Ops>3))
  382.                         goto synterr2;
  383.                     if((i=evalops(pointer,TRUE))==-1) {
  384.                         word=value;
  385.                         if(Ops>1) {
  386.                             if(!evalops(NULL,NULL)) 
  387.                                 goto synterr2;
  388.                             if((value<0)||(value>7))
  389.                                 goto synterr2;
  390.                             word=word|(value<<8);
  391.                             if(Ops==3) {
  392.                                 if(!evalops(NULL,NULL)) 
  393.                                     goto synterr2;
  394.                                 if((value>1)||(value<0))
  395.                                     goto synterr2;
  396.                                 word=word&0xfff7|value;
  397.                             }
  398.                         }
  399.                     }
  400.                     else {
  401.                         if (Ops!=2)
  402.                             goto synterr2;
  403.                         if(!i)
  404.                             goto synterr2;
  405.                         if((value>127)||(value<0))
  406.                             goto synterr2;
  407.                         word=value;
  408.                         if(!evalops(NULL,NULL)) 
  409.                             goto synterr2;
  410.                         if((value<0)||(value>7))
  411.                             goto synterr2;
  412.                         word=word|(value<<8);
  413.                     }
  414.                     fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode|word);
  415.                     break;
  416.                 case 9:
  417.                     if((!Ops)||(Ops>3))
  418.                         goto synterr2;
  419.                     if((i=evalops(pointer,TRUE))==-1) {
  420.                         word=value;
  421.                         if(Ops>1) {
  422.                             if(!evalops(NULL,NULL)) 
  423.                                 goto synterr2;
  424.                             if((value<0)||(value>15))
  425.                                 goto synterr2;
  426.                             word=word|(value<<8);
  427.                             if(Ops==3) {
  428.                                 if(!evalops(NULL,NULL)) 
  429.                                     goto synterr2;
  430.                                 if((value>1)||(value<0))
  431.                                     goto synterr2;
  432.                                 word=word&0xfff7|value;
  433.                             }
  434.                         }
  435.                     }
  436.                     else {
  437.                         if (Ops!=2)
  438.                             goto synterr2;
  439.                         if(!i)
  440.                             goto synterr2;
  441.                         if((value>127)||(value<0))
  442.                             goto synterr2;
  443.                         word=value;
  444.                         if(!evalops(NULL,NULL)) 
  445.                             goto synterr2;
  446.                         if((value<0)||(value>15))
  447.                             goto synterr2;
  448.                         word=word|(value<<8);
  449.                     }
  450.                     fprintf(fo,"%04X\n%04X\n",PC,opinfo->OpCode|word);
  451.                     break;
  452.                 case 10:
  453.                     if(Ops!=1)
  454.                         goto synterr2;
  455.                     if(!eval(pointer,NULL))
  456.                         goto synterr2;
  457.                     if((value>4095)||(value<0))
  458.                         goto synterr2;
  459.                     fprintf(fo,"%04X\n%04X\n%04X\n%04X\n",PC,opinfo->OpCode,PC+1,value);
  460.                     break;
  461.                 case 11:
  462.                     if(!Ops)
  463.                         goto synterr2;
  464.                     if(!evalops(pointer,NULL))
  465.                         goto synterr2;
  466.                     if((value>65535)||(value<-32767))
  467.                         goto synterr2;
  468.                     fprintf(fo,"%04X\n%04X\n",PC++,value);
  469.                     while (--Ops) {                /* handle multiple operands */
  470.                         if(!evalops(NULL,NULL))
  471.                             goto synterr2;
  472.                         if((value>65535)||(value<-32767))
  473.                             goto synterr2;
  474.                         fprintf(fo,"%04X\n%04X\n",PC++,value);
  475.                     }
  476.                     break;
  477.                 case 13:
  478.                     break;
  479.                 case 15:
  480.                     goto end;
  481.                     break;
  482.                 default:
  483.                     puts("*** Oh, Oh, the soft is dead...");
  484.                     goto error;
  485.             }
  486.             incpc();
  487.         }
  488.     }
  489. end:    fclose(fi);
  490.     fclose(fo);
  491.     if(link) {        
  492.         sprintf(linebuf,"L320 %s\n",fileout);
  493.         Execute(linebuf,0,0);
  494.     }
  495.     exit(0);
  496. error:    fclose(fi);
  497.     fclose(fo);
  498.     exit(1);
  499. }
  500.  
  501. void Copyright(void)
  502. {
  503.     puts("TMS32010 Cross Assembler (C)1994 by SRC");
  504. }
  505.  
  506. issep(char c)
  507. {
  508.     return((c==' ')||(c=='\t'));
  509. }
  510.  
  511. issepp(char c)
  512. {
  513.     return((c==' ')||(c=='\t')||(c==';'));
  514. }
  515.  
  516. isseppp(char c)
  517. {
  518.     return((c==' ')||(c=='\t')||(c==';')||(c=='\n'));
  519. }
  520.  
  521. char *getword(char *ptr)    /* get a word from a line */
  522. {
  523. char word[LINEBUF];
  524. int i;
  525.     for(;(*ptr!=0)&&(issep(*ptr));ptr++);        /* skip leading blanks */
  526.     if((*ptr==0)||(isseppp(*ptr)))            /* handle EOL */
  527.         return(0);
  528.     strcpy(word,ptr);                /* get word */
  529.     for(i=0;(*ptr!=0)&&(!(isseppp(*ptr)));i++,ptr++); /* find lenght */
  530.     word[i]=0;
  531.     return(word);
  532. }
  533.  
  534. findword(word, tab, n)        /* find a word in an array, tab is an array */
  535.                 /* of vectors pointing to each entry in the table */
  536. char *word, *tab[];        /* the array is sorted lower to higher */
  537. int n;
  538. {
  539. int low,high,mid,cond;        /* (C) Kernighan & Ritchie */
  540.  
  541.     low=0;
  542.     high=n-1;
  543.     while(low<=high) {
  544.         mid=(low+high)/2;
  545.         if((cond=strcmp(word,tab[mid]))<0)
  546.             high=mid-1;
  547.         else if(cond>0)
  548.             low=mid+1;
  549.         else return(mid);
  550.     }
  551.     return(-1);
  552. }
  553.  
  554. findopc(char *word)        /* find an opcode in the opcode table */
  555. {
  556. int pos=0;
  557. char *opc;
  558.     opc=strdup(word);
  559.     if(!(isupper(opc[0])))            /* if lower case, get upper */
  560.         for(pos=0;pos<strlen(opc);pos++) 
  561.             opc[pos]=toupper(opc[pos]);                            
  562.     if((pos=findword(opc,mntable,TABLEN))==-1)    /* search... */
  563.         return(-1);
  564.     opinfo->Type=tytable[pos];    /* if found, fill structure */
  565.     opinfo->OpCode=optable[pos];
  566.     pointer=getop(word);        /* advance pointer to point to ops */
  567.     Ops=getopinf(pointer);
  568.     return(pos);
  569. }
  570.  
  571. void incpc(void)        /* increment PC according to instruction */
  572. {
  573.     if(opinfo->Type<11)    /* standard opcode */
  574.         PC++;
  575.     if(opinfo->Type==10)    /* Two word instruction */
  576.         PC++;        
  577. }
  578.  
  579. long getnum(char *ptr)
  580. {
  581. int base=0;            /* support C notation */
  582. long add;
  583. char **eptr;
  584.  
  585.     if(ptr[0]=='>') {    /* support Texas hex notation */
  586.         base=16;
  587.         ptr++;
  588.     }
  589.     add=strtol(ptr,eptr,base);
  590.     if(*eptr==ptr)        /* syntax error (labels not supported) */
  591.         return(-1);
  592.     return(add);
  593. }
  594.     
  595. char *getop(char *inst)
  596. {
  597. char *ptr;
  598.  
  599.     strcpy(auxbuf,linebuf);
  600.     ptr=strstr(auxbuf,inst);        /* point to instruction */ 
  601.     ptr+=(strlen(inst)+1);            /* point to operands */
  602.     ptr[strlen(ptr)-1]=0;
  603.     return(ptr);
  604. }
  605.     
  606. stlabel(char *label)            /* store label in label table */
  607. {
  608.     if(findlabel(label)!=-1)    /* check if already defined */
  609.         return(0);
  610.     if(indx==MAXLAB)          /* check for room */
  611.         return(-1);
  612.     strcpy(labtab[indx].Label,label);
  613.     labtab[indx++].Address=PC;
  614.     return(1);
  615. }
  616.  
  617. findlabel(char *label)
  618. {
  619. int i;
  620.     for(i=0;i<indx;i++)
  621.         if(!strcmp(labtab[i].Label,label))    /* label found */
  622.             return(i);
  623.     return(-1);
  624. }
  625.  
  626. eval (char *ptr,BOOL type)
  627. {
  628. int i=0;
  629.     ptr=getword(ptr);
  630.     if((strlen(ptr)==1)&&(*ptr=='$')) {    /* allow "?" label */
  631.         value=PC;
  632.         return(1);
  633.     }
  634.     if (type &&((*ptr)=='*')) {                /* handle indirect addressing */
  635.         i=strlen(ptr++);
  636.         if(i==1) {
  637.             value=0x88;
  638.             return(-1);
  639.         }
  640.         if(i==2) {
  641.             if(*ptr=='+') {    /* handle postincrement */
  642.                 value=0xa8;
  643.                 return(-1);
  644.             }
  645.             else if(*ptr=='-') {    /* handle postdecrement */
  646.                 value=0x98;
  647.                 return(-1);
  648.             }
  649.             else    return(0);
  650.         }
  651.     }
  652.     if((value=findlabel(ptr))!=-1) {    /* is it a label ? */
  653.         value=labtab[value].Address;
  654.         return(1);
  655.     }
  656.     if((value=getnum(ptr))!=-1)     /* evaluate operand */
  657.         return(1);
  658.     return(0);
  659. }
  660.  
  661. evalops(char *ptr,BOOL type)
  662. {
  663.     if(ptr) 
  664.         strtok(ptr,",");        /* get first operand */
  665.     else 
  666.         pointer=strtok(NULL,",");            /* get next operand */
  667.     return(eval(pointer,type));
  668. }
  669.  
  670. getopinf(char *ptr)
  671. {
  672. int n=1;
  673.     for(;(*ptr!=0)&&(issep(*ptr));ptr++);    /* skip blanks */
  674.     if(!strlen(ptr))
  675.         return(0);
  676.     for(;*ptr!=0;ptr++)
  677.         if(*ptr==',')
  678.             n++;
  679.     return(n);
  680. }