forked from amberisvibin/chibi-pc09
copy all local files to repo
cp/m files, sprites, circuit design
This commit is contained in:
255
emu/z80pack-1.9/z80asm/z80atab.c
Normal file
255
emu/z80pack-1.9/z80asm/z80atab.c
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Z80 - Assembler
|
||||
* Copyright (C) 1987-2006 by Udo Munk
|
||||
*
|
||||
* History:
|
||||
* 17-SEP-1987 Development under Digital Research CP/M 2.2
|
||||
* 28-JUN-1988 Switched to Unix System V.3
|
||||
* 22-OCT-2006 changed to ANSI C for modern POSIX OS's
|
||||
*/
|
||||
|
||||
/*
|
||||
* module with table oprations on opcode and symbol tables
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "z80a.h"
|
||||
#include "z80aglb.h"
|
||||
|
||||
extern void fatal(int, char *);
|
||||
extern void asmerr(int);
|
||||
|
||||
/*
|
||||
* binary search in sorted table opctab
|
||||
*
|
||||
* Input: pointer to string with opcode
|
||||
*
|
||||
* Output: pointer to table element, or NULL if not found
|
||||
*/
|
||||
struct opc *search_op(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);
|
||||
}
|
||||
|
||||
/*
|
||||
* binary search on sorted table opetab
|
||||
*
|
||||
* Input: pointer to string with operand
|
||||
*
|
||||
* Output: symbol for operand, NOOPERA if empty operand,
|
||||
* NOREG if operand not found
|
||||
*/
|
||||
int get_reg(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);
|
||||
}
|
||||
|
||||
/*
|
||||
* hash search on symbol table symtab
|
||||
*
|
||||
* Input: pointer to string with symbol
|
||||
*
|
||||
* Output: pointer to table element, or NULL if not found
|
||||
*/
|
||||
struct sym *get_sym(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);
|
||||
}
|
||||
|
||||
/*
|
||||
* add symbol to symbol table symtab, or modify existing symbol
|
||||
*
|
||||
* Input: sym_name pointer to string with symbol name
|
||||
* sym_wert value of symbol
|
||||
*
|
||||
* Output: 0 symbol added/modified
|
||||
* 1 out of memory
|
||||
*/
|
||||
int put_sym(char *sym_name, int sym_wert)
|
||||
{
|
||||
struct sym *get_sym();
|
||||
register int hashval;
|
||||
register struct sym *np;
|
||||
|
||||
char *strsave(char *);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* add label to symbol table, error if symbol already exists
|
||||
*/
|
||||
void put_label(void)
|
||||
{
|
||||
struct sym *get_sym(char *);
|
||||
|
||||
if (get_sym(label) == NULL) {
|
||||
if (put_sym(label, pc))
|
||||
fatal(F_OUTMEM, "symbols");
|
||||
} else
|
||||
asmerr(E_MULSYM);
|
||||
}
|
||||
|
||||
/*
|
||||
* hash algorithm
|
||||
*
|
||||
* Input: pointer to string with name
|
||||
*
|
||||
* Output: hash value
|
||||
*/
|
||||
int hash(char *name)
|
||||
{
|
||||
register int hashval;
|
||||
|
||||
for (hashval = 0; *name;)
|
||||
hashval += *name++;
|
||||
return(hashval % HASHSIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
* save string into allocated memory
|
||||
*
|
||||
* Input: pointer to string
|
||||
*
|
||||
* Output: pointer to allocated memory with string
|
||||
*/
|
||||
char *strsave(char *s)
|
||||
{
|
||||
register char *p;
|
||||
|
||||
if ((p = malloc((unsigned) strlen(s)+1)) != NULL)
|
||||
strcpy(p, s);
|
||||
return(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* copy whole symbol hast table into allocated pointer array
|
||||
* used for sorting the symbol table later
|
||||
*/
|
||||
int copy_sym(void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* sort symbol table by name
|
||||
*/
|
||||
void n_sort_sym(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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sort symbol table by address
|
||||
*/
|
||||
void a_sort_sym(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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* compares two 16bit values, result like strcmp()
|
||||
*/
|
||||
int numcmp(int n1, int n2)
|
||||
{
|
||||
if ((unsigned) (n1 & 0xffff) < (unsigned) (n2 & 0xffff))
|
||||
return(-1);
|
||||
else if ((unsigned) (n1 & 0xffff) > (unsigned) (n2 & 0xffff))
|
||||
return(1);
|
||||
else
|
||||
return(0);
|
||||
}
|
Reference in New Issue
Block a user