home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 2 / RISC_DISC_2.iso / pd_share / program / language / motasm / src_c_symtab < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-04  |  13.5 KB  |  412 lines

  1. #include <string.h>
  2. #include <stdio.h>
  3.  
  4. #include "proto.h"
  5. #include "as.h"
  6. #include "structs.h"
  7.  
  8. #include "mselect.h"
  9.  
  10.  
  11. #if (defined  MC68HC11)
  12. #include "table11.h"
  13. #else
  14. #if (defined  MC68HC05)
  15. #include "table5.h"
  16. #else
  17. #if (defined MC6809)
  18. #include "table9.h"
  19. #else
  20. #error undefined target processor, please define MICRO
  21. #endif /*6809*/
  22. #endif /*68HC05*/
  23. #endif /*68HC11*/
  24.  
  25.  
  26.  
  27. #include "extvars.h"
  28.  
  29. /*
  30.  * pseudo --- pseudo op processing
  31.  */
  32.  
  33. #define RMB     0               /* Reserve Memory Bytes         */
  34. #define FCB     1               /* Form Constant Bytes          */
  35. #define FDB     2               /* Form Double Bytes (words)    */
  36. #define FCC     3               /* Form Constant Characters     */
  37. #define ORG     4               /* Origin                       */
  38. #define EQU     5               /* Equate                       */
  39. #define ZMB     6               /* Zero memory bytes            */
  40. #define FILL    7               /* block fill constant bytes    */
  41. #define OPT     8               /* assembler option             */
  42. #define NULL_OP 9               /* null pseudo op               */
  43. #define PAGE    10              /* new page                     */
  44. #define BSS     17              /* block storage segment (RAM) ver TER_2.09 */
  45. #define CODE    18              /* code segment ver TER_2.09 25 Jul 89 */
  46. #define DATA    19              /* data segment ver TER_2.09 25 Jul 89 */
  47. #define AUTO    20              /* data segment ver TER_2.09 25 Jul 89 */
  48. #define END     21              /* end of file directive        */
  49.  
  50. struct oper     pseudo[] = {
  51.         "=", PSEUDO, EQU, 0,    /* ver TER_2.09 25 Jul 89 */
  52.         "auto", PSEUDO, AUTO, 0,/* ver TER_2.09 25 Jul 89 */
  53.         "bss", PSEUDO, BSS, 0,  /* ver TER_2.09 25 Jul 89 */
  54.         "bsz", PSEUDO, ZMB, 0,
  55.         "code", PSEUDO, CODE, 0,/* ver TER_2.09 25 Jul 89 */
  56.         "data", PSEUDO, DATA, 0,/* ver TER_2.09 25 Jul 89 */
  57.         "end", PSEUDO, END, 0,
  58.         "equ", PSEUDO, EQU, 0,
  59.         "fcb", PSEUDO, FCB, 0,
  60.         "fcc", PSEUDO, FCC, 0,
  61.         "fdb", PSEUDO, FDB, 0,
  62.         "fill", PSEUDO, FILL, 0,
  63.         "nam", PSEUDO, NULL_OP, 0,
  64.         "name", PSEUDO, NULL_OP, 0,
  65.         "opt", PSEUDO, OPT, 0,
  66.         "org", PSEUDO, ORG, 0,
  67.         "pag", PSEUDO, PAGE, 0,
  68.         "page", PSEUDO, PAGE, 0,
  69.         "ram", PSEUDO, BSS, 0,  /* ver TER_2.09 25 Jul 89 */
  70.         "rmb", PSEUDO, RMB, 0,
  71.         "spc", PSEUDO, NULL_OP, 0,
  72.         "ttl", PSEUDO, NULL_OP, 0,
  73.         "zmb", PSEUDO, ZMB, 0
  74. };
  75.  
  76. /*
  77.  * do_pseudo --- do pseudo op processing
  78.  */
  79. void
  80. do_pseudo(int op)
  81. /* int op; which op */
  82. {
  83.         char            fccdelim;
  84.         int             fill;
  85.         /*
  86.          * void    pouterror(), NewPage(), IfMachine();
  87.          *//* rel TER_2.0 6/18/89 */
  88.         /* void    PC_Exchange();  *//* ver TER_2.09 25 Jul 89 */
  89.  
  90.         if (op != EQU && *Label)
  91.                 install(Label, Pc);
  92.  
  93.         P_force++;
  94.  
  95. #ifdef DEBUG3
  96.         printf("%s, line no. ", Argv[Cfn]);     /* current file name */
  97.         printf("%d: ", Line_num);       /* current line number */
  98.         printf(" Pseudo Op=%u\n", op);
  99. #endif
  100.  
  101.         switch (op) {
  102.         case RMB:               /* reserve memory bytes */
  103.                 if (eval()) {
  104.                         Pc += Result;
  105.                         f_record();     /* flush out bytes */
  106.                 } else
  107.                         error("Undefined Operand during Pass One");
  108.                 break;
  109.         case ZMB:               /* zero memory bytes */
  110.                 if (eval())
  111.                         while (Result--)
  112.                                 emit(0);
  113.                 else
  114.                         error("Undefined Operand during Pass One");
  115.                 break;
  116.         case FILL:              /* fill memory with constant */
  117.                 eval();
  118.                 fill = Result;
  119.                 if (*Optr++ != ',')
  120.                         error("Bad fill");
  121.                 else {
  122.                         Optr = skip_white(Optr);
  123.                         eval();
  124.                         while (Result--)
  125.                                 emit(fill);
  126.                 }
  127.                 break;
  128.         case FCB:               /* form constant byte(s) */
  129.                 do {
  130.                         Optr = skip_white(Optr);
  131.                         eval();
  132.                         if (Result > 0xFF) {
  133.                                 if (!Force_byte)
  134.                                         warn("Value truncated");
  135.                                 Result = lobyte(Result);
  136.                         }
  137.                         emit(Result);
  138.                 } while (*Optr++ == ',');
  139.                 break;
  140.         case FDB:               /* form double byte(s) */
  141.                 do {
  142.                         Optr = skip_white(Optr);
  143.                         eval();
  144.                         eword(Result);
  145.                 } while (*Optr++ == ',');
  146.                 break;
  147.         case FCC:               /* form constant characters */
  148.                 if (*Operand == EOS)
  149.                         break;
  150. /*                Optr++;*/
  151.                 fccdelim = *Optr++;
  152.                 if ((fccdelim != SQUOT) && (fccdelim != DQUOT))
  153.                         {error("Missing Delimiter - \' or \" expected");
  154.                           break;}
  155. /*              putchar ( fccdelim );*/
  156.                 while (*Optr != EOS && *Optr != fccdelim)
  157.                         emit(*Optr++);
  158.                 if (*Optr == fccdelim)
  159.                         {Optr++;}
  160.                 else
  161.                         {error("Missing Delimiter");}
  162.                 break;
  163.         case ORG:               /* origin */
  164.                 if (eval()) {
  165.                         Old_pc = Pc = Result;
  166.                         f_record();     /* flush out any bytes */
  167.                 } else
  168.                         error("Undefined Operand during Pass One");
  169.                 break;
  170.         case EQU:               /* equate */
  171.                 if (*Label == EOS) {
  172.                         error("EQU requires label");
  173.                         break;
  174.                 }
  175.                 if (eval()) {
  176.                         install(Label, Result);
  177.                         Old_pc = Result;        /* override normal */
  178.                 } else
  179.                         error("Undefined Operand during Pass One");
  180.                 break;
  181.         case OPT:               /* assembler option */
  182.                 P_force = 0;
  183.                 if (head(Operand, "l") || head(Operand, "list"))
  184.                         Lflag = 1;
  185.                 else if (head(Operand, "nol") || head(Operand, "nolist"))
  186.                         Lflag = 0;
  187.                 else if (head(Operand, "c") || head(Operand, "cyc")) {
  188.                         Cflag = 1;
  189.                         Ctotal = 0;
  190.                 } else if (head(Operand, "noc") || head(Operand, "nocyc"))
  191.                         Cflag = 0;
  192.                 else if (head(Operand, "contc") || head(Operand, "contcyc")) {
  193.                         Cflag = 1;
  194.                 } else if (head(Operand, "s") || head(Operand, "sym"))
  195.                         Sflag = 1;
  196.                 else if (head(Operand, "cre") || head(Operand, "x"))
  197.                         CREflag = 1;
  198.                 else if (head(Operand, "p50"))  /* turn on page flag */
  199.                         Pflag50 = 1;    /* ver (TER) 2.02 19 Jun 89 */
  200.                 else if (head(Operand, "crlf")) /* add <CR> <LF> to */
  201.                         CRflag = 1;     /* S record ver TER_2.08 */
  202.                 else
  203.                         error("Unrecognized OPT");
  204.                 break;
  205.         case PAGE:              /* go to a new page */
  206.                 P_force = 0;
  207.                 N_page = 1;
  208.                 if (Pass == 2)
  209.                         if (Lflag)
  210.                                 NewPage();
  211.                 break;
  212.         case NULL_OP:           /* ignored psuedo ops */
  213.                 P_force = 0;
  214.                 break;
  215.         case CODE:              /* CODE,DATA,BSS,AUTO ver TER_2.09 */
  216.                 PC_Exchange(0);
  217.                 break;
  218.         case DATA:
  219.                 PC_Exchange(1);
  220.                 break;
  221.         case BSS:
  222.                 PC_Exchange(2);
  223.                 break;
  224.         case AUTO:
  225.                 PC_Exchange(3);
  226.                 break;
  227.         case END:
  228.             P_force = 0;
  229.                 end_found = YES;
  230.                 break;
  231.         default:
  232.                 fatal("Pseudo error");
  233.                 break;
  234.         }
  235. }
  236.  
  237.  
  238. /*
  239.  * PC_Exchange --- Save current PC and recover requested one added ver
  240.  * TER_2.09
  241.  */
  242. void
  243. PC_Exchange(int PC_ptr_new)
  244. /* int PC_ptr_new; request 0=CODE,1=DATA,2=BSS */
  245. {
  246.         P_force = 0;            /* no PC in output cuz wrong first time (?) */
  247.         PC_Save[PC_ptr] = Pc;   /* save current PC */
  248.         PC_ptr = PC_ptr_new;    /* remember which one we're using */
  249.         Old_pc = Pc = PC_Save[PC_ptr];  /* recover the one requested */
  250.         f_record();             /* flush out any bytes, this is really an ORG */
  251. }
  252.  
  253. /* pseudo module ends here */
  254.  
  255.  
  256.  
  257. /*
  258.  * install --- add a symbol to the table
  259.  */
  260. int
  261. install(char *str, int val)
  262. {
  263.         struct link    *lp;
  264.         struct nlist   *np, *p, *backp;
  265.         int             i;
  266.         /* char *LastChar();    *//* ver TER_2.0 */
  267.  
  268.         if (!alpha(*str)) {
  269.                 error("Illegal Symbol Name");
  270.                 return (NO);
  271.         }
  272.         if ((np = lookup(str)) != NULL) {
  273.                 if (*LastChar(str) == '@') {    /* redefinable symbol  ver
  274.                                                  * TER_2.0 */
  275.                         np->def = val;  /* redefined */
  276.                         return (YES);
  277.                 }
  278.                 if (Pass == 2) {
  279.                         np->def2 = 2;   /* defined for this pass=Pass  ver
  280.                                          * TER_2.0 */
  281.                         if (np->def == val)
  282.                                 return (YES);
  283.                         else {
  284.                                 error("Phasing Error");
  285.                                 return (NO);
  286.                         }
  287.                 }
  288.                 error("Symbol Redefined");
  289.                 return (NO);
  290.         }
  291.         /* enter new symbol */
  292. #ifdef DEBUG
  293.         printf("Installing %s as %d\n", str, val);
  294. #endif
  295.         np = (struct nlist *) alloc(sizeof(struct nlist));
  296.         if (np == (struct nlist *) ERR) {
  297.                 error("Symbol table full");
  298.                 return (NO);
  299.         }
  300.         np->name = alloc(strlen(str) + 1);
  301.         if (np->name == (char *) ERR) {
  302.                 error("Symbol table full");
  303.                 return (NO);
  304.         }
  305.         strcpy(np->name, str);
  306.         np->def = val;
  307.         np->def2 = 1;           /* defined for this pass=Pass  ver TER_2.0 */
  308.         np->Lnext = NULL;
  309.         np->Rnext = NULL;
  310.         lp = (struct link *) alloc(sizeof(struct link));
  311.         np->L_list = lp;
  312.         lp->L_num = Line_num;
  313.         lp->next = NULL;
  314.         p = root;
  315.         backp = NULL;
  316.         while (p != NULL) {
  317.                 backp = p;
  318.                 i = strcmp(str, p->name);
  319.                 if (i < 0)
  320.                         p = p->Lnext;
  321.                 else
  322.                         p = p->Rnext;
  323.         }
  324.         if (backp == NULL)
  325.                 root = np;
  326.         else if (strcmp(str, backp->name) < 0)
  327.                 backp->Lnext = np;
  328.         else
  329.                 backp->Rnext = np;
  330.         return (YES);
  331. }
  332.  
  333. /*
  334.  * lookup --- find string in symbol table
  335.  */
  336. struct nlist   *
  337. lookup(char *name)
  338. {
  339.         struct nlist   *np;
  340.         int             i;
  341.         char           *c;      /* ver TER_2.0 */
  342.  
  343.         c = name;               /* copy symbol pointer */
  344.         while (alphan(*c))      /* search for end of symbol */
  345.                 c++;            /* next char */
  346.         *c = EOS;               /* disconnect anything after for good compare */
  347.         /* end of mods for ver TER_2.0 */
  348.  
  349.         np = root;              /* and now go on and look for symbol */
  350.         while (np != NULL) {
  351.                 i = strcmp(name, np->name);
  352.                 if (i == 0) {
  353.                         Last_sym = np->def;
  354.                         return (np);
  355.                 } else if (i < 0)
  356.                         np = np->Lnext;
  357.                 else
  358.                         np = np->Rnext;
  359.         }
  360.         Last_sym = 0;
  361.         /*
  362.          * if (Pass == 2) error ("symbol Undefined on pass 2");
  363.          */
  364.         /* commented out ver TER_2.0 2 Jul 89 */
  365.         /* function used in IFD */
  366.         return (NULL);
  367. }
  368.  
  369.  
  370. #define NMNE (sizeof(table)/ sizeof(struct oper))
  371. #define NPSE (sizeof(pseudo)/ sizeof(struct oper))
  372. /*
  373.  * mne_look --- mnemonic lookup
  374.  *
  375.  * Return pointer to an oper structure if found. Searches both the machine
  376.  * mnemonic table and the pseudo table.
  377.  */
  378. struct oper    *
  379. mne_look(char *str)
  380. {
  381.         struct oper    *low, *high, *mid;
  382.         int             cond;
  383.  
  384.         /* Search machine mnemonics first */
  385.         low = &table[0];
  386.         high = &table[NMNE - 1];
  387.         while (low <= high) {
  388.                 mid = low + (high - low) / 2;
  389.                 if ((cond = strcmp(str, mid->mnemonic)) < 0)
  390.                         high = mid - 1;
  391.                 else if (cond > 0)
  392.                         low = mid + 1;
  393.                 else
  394.                         return (mid);
  395.         }
  396.  
  397.         /* Check for pseudo ops */
  398.         low = &pseudo[0];
  399.         high = &pseudo[NPSE - 1];
  400.         while (low <= high) {
  401.                 mid = low + (high - low) / 2;
  402.                 if ((cond = strcmp(str, mid->mnemonic)) < 0)
  403.                         high = mid - 1;
  404.                 else if (cond > 0)
  405.                         low = mid + 1;
  406.                 else
  407.                         return (mid);
  408.         }
  409.  
  410.         return (NULL);
  411. }
  412.