home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / emulator / unix / z80pack / z80asm / z80atab.c < prev   
Encoding:
C/C++ Source or Header  |  1992-07-09  |  6.1 KB  |  273 lines

  1. /*
  2.  *      Z80 - Assembler
  3.  *      Copyright (C) 1987-1992 by Udo Munk
  4.  *
  5.  *    History:
  6.  *    17-SEP-1987 Development under Digital Research CP/M 2.2
  7.  *      28-JUN-1988 Switched to Unix System V.3
  8.  */
  9.  
  10. /*
  11.  *    Dieses Modul enthaelt alle Operationen, die die
  12.  *    Tabellen durchsuchen oder veraendern.
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include "z80a.h"
  17. #include "z80aglb.h"
  18.  
  19. /*    Die folgende Funktion fuehrt die binaere Suche
  20.  *    in der alphabetisch sortierten OP-Code-Tabelle
  21.  *    'opctab' aus.
  22.  *
  23.  *      Input:  Zeiger auf String mit dem OP-Code
  24.  *
  25.  *      Output: Zeiger auf das Tabellenelement oder
  26.  *              einen NULL-Pointer, wenn OP-Code
  27.  *              nicht gefunden
  28.  */
  29. struct opc *search_op(op_name)
  30. register char *op_name;
  31. {
  32.     register int cond;
  33.     register struct opc *low, *high, *mid;
  34.  
  35.     low = &opctab[0];
  36.     high = &opctab[no_opcodes - 1];
  37.     while (low <= high) {
  38.         mid = low + (high - low) / 2;
  39.         if ((cond = strcmp(op_name, mid->op_name)) < 0)
  40.             high = mid - 1;
  41.         else if (cond > 0)
  42.             low = mid + 1;
  43.         else
  44.             return(mid);
  45.     }
  46.     return(NULL);
  47. }
  48.  
  49. /*    Die folgende Funktion fuehrt die binaere Suche
  50.  *      in der alphabetisch sortierten Operanden-Tabelle
  51.  *      'opetab' aus.
  52.  *
  53.  *      Input:  Zeiger auf String mit dem Operanden
  54.  *
  55.  *      Output: Symbol fuer den Operanden
  56.  *              NOOPERA, wenn Operand leer ist
  57.  *              NOREG, wenn Operand nicht gefunden
  58.  */
  59. get_reg(s)
  60. register char *s;
  61. {
  62.     register int cond;
  63.     register struct ope *low, *high, *mid;
  64.  
  65.     if (s == NULL || *s == '\0')
  66.         return(NOOPERA);
  67.     low = &opetab[0];
  68.     high = &opetab[no_operands - 1];
  69.     while (low <= high) {
  70.         mid = low + (high - low) / 2;
  71.         if ((cond = strcmp(s, mid->ope_name)) < 0)
  72.             high = mid - 1;
  73.         else if (cond > 0)
  74.             low = mid + 1;
  75.         else
  76.             return(mid->ope_sym);
  77.     }
  78.     return(NOREG);
  79. }
  80.  
  81. /*    Die folgende Funktion fuehrt die Suche in der Symboltabelle
  82.  *    'symtab' durch. Dazu wird ein HASH-Algorithmus verwendet.
  83.  *
  84.  *      Input:  Zeiger auf String mit dem Symbol
  85.  *
  86.  *      Output: Zeiger auf das Tabellenelement oder
  87.  *              einen NULL-Pointer, wenn Symbol
  88.  *              nicht gefunden
  89.  */
  90. struct sym *get_sym(sym_name)
  91. register char *sym_name;
  92. {
  93.     register struct sym *np;
  94.  
  95.     for (np = symtab[hash(sym_name)]; np != NULL; np = np->sym_next)
  96.         if (strcmp(sym_name, np->sym_name) == 0)
  97.             return(np);
  98.     return(NULL);
  99. }
  100.  
  101. /*    Die folgende Funktion traegt ein Symbol in die Symboltabelle
  102.  *      'symtab' ein. Ist das Symbol in der Tabelle noch nicht
  103.  *      vorhanden, wird es neu angelegt, sonst wird 'sym_wert'
  104.  *      in den vorhandenen Eintrag uebernommen.
  105.  *    Fuer die Symboltabellen-Zugriffe wird ein HASH-Algorithmus
  106.  *    verwendet.
  107.  *
  108.  *    Input:    sym_name Zeiger auf String mit dem Symbol
  109.  *        sym_wert Wert des Symbols
  110.  *
  111.  *      Output: 0 = eingetragen
  112.  *              1 = kein Speicherplatz mehr frei
  113.  */
  114. put_sym(sym_name, sym_wert)
  115. char *sym_name;
  116. int sym_wert;
  117. {
  118.     char *strsave(), *malloc();
  119.     struct sym *get_sym();
  120.     register int hashval;
  121.     register struct sym *np;
  122.  
  123.     if (!gencode)
  124.         return(0);
  125.     if ((np = get_sym(sym_name)) == NULL) {
  126.         np = (struct sym *) malloc(sizeof (struct sym));
  127.         if (np == NULL)
  128.             return(1);
  129.         if ((np->sym_name = strsave(sym_name)) == NULL)
  130.             return(1);
  131.         hashval = hash(sym_name);
  132.         np->sym_next = symtab[hashval];
  133.         symtab[hashval] = np;
  134.     }
  135.     np->sym_wert = sym_wert;
  136.     return(0);
  137. }
  138.  
  139. /*
  140.  *      Diese Funktion traegt ein Label in die Symboltabelle ein.
  141.  *      Vorher wird geprueft, ob dieses Symbol bereits vorhanden
  142.  *      ist, was zu einer entsprechenden Fehlermeldung fuehrt.
  143.  */
  144. put_label()
  145. {
  146.     struct sym *get_sym();
  147.  
  148.     if (get_sym(label) == NULL) {
  149.         if (put_sym(label, pc))
  150.             fatal(F_OUTMEM, "symbols");
  151.     } else
  152.         asmerr(E_MULSYM);
  153. }
  154.  
  155. /*    Hier folget der HASH-Algorithmus selbst.
  156.  *
  157.  *      Input:  Zeiger auf String mit dem Namen
  158.  *
  159.  *      Output: HASH-Wert
  160.  */
  161. hash(name)
  162. register char *name;
  163. {
  164.     register int hashval;
  165.  
  166.     for (hashval = 0; *name;)
  167.         hashval += *name++;
  168.     return(hashval % HASHSIZE);
  169. }
  170.  
  171. /*    Diese Funktion kopiert einen String auf einen
  172.  *    angeforderten Speicherplatz.
  173.  *
  174.  *      Input:  Zeiger auf den String
  175.  *
  176.  *      Output: Zeiger auf den Speicherplatz
  177.  */
  178. char *strsave(s)
  179. register char *s;
  180. {
  181.     char *malloc(), *strcpy();
  182.     register char *p;
  183.  
  184.     if ((p = malloc((unsigned) strlen(s)+1)) != NULL)
  185.         strcpy(p, s);
  186.     return(p);
  187. }
  188.  
  189. /*
  190.  *      Diese Funktion kopiert alle Eintraege aus der
  191.  *      Symbol-Hashtabelle in ein dynamisch erzeugtes
  192.  *      Pointer-Array
  193.  */
  194. copy_sym()
  195. {
  196.     char *malloc(), *realloc();
  197.     register int i, j;
  198.     register struct sym *np;
  199.  
  200.     symarray = (struct sym **) malloc(SYMINC * sizeof(struct sym *));
  201.     if (symarray == NULL)
  202.         fatal(F_OUTMEM, "sorting symbol table");
  203.     symsize = SYMINC;
  204.     for (i = 0, j = 0; i < HASHSIZE; i++) {
  205.         if (symtab[i] != NULL) {
  206.             for (np = symtab[i]; np != NULL; np = np->sym_next) {
  207.                 symarray[j++] = np;
  208.                 if (j == symsize) {
  209.                     symarray = (struct sym **) realloc((char *) symarray, symsize * sizeof(struct sym *) + SYMINC * sizeof(struct sym *));
  210.                     if (symarray == NULL)
  211.                         fatal(F_OUTMEM, "sorting symbol table");
  212.                     symsize += SYMINC;
  213.                 }
  214.             }
  215.         }
  216.     }
  217.     return(j);
  218. }
  219.  
  220. /*
  221.  *      Symboltabelle nach Namen sortieren
  222.  */
  223. n_sort_sym(len)
  224. register int len;
  225. {
  226.     register int gap, i, j;
  227.     register struct sym *temp;
  228.  
  229.     for (gap = len/2; gap > 0; gap /= 2)
  230.         for (i = gap; i < len; i++)
  231.             for (j = i-gap; j >= 0; j -= gap) {
  232.                 if (strcmp(symarray[j]->sym_name, symarray[j+gap]->sym_name) <= 0)
  233.                     break;
  234.                 temp = symarray[j];
  235.                 symarray[j] = symarray[j+gap];
  236.                 symarray[j+gap] = temp;
  237.             }
  238. }
  239.  
  240. /*
  241.  *      Symboltabelle nach Adressen sortieren
  242.  */
  243. a_sort_sym(len)
  244. register int len;
  245. {
  246.     register int gap, i, j;
  247.     register struct sym *temp;
  248.  
  249.     for (gap = len/2; gap > 0; gap /= 2)
  250.         for (i = gap; i < len; i++)
  251.             for (j = i-gap; j >= 0; j -= gap) {
  252.                 if (numcmp(symarray[j]->sym_wert, symarray[j+gap]->sym_wert) <= 0)
  253.                     break;
  254.                 temp = symarray[j];
  255.                 symarray[j] = symarray[j+gap];
  256.                 symarray[j+gap] = temp;
  257.             }
  258. }
  259.  
  260. /*
  261.  *      Vergleicht zwei 16-Bit Werte, Ergebnis wie strcmp
  262.  */
  263. numcmp(n1, n2)
  264. register int n1, n2;
  265. {
  266.     if ((unsigned) (n1 & 0xffff) < (unsigned) (n2 & 0xffff))
  267.         return(-1);
  268.     else if ((unsigned) (n1 & 0xffff) > (unsigned) (n2 & 0xffff))
  269.         return(1);
  270.     else
  271.         return(0);
  272. }
  273.