home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / crossasm / uasm.arc / UASM.C < prev    next >
C/C++ Source or Header  |  1986-04-06  |  22KB  |  873 lines

  1. /*
  2.                 UASM - UNIVERSAL CROSS ASSMEBLER                 uasm.c
  3.                 CUSTOM COMPUTER CONSULTANTS
  4.                 5 April 1986
  5.  
  6. */
  7. #include <stdio.h>
  8. #include <uasm.h>
  9.  
  10. #define NHASH  512
  11. #define HP1    7
  12. #define HP2    2
  13.                         /* Flags                */
  14.  
  15. int     sf, lf, hf, nolist ;
  16. int     pass1, pass2 ;
  17. int     lbl ;
  18. int     info ;
  19. int     valid ;
  20.  
  21.                         /* Numbers              */
  22. int     i, j, k ;
  23. int     kk, r ;
  24. int     lineno, lnspp, pgno ;
  25.  
  26. int     cc ;            /* character count      */
  27. int     mcc ;           /* mark character count */
  28. int     ll ;            /* line length          */
  29. int     maxop ;
  30. int     maxpseudo ;
  31. int     ilc, active ;
  32. int     il[NSEG] ;
  33. int     instl ;
  34. int     parval ;
  35. int     num ;
  36. int     radix ;
  37. int     cput ;          /* ib pointer           */
  38. int     errcnt, esp ;
  39. int     syte, sytx ;
  40.  
  41. unsigned        unpar ;
  42. unsigned        ht ;    /* Record Type                          */
  43. unsigned        ha ;    /* Record Start Address                 */
  44. unsigned        he ;    /* Expected Address of next item        */
  45. unsigned        hc ;    /* Checksum Mod 256                     */
  46. unsigned        hsp ;   /* Hex String Pointer                   */
  47.  
  48. long     start, finish, time() ;
  49. #define  NOW   (0L)
  50.                         /* Characters           */
  51.  
  52. unsigned  char    ch ;            /* last character       */
  53. unsigned  char    nch ;           /* next character       */
  54. unsigned  char    sym ;           /* last symbol          */
  55.                         /* Pointers             */
  56.  
  57. char    *iptr ;         /* Input Buffer         */
  58. char    *src ;          /* Source File Name     */
  59. char    *cp ;           /* General Purpose      */
  60.  
  61.                         /* Character Arrays     */
  62.  
  63. char    hex[13] ;       /* Hex File Name        */
  64. char    lst[13] ;       /* List File Name       */
  65.  
  66. char    segtype[NSEG] ;
  67.  
  68. char    id[AL] ;        /* Last Identifier      */
  69. unsigned  char    ib[256] ;       /* Instruction Byte Queue       */
  70. unsigned  char    ssym[256] ;     /* character symbols    */
  71. unsigned  char    hs[MAXB] ;
  72. char    errstk[25] ;
  73. unsigned  char    pv[200] ;
  74. unsigned  char    px[80] ;
  75.  
  76. int    pj[15] ;
  77.  
  78. int    qhash[NHASH] ;     /* Head indexes for hash chains        */
  79. int    nlook, nprobe ;
  80. int    maxprobe ;
  81.  
  82.                         /* Pointer Arrays       */
  83.  
  84. char    *pc[80], *pseudo[15] ;
  85.  
  86. int     (*pp[200])() ;
  87. int     (*ppo[15])() ;
  88.                         /* I/O Buffers          */
  89.  
  90. char    ibuf[MAXLINE] ;
  91. FILE    *dibuf, *libuf, *hxbuf ;
  92.  
  93. struct  symbol  symtab[NSYM] ;
  94. int     psym[NSYM] ;
  95.  
  96. extern  char    push() ;
  97. extern  char    pop() ;
  98. extern  int     cpmf() ;
  99. extern  char    *strcat() ;
  100.  
  101.  
  102. extern  char    *version ;
  103.  
  104. /*
  105.        Control Programs
  106.  
  107.                main()          Open files, assemble, close files, exit
  108.                assemble()      Process input and create tables
  109.                code()          Generate object output
  110.                list()          Generate Listing
  111. */
  112.  
  113. main(narg,argv)
  114. int  narg;
  115. char **argv;
  116.  
  117. {
  118.         start = time(NOW) ;
  119.  
  120.         puts("\033[2J") ;     /* CLEAR_SCREEN */
  121.  
  122.         puts("Universal Cross Assembler -- V1.4  4/5/86\n") ;
  123.         puts("(c) Custom Computer Consultants, 1986\n") ;
  124.         puts(version) ;
  125.  
  126.         sf = lf = hf = nolist = FALSE ;
  127.  
  128. /*              FILE OPERATIONS                 */
  129.  
  130.         if( --narg > 0  ) {
  131.           dibuf = fopen( *(++argv), "r" ) ;
  132.           if( dibuf == NULL ) abort("Source ?\n")   ;
  133.           src = *argv ; sf = TRUE ;
  134.           }
  135.  
  136.         if( --narg > 0 ) {
  137.           j = 0 ;
  138.           while( **argv != '.' && j < 8 ) {
  139.             hex[j] = lst[j] = *(*argv)++ ;
  140.             ++j ;
  141.             }
  142.           hex[j] = lst[j] = EOS ;
  143.           strcat( hex, ".HEX" )  ;
  144.           strcat( lst, ".LST" )  ;
  145.           ++argv ;
  146.           while( ch = *(*argv)++ ) {
  147.             if((ch == 'L') || (ch == 'l')) {
  148.               libuf = fopen(lst,"w") ;
  149.               if( libuf == NULL ) abort("List ?\n") ;
  150.               lf = TRUE ;
  151.               }
  152.             else if((ch == 'O') || (ch == 'o')) {
  153.                    hxbuf = fopen(hex,"w") ;
  154.                    if( hxbuf == NULL ) abort("Hex ?\n")  ;
  155.                    hf = TRUE ;
  156.                    }
  157.                  else if((ch == 'N') || (ch == 'n')) nolist = TRUE ;
  158.  
  159.             }  /* END while(ch = *(*argv)++ )  */
  160.  
  161.           }    /* END if(--narg > 0)           */
  162.  
  163.         syte = pgno = lnspp = 0 ;
  164.         nlook = nprobe = maxprobe = 0 ;
  165.         setmem(ssym,256,NUL) ;         /* NUL is the token value \200  */
  166.         setmem(qhash,2*NHASH,ERROR) ;
  167.  
  168.         cp = "$+-*/(),;%~|&^'@#.<>\"" ;
  169.         while( ch = *cp++ ) ssym[ch]=ch ;
  170.  
  171.         set_type() ;
  172.  
  173.         maxpseudo = build_pseudo() ;
  174.         maxop = buildopc();
  175.         
  176.         pass1 = sf ? TRUE  : FALSE ;
  177.         pass2 = sf ? FALSE : TRUE  ;
  178.  
  179. /*      Main Assembler Loop                     */
  180.  
  181.         while ( pass1 || pass2 ) {
  182.         if ( pass1 ) puts("Pass 1 : ") ;
  183.         if ( pass2 ) puts("Pass 2 : ") ;
  184.         lineno = 1;
  185.  
  186.         set_il() ;
  187.         
  188.         active = code_seg() ;
  189.         hsp = hc = ht = 0 ;
  190.         ha  = he = ilc = il[active] ;
  191.         errcnt = 0 ;
  192.         radix = 10 ;
  193.  
  194.         while(( getline(ibuf)) != EOF ) {
  195.           info = assemble() ;
  196.           code() ;
  197.           list() ;
  198.           lineno++ ;
  199.           ilc +=  instl ;
  200.           }                             /*  end while on getline(ibuf) */
  201.  
  202.         if ( sf ) {
  203.           fclose(dibuf) ;
  204.           dibuf = pass1 ? fopen(src,"r") : dibuf ;
  205.           if( dibuf == NULL ) abort("Source Reopen ?\n") ;
  206.           }
  207.  
  208.         pass1 = FALSE ;
  209.         pass2 = pass2 ? FALSE : TRUE ;
  210.         finish = time(NOW) ;
  211.         printf("\t%5ld\tseconds\n",finish-start) ;
  212.         }                               /* end while on pass1 || pass2 */
  213.  
  214. /*     Sort the Symbol Table                                            */
  215.  
  216.        if ( syte ) {
  217.          qsort(psym,syte,sizeof(int),cpmf) ;
  218.          }
  219.  
  220.  
  221. /*      Print the Symbol Table                                          */
  222.  
  223.         if( !nolist ) {
  224.           cprintf("\fSymbol Table\n\n") ;
  225.           for ( i = 0 ; i < syte ; i++ ) {
  226.             if ( i % 5 == 0 ) cprintf("\n") ;
  227.             sytx = psym[i] ;
  228.             cprintf("%-12s%04x%c   ",symtab[sytx].name,
  229.                                      symtab[sytx].value,
  230.                                      segtype[symtab[sytx].flags & (NSEG-1)] ) ;
  231.           }
  232.         }
  233.  
  234.         cprintf("\n\n") ;
  235.         if( errcnt > 0 ) {
  236.           cprintf("%04d  ERRORS\n",errcnt) ;
  237.           if( nolist || lf ) printf("\n%04d  ERRORS\n",errcnt) ;
  238.           }
  239.         else {
  240.           cprintf("  NO  ERRORS\n") ;
  241.           if( nolist || lf ) puts("\n  NO  ERRORS\n") ;
  242.           }
  243.  
  244.         if ( lf ) {
  245.           putc(CPMEOF,libuf) ;
  246.           fflush(libuf) ;
  247.           fclose(libuf) ;
  248.           }
  249.  
  250.         if ( hf ) {
  251.           hsout() ;
  252.           fprintf(hxbuf,":00000001FF\n") ;
  253.           putc(CPMEOF,hxbuf) ;
  254.           fflush(hxbuf) ;
  255.           fclose(hxbuf) ;
  256.           }
  257.  
  258.         puts("ASSEMBLY COMPLETE\n");
  259.         finish = time(NOW) ;
  260.         printf("\n%5ld\tseconds\n",finish-start) ;
  261.         printf("%5ld\tlines/minute\n",lineno*60/(finish-start)) ;
  262.         printf("%5d\tprobes\n%5d\tlookups\n",nprobe,nlook) ;
  263.         printf("%5.2f\tprobes/lookup\n",(float)nprobe/(float)nlook) ;
  264.         printf("%5d\tmaximum probe\n",maxprobe) ;
  265.         nprobe = 0 ;
  266.         for (nlook = 0 ; nlook < NHASH ; ++nlook ) {
  267.           if( qhash[nlook] != ERROR ) ++nprobe ;
  268.           }
  269.         printf("%5d\thash entries\n",nprobe) ;
  270.         printf("%5d\tpercent utilization\n",(100*nprobe)/nlook) ;
  271.         exit();
  272. }
  273.  
  274. cpmf(a,b)
  275. int    *a, *b ;
  276. {
  277.        return strcmp(symtab[*a].name,symtab[*b].name) ;
  278. }
  279.  
  280. #define INFO    1
  281. #define NOINFO  0
  282.  
  283.  
  284. assemble()
  285. {
  286.  
  287.         setmem(ib,4,0) ;                /* clear info bytes     */
  288.         esp = 0 ;                       /* clear error stack    */
  289.         instl = parval = valid = 0 ;    /* clear length & val   */
  290.         cput = 0 ;                      /* clear queue          */
  291.  
  292.         if( isin(ch,"*;\n") ) return NOINFO ;
  293.  
  294. /*      process labels  */
  295.  
  296.         lbl = ERROR ;
  297.         if ( isalpha(ch) ) {
  298.           getsym() ;
  299.           if ( pass1 ) {
  300.             if ( append(id) == ERROR ) puts("Symbol Table Full\n") ;
  301.             else { symtab[syte].value = ilc ;
  302.                    symtab[syte].flags = active ;
  303.                    psym[syte] = syte ;
  304.                    lbl= ++syte == NSYM ? (--syte , ERROR) : OK ;
  305.                    }
  306.             }
  307.           if( ch == ':' ) getch() ;    /* swallow colons       */
  308.         }
  309.  
  310.         getsym() ;
  311.         if( sym != IDENT ) return NOINFO ;
  312.  
  313. /*
  314.         search pseudo operation table
  315.         use index in case statement to determine action
  316. */
  317.         i = 0 ; k = maxpseudo - 1 ;
  318.         do {
  319.           j = ( i + k ) / 2 ;
  320.           mcc = sscmp(id,pseudo[j]) ;
  321.           if( mcc <= 0 ) k = j - 1 ;
  322.           if( mcc >= 0 ) i = j + 1 ;
  323.           } while( i <= k ) ;
  324.  
  325.         if ( i - 1 > k ) {
  326.              j = pj[j] ;
  327.              return (*ppo[j])() ;
  328.              }
  329.  
  330.         i = 0 ; k = maxop - 1 ;
  331.         do {
  332.           j = ( i + k ) / 2 ;
  333.           mcc = sscmp(id,pc[j]) ;
  334.           if( mcc <= 0 ) k = j - 1 ;
  335.           if( mcc >= 0 ) i = j + 1 ;
  336.           } while( i <= k ) ;
  337.  
  338.         if ( i - 1 > k ) {
  339.            while ( isin(ch," \t") ) getch() ;
  340.            mcc = cc - 1 ;
  341.            for ( k = px[j] ; k < px[j+1] ; ++k ) {
  342.                 valid = (*pp[k])() ;
  343.                 if( valid  ) break ;
  344.                 else { iptr = &ibuf[cc=mcc] ; getch() ; }
  345.                 }
  346.            valid ? TRUE : push('M') ;
  347.            }
  348.         else push('O') ;
  349.         return INFO ;
  350. }
  351.  
  352. code()
  353. {
  354.         if ( pass1 || !info ) return ;
  355.         if ( !hf ) return ;
  356.         if ( not_cseg(active) ) return ;
  357.  
  358. /*    hex string output         */
  359.  
  360.         if ( (hsp>0) && (he != ilc) || hsp > MAXB - 1 ) {
  361.                 hsout() ;
  362.                 ha = ilc ;
  363.                 }
  364.  
  365.         for ( k = 0 ; k < instl ; k++ ) {
  366.                 hs[hsp++] = ib[k] ;
  367.                 hc += ib[k] ;
  368.                 hc &= 0xFF ;
  369.                 if( hsp > MAXB-1 ) {
  370.                         hsout() ;
  371.                         ha += MAXB ;
  372.                         }
  373.                 }
  374.         he = ilc + instl ;
  375.         return ;
  376. }
  377.  
  378. list()
  379. {
  380.         if ( pass1 || nolist ) return ;
  381.         lnspp -= esp + 1 ;
  382.         if ( lf != 0 && lnspp <= 0 ) {
  383.           pgno++ ;
  384.           lnspp = 55 ;
  385.           cprintf("\fCustom Computer Consultants\t\t\t\t\t\t") ;
  386.           cprintf("PAGE %-4d\n",pgno) ;
  387.           cprintf("%s\n",version) ;
  388.           cprintf("LN #\tLOC   CODE\t\tSOURCE\n") ;
  389.           }
  390.         cprintf("%04d|\t",lineno) ;
  391.         if( instl ) cprintf("%04x%c\t",ilc,segtype[active]) ;
  392.         else        cprintf("\t") ;
  393.         if (info) {
  394.           kk = ( instl <= 4 ) ? instl : 4 ;
  395.           r = instl - kk ;
  396.           i = ( kk <= 4 ) ? 4 - kk : 0 ;
  397.           j = 0 ;
  398.           while ( kk--)  cprintf("%02x ",ib[j++]) ;
  399.           while ( i-- )  cprintf("   ") ;
  400.           cprintf("\t%s",ibuf) ;
  401.  
  402.           while ( r ) {
  403.             kk = r <= 4 ? r : 4 ;
  404.             r -= kk ;
  405.             cprintf("\t\t") ;
  406.             while( kk-- ) cprintf("%02x ",ib[j++]) ;
  407.             cprintf("\n") ;
  408.             }
  409.           }
  410.         else cprintf("\t\t%s",ibuf) ;
  411.         while( ch = pop() ) {
  412.           errcnt++ ;
  413.           switch(ch) {
  414.             case 'R' : cprintf("R*** RELATIVE ADDRESS RANGE\n");
  415.                        break;
  416.  
  417.             case 'O' : cprintf("O*** ILLEGAL OPCODE\n") ;
  418.                        break;
  419.  
  420.             case 'M' : cprintf("M*** ADDRESSING MODE ERROR\n");
  421.                        break;
  422.  
  423.             case 'S' : cprintf("S*** SYNTAX ERROR\n") ;
  424.                        break;
  425.  
  426.             case 'P' : cprintf("P*** ILLEGAL OPERATOR\n") ;
  427.                        break ;
  428.  
  429.             case 'E' : cprintf("E*** SYMBOL TABLE EMPTY\n") ;
  430.                        break;
  431.  
  432.             case 'U' : cprintf("U*** UNDEFINED SYMBOL\n") ;
  433.                        break ;
  434.  
  435.             default  : cprintf("E*** ERROR MESSAGE ERROR <%02x>\n",ch) ;
  436.             }
  437.           }
  438. }
  439.  
  440.  
  441. /*
  442.         getline -- assembles one line of input text from
  443.                    the console input or from a buffered i/o
  444.                    device.
  445.  
  446. */
  447. getline()
  448. {
  449.         iptr = sf ? fgets(ibuf,MAXLINE,dibuf) :
  450.                     strcat(gets(ibuf,MAXLINE),"\n" ) ;
  451.         if( !iptr || *iptr == CPMEOF ) return EOF ;
  452.         ll = strlen(ibuf) ;
  453.         cc = 0 ;
  454.         getch() ;
  455.         return ll ;
  456. }
  457.  
  458. getch()
  459. {       ch  = cc < ll ? (++cc , *iptr++)  : '\n' ;
  460.         nch = *iptr ;
  461. }
  462.  
  463. getsym()
  464. {
  465.         int     k, np, rad, irad ;
  466.         char    rc ;
  467.  
  468.         while( isin(ch," \t") ) getch() ;
  469.         if( (sym = ssym[ch]) == ch )  return ;
  470.         else 
  471.         if( isdigit(ch) ) {
  472.           sym = NUMBER ;
  473.           rad = radix ;
  474.           np = cc - 1 ;
  475.           do {
  476.             irad = rad ;
  477.             iptr = &ibuf[cc=np] ; getch() ;
  478.             num = 0 ;
  479.             while( ( k = _bc(ch,rad)) != ERROR ) {
  480.                num = num * rad + k ;
  481.                rc = ch ;        /* possible radix overide */
  482.                getch() ;
  483.                }
  484.             if( isin(ch,"ABCDEF") ) { rad = 16 ; continue ; }
  485.             if( isin(ch,"doqbhx") ) rc = ch ;
  486.             switch(rc) {
  487.                 case 'd' : rad = 10 ; getch() ; break ;
  488.  
  489.                 case 'o' :
  490.                 case 'q' : rad = 8  ; getch() ; break ;
  491.  
  492.                 case 'b' : rad = 2  ; getch() ; break ;
  493.  
  494.                 case 'h' :
  495.                 case 'x' : rad = 16 ; getch() ; break ;
  496.                 }
  497.             } while( rad != irad ) ;
  498.           }
  499.         else
  500.         if( isalpha(ch) ) {
  501.           k = 0 ;
  502.           do {
  503.              if( k < AL ) id[k++] = ch ;
  504.              getch() ;
  505.              } while ( alphanum(ch) ) ;
  506.           sym = IDENT ;
  507.           if ( k >= AL ) --k ;
  508.           id[k] = EOS ;
  509.           }
  510. }         
  511.  
  512.  
  513. isin(c,s)
  514. char    c ;
  515. char    *s ;
  516. {
  517.         cp = s ;
  518.         do { if ( c == *s++ ) return s - cp ; } while ( *s ) ;
  519.         return FALSE ;
  520. }
  521.  
  522.  
  523. sscmp(s,t)
  524. char    *s, *t ;
  525. {
  526.         char    c ;
  527.  
  528.         while ( (c = toupper(*s)) == *t ) {
  529.           if( c == EOS ) return 0 ;
  530.           ++s ; ++t ;
  531.           }
  532.         return c - *t ;
  533. }
  534.  
  535. nomatch(s)
  536. char    *s ;
  537. {
  538.         while ( *s ) {
  539.           if ( toupper(ch) != *s++ ) return TRUE ;
  540.           getch() ;
  541.           }
  542.         return FALSE ;
  543. }  
  544.  
  545. notcomma()
  546. {
  547.         if( ch != ',' )         return TRUE  ;
  548.         getch() ;
  549.         return FALSE ;
  550. }
  551.  
  552.  
  553. alphanum(c)
  554. char    c ;
  555. {       return isalpha(c) || isdigit(c) || c == '_' ; }
  556.  
  557.  
  558. /*
  559.        Output Processing
  560.  
  561.                hsout()
  562.                cprintf()
  563.                puts()
  564. */
  565.  
  566. hsout()
  567. {
  568.                 if( hsp == 0 ) return ;
  569.                 hc += (( hsp + ( ha >> 8 ) +  ha  + ht ) & 0xFF ) ;
  570.                 hs[hsp] = 256 - hc ;
  571.                 fprintf(hxbuf,":%02x%04x%02x",hsp,ha,ht) ;
  572.                 for ( j=0 ; j <= hsp ; j++ )
  573.                         fprintf(hxbuf,"%02x",hs[j]) ;
  574.                 fprintf(hxbuf,"\n") ;
  575.                 hsp = hc = ht = 0 ;
  576.  
  577. }
  578.  
  579.  
  580.  
  581. cprintf(format,args)
  582. unsigned  char *format ;
  583. unsigned       args ;
  584. {
  585.        extern  int     write() ;
  586.  
  587.        int     fn ;
  588.  
  589.        if( nolist ) return ;
  590.        fn = lf ? fileno(libuf) : fileno(stdout) ;     
  591.        return _fmtout(&write,fn,format,&args) ;
  592.       
  593. }
  594.  
  595.  
  596. /*     puts -- Replaces the version in the library
  597.                It does not do an explicit newline      */
  598.  
  599. puts(s)
  600. char   *s ;
  601. {
  602.        while(*s) putchar(*s++) ;
  603. }
  604.  
  605. /*
  606.        Expression Analyzer
  607.  
  608.                eval()
  609.                hier1()
  610.                hier2()
  611.                hier3()
  612.                hier4()
  613.                term()
  614.                factor()
  615.                _bc
  616. */
  617.  
  618. eval()
  619. {
  620.         int     val ;
  621.  
  622.         val = hier1() ;
  623.         while( sym == '|' ) {
  624.           getch() ;
  625.           val |= hier1() ;
  626.           }
  627.         return val ;
  628. }
  629.  
  630.  
  631. hier1()
  632. {
  633.         int     val ;
  634.  
  635.         val = hier2() ;
  636.         while( sym == '^' ) {
  637.           getch() ;
  638.           val ^= hier2() ;
  639.           }
  640.         return val ;
  641. }
  642.  
  643.  
  644. hier2()
  645. {
  646.         int     val ;
  647.  
  648.         val = hier3() ;
  649.         while( sym == '&' ) {
  650.           getch() ;
  651.           val &= hier3() ;
  652.           }
  653.         return val ;
  654. }
  655.  
  656.  
  657. hier3()
  658. {
  659.         int     val ;
  660.  
  661.         val = hier4() ;
  662.         while( isin(sym,"<>") ) {
  663.           getch() ;
  664.           switch(sym) {
  665.              case '<' : val <<= hier4() ;
  666.                         break ;
  667.              case '>' : val >>= hier4() ;
  668.              }
  669.           }
  670.         return val ;
  671. }
  672.  
  673. hier4()
  674. {
  675.         int     val ;
  676.  
  677.         val = term() ;
  678.         while( isin(sym,".+-") ) {
  679.           getch() ;
  680.           switch(sym) {
  681.              case '.' : 
  682.              case '+' : val += term() ;
  683.                         break ;
  684.              case '-' : val -= term() ;
  685.              }
  686.           }
  687.         return val ;
  688. }
  689.  
  690. term()
  691. {
  692.         int     val ;
  693.  
  694.         val = factor() ;
  695.         while( isin(sym,"*/%") ) {
  696.           getch() ;
  697.           switch (sym) {
  698.              case '*' : val *= factor() ;
  699.                         break ;
  700.              case '/' : val /= factor() ;
  701.                         break ;
  702.              case '%' : val %= factor() ;
  703.              }
  704.           }
  705.         return val ;
  706. }
  707.  
  708. factor()
  709. {
  710.         int     val, sx ;
  711.         char    sign ;
  712.  
  713.         val = 0 ; sign = '+' ; sytx = ERROR ;
  714.         getsym() ;
  715.         if( isin(sym,"+-~") ) {
  716.             sign = sym ;
  717.             getch() ;
  718.             getsym() ;
  719.             }
  720.         if( sym == IDENT ) {
  721.             sx = lookup(id) ;
  722.             if( sx == NSYM ) push('U') ;
  723.             else
  724.             if( sx == ERROR ) push('E') ;
  725.             else {
  726.               val = symtab[sx].value ;
  727.               sytx = sx ;
  728.               getsym() ;
  729.               }
  730.             }
  731.         else 
  732.         if( sym == NUMBER ) {
  733.             val = num ;
  734.             getsym() ;
  735.             }
  736.         else 
  737.         if( sym == '(' ) {
  738.             getch() ;
  739.             val = eval() ;
  740.             if( sym == ')' ) { getch() ; getsym() ; }
  741.             else push('S') ;
  742.             }
  743.         else
  744.         if( sym == '$' ) {
  745.             val = ilc ;
  746.             getch() ;
  747.             getsym() ;
  748.             }
  749.         else
  750.         if( sym == '\'' ) {
  751.             getch() ;
  752.             val = ch & 0xFF ;
  753.             getch() ;
  754.             if( ch == '\'' ) { getch() ; getsym() ; }
  755.             else push('S') ;
  756.             }
  757.         else push('S') ;
  758.  
  759.         switch(sign) {
  760.           case '-' : val = -val ;
  761.                      break ;
  762.           case '~' : val = ~val ;
  763.  
  764.           default  : break ;
  765.           }
  766.         return val ;
  767. }
  768.  
  769. _bc(c,b)
  770. char   c, b ;
  771. {
  772.        if(isalpha(c = toupper(c))) c -= 55 ;
  773.        else if(isdigit(c))         c -= 0x30 ;
  774.             else return ERROR ;
  775.        if(c > b-1) return ERROR ;
  776.        else return c ;
  777. }
  778.  
  779. /*
  780.        Symbol Table Routines
  781.  
  782.                append()        adds a new symbol to the table
  783.                lookup()        checks the table for a symbol
  784. */
  785.  
  786. hash(s,l)
  787. unsigned  char   *s ;
  788. unsigned  int    l ;
  789. {
  790.         unsigned  char   c ;
  791.  
  792.         if ( l == 0 ) l = strlen(s) ;
  793.         c = ( *s + *(s+l-1) ) >> 1 ;
  794.         return (( c * HP1 + l * HP2 ) & (NHASH-1));
  795. }
  796.  
  797. append(s)
  798. char    *s ;
  799. {
  800.         int  h, q ;
  801.         int  l ;
  802.  
  803.         if ( syte == NSYM ) return ERROR  ;
  804.         l = 1 + strlen(s) ;
  805.         symtab[syte].name = sbrk(l) ;
  806.         strcpy(symtab[syte].name , s ) ;
  807.         symtab[syte].flags = '\0' ;
  808.         symtab[syte].value = 0 ;
  809.         symtab[syte].link = ERROR ;
  810.  
  811.         h = hash(s,l-1) ;
  812.         q = qhash[h] ;
  813.         if ( q == ERROR ) qhash[h] = syte ;
  814.         else {
  815.           while( symtab[q].link != ERROR ) q = symtab[q].link ;
  816.           symtab[q].link = syte ;
  817.           }
  818.         return OK ;
  819. }
  820.  
  821. lookup(s)
  822. char *s ;
  823. {
  824.         int  q, m ;
  825.  
  826.         m = 0 ;
  827.         if ( syte == 0 ) return ERROR ; /* ST EMPTY */
  828.         ++nlook ;
  829.         q = qhash[hash(s,0)] ;
  830.         while( q != ERROR ) {
  831.           ++nprobe ; ++m ;
  832.           if( m > maxprobe ) maxprobe = m ;
  833.           if( strcmp(symtab[q].name,s) == 0 ) return q ;
  834.           q = symtab[q].link ;
  835.           }
  836.         return NSYM ;   /* Not Found */
  837. }
  838.  
  839.  
  840. /*     Error Processing
  841.  
  842.                abort()
  843.                push()
  844.                pop()
  845. */
  846.  
  847. abort(s)
  848. char    *s ;
  849.  
  850. {       puts(s) ; exit() ;      }
  851.  
  852.  
  853. char push(c)
  854. char c;
  855. {
  856.         if( esp < 25 ) return (errstk[esp++] = c);
  857.         return '\0';
  858. }
  859.  
  860. char pop()
  861. {
  862.         if( esp > 0 ) return (errstk[--esp]);
  863.         return '\0';
  864. }
  865.  
  866.  
  867. /*
  868.         End of UASM.C
  869. */
  870.  
  871.  
  872.  
  873.