home *** CD-ROM | disk | FTP | other *** search
- /*
- * Z80 - Assembler
- * Copyright (C) 1987-1992 by Udo Munk
- *
- * History:
- * 17-SEP-1987 Development under Digital Research CP/M 2.2
- * 28-JUN-1988 Switched to Unix System V.3
- */
-
- /*
- * Dieses Modul enthaelt alle Operationen, die die
- * Tabellen durchsuchen oder veraendern.
- */
-
- #include <stdio.h>
- #include "z80a.h"
- #include "z80aglb.h"
-
- /* Die folgende Funktion fuehrt die binaere Suche
- * in der alphabetisch sortierten OP-Code-Tabelle
- * 'opctab' aus.
- *
- * Input: Zeiger auf String mit dem OP-Code
- *
- * Output: Zeiger auf das Tabellenelement oder
- * einen NULL-Pointer, wenn OP-Code
- * nicht gefunden
- */
- struct opc *search_op(op_name)
- register char *op_name;
- {
- register int cond;
- register struct opc *low, *high, *mid;
-
- low = &opctab[0];
- high = &opctab[no_opcodes - 1];
- while (low <= high) {
- mid = low + (high - low) / 2;
- if ((cond = strcmp(op_name, mid->op_name)) < 0)
- high = mid - 1;
- else if (cond > 0)
- low = mid + 1;
- else
- return(mid);
- }
- return(NULL);
- }
-
- /* Die folgende Funktion fuehrt die binaere Suche
- * in der alphabetisch sortierten Operanden-Tabelle
- * 'opetab' aus.
- *
- * Input: Zeiger auf String mit dem Operanden
- *
- * Output: Symbol fuer den Operanden
- * NOOPERA, wenn Operand leer ist
- * NOREG, wenn Operand nicht gefunden
- */
- get_reg(s)
- register char *s;
- {
- register int cond;
- register struct ope *low, *high, *mid;
-
- if (s == NULL || *s == '\0')
- return(NOOPERA);
- low = &opetab[0];
- high = &opetab[no_operands - 1];
- while (low <= high) {
- mid = low + (high - low) / 2;
- if ((cond = strcmp(s, mid->ope_name)) < 0)
- high = mid - 1;
- else if (cond > 0)
- low = mid + 1;
- else
- return(mid->ope_sym);
- }
- return(NOREG);
- }
-
- /* Die folgende Funktion fuehrt die Suche in der Symboltabelle
- * 'symtab' durch. Dazu wird ein HASH-Algorithmus verwendet.
- *
- * Input: Zeiger auf String mit dem Symbol
- *
- * Output: Zeiger auf das Tabellenelement oder
- * einen NULL-Pointer, wenn Symbol
- * nicht gefunden
- */
- struct sym *get_sym(sym_name)
- register char *sym_name;
- {
- register struct sym *np;
-
- for (np = symtab[hash(sym_name)]; np != NULL; np = np->sym_next)
- if (strcmp(sym_name, np->sym_name) == 0)
- return(np);
- return(NULL);
- }
-
- /* Die folgende Funktion traegt ein Symbol in die Symboltabelle
- * 'symtab' ein. Ist das Symbol in der Tabelle noch nicht
- * vorhanden, wird es neu angelegt, sonst wird 'sym_wert'
- * in den vorhandenen Eintrag uebernommen.
- * Fuer die Symboltabellen-Zugriffe wird ein HASH-Algorithmus
- * verwendet.
- *
- * Input: sym_name Zeiger auf String mit dem Symbol
- * sym_wert Wert des Symbols
- *
- * Output: 0 = eingetragen
- * 1 = kein Speicherplatz mehr frei
- */
- put_sym(sym_name, sym_wert)
- char *sym_name;
- int sym_wert;
- {
- char *strsave(), *malloc();
- struct sym *get_sym();
- register int hashval;
- register struct sym *np;
-
- if (!gencode)
- return(0);
- if ((np = get_sym(sym_name)) == NULL) {
- np = (struct sym *) malloc(sizeof (struct sym));
- if (np == NULL)
- return(1);
- if ((np->sym_name = strsave(sym_name)) == NULL)
- return(1);
- hashval = hash(sym_name);
- np->sym_next = symtab[hashval];
- symtab[hashval] = np;
- }
- np->sym_wert = sym_wert;
- return(0);
- }
-
- /*
- * Diese Funktion traegt ein Label in die Symboltabelle ein.
- * Vorher wird geprueft, ob dieses Symbol bereits vorhanden
- * ist, was zu einer entsprechenden Fehlermeldung fuehrt.
- */
- put_label()
- {
- struct sym *get_sym();
-
- if (get_sym(label) == NULL) {
- if (put_sym(label, pc))
- fatal(F_OUTMEM, "symbols");
- } else
- asmerr(E_MULSYM);
- }
-
- /* Hier folget der HASH-Algorithmus selbst.
- *
- * Input: Zeiger auf String mit dem Namen
- *
- * Output: HASH-Wert
- */
- hash(name)
- register char *name;
- {
- register int hashval;
-
- for (hashval = 0; *name;)
- hashval += *name++;
- return(hashval % HASHSIZE);
- }
-
- /* Diese Funktion kopiert einen String auf einen
- * angeforderten Speicherplatz.
- *
- * Input: Zeiger auf den String
- *
- * Output: Zeiger auf den Speicherplatz
- */
- char *strsave(s)
- register char *s;
- {
- char *malloc(), *strcpy();
- register char *p;
-
- if ((p = malloc((unsigned) strlen(s)+1)) != NULL)
- strcpy(p, s);
- return(p);
- }
-
- /*
- * Diese Funktion kopiert alle Eintraege aus der
- * Symbol-Hashtabelle in ein dynamisch erzeugtes
- * Pointer-Array
- */
- copy_sym()
- {
- char *malloc(), *realloc();
- register int i, j;
- register struct sym *np;
-
- symarray = (struct sym **) malloc(SYMINC * sizeof(struct sym *));
- if (symarray == NULL)
- fatal(F_OUTMEM, "sorting symbol table");
- symsize = SYMINC;
- for (i = 0, j = 0; i < HASHSIZE; i++) {
- if (symtab[i] != NULL) {
- for (np = symtab[i]; np != NULL; np = np->sym_next) {
- symarray[j++] = np;
- if (j == symsize) {
- symarray = (struct sym **) realloc((char *) symarray, symsize * sizeof(struct sym *) + SYMINC * sizeof(struct sym *));
- if (symarray == NULL)
- fatal(F_OUTMEM, "sorting symbol table");
- symsize += SYMINC;
- }
- }
- }
- }
- return(j);
- }
-
- /*
- * Symboltabelle nach Namen sortieren
- */
- n_sort_sym(len)
- register int len;
- {
- register int gap, i, j;
- register struct sym *temp;
-
- for (gap = len/2; gap > 0; gap /= 2)
- for (i = gap; i < len; i++)
- for (j = i-gap; j >= 0; j -= gap) {
- if (strcmp(symarray[j]->sym_name, symarray[j+gap]->sym_name) <= 0)
- break;
- temp = symarray[j];
- symarray[j] = symarray[j+gap];
- symarray[j+gap] = temp;
- }
- }
-
- /*
- * Symboltabelle nach Adressen sortieren
- */
- a_sort_sym(len)
- register int len;
- {
- register int gap, i, j;
- register struct sym *temp;
-
- for (gap = len/2; gap > 0; gap /= 2)
- for (i = gap; i < len; i++)
- for (j = i-gap; j >= 0; j -= gap) {
- if (numcmp(symarray[j]->sym_wert, symarray[j+gap]->sym_wert) <= 0)
- break;
- temp = symarray[j];
- symarray[j] = symarray[j+gap];
- symarray[j+gap] = temp;
- }
- }
-
- /*
- * Vergleicht zwei 16-Bit Werte, Ergebnis wie strcmp
- */
- numcmp(n1, n2)
- register int n1, n2;
- {
- if ((unsigned) (n1 & 0xffff) < (unsigned) (n2 & 0xffff))
- return(-1);
- else if ((unsigned) (n1 & 0xffff) > (unsigned) (n2 & 0xffff))
- return(1);
- else
- return(0);
- }
-