From 48c64f59592c39f8ffc9dbd6f10ed79f046841a3 Mon Sep 17 00:00:00 2001 From: borutr Date: Fri, 28 Dec 2007 18:39:56 +0000 Subject: [PATCH] * as/asxxsrc/aslex.c: moved from as/mcs51/aslex.c; introduced (readlin) - long lines are turuncated * as/hc08/as_hc08.dsp, as/mcs51/asx8051.dsp, as/z80/as_gbz80.dsp, as/z80/as_z80.dsp, as/hc08/Makefile.in, as/mcs51/Makefile.in, as/z80/Makefile.in: moved aslex.c to asxxsrc * as/hc08/aslex.c, as/z80/aslex.c: deleted * as/z80/asmain.c, as/hc08/asmain.c, as/mcs51/asmain.c: added missing initialization of a_addr field git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4982 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 11 + as/asxxsrc/aslex.c | 556 +++++++++++ as/hc08/Makefile.in | 4 +- as/hc08/as_hc08.dsp | 2 +- as/hc08/aslex.c | 520 ---------- as/hc08/asmain.c | 2233 +++++++++++++++++++++--------------------- as/mcs51/Makefile.in | 4 +- as/mcs51/aslex.c | 520 ---------- as/mcs51/asmain.c | 1 + as/mcs51/asx8051.dsp | 2 +- as/z80/Makefile.in | 4 +- as/z80/as_gbz80.dsp | 3 +- as/z80/as_z80.dsp | 2 +- as/z80/aslex.c | 502 ---------- as/z80/asmain.c | 1 + 15 files changed, 1696 insertions(+), 2669 deletions(-) create mode 100644 as/asxxsrc/aslex.c delete mode 100644 as/hc08/aslex.c delete mode 100644 as/mcs51/aslex.c delete mode 100644 as/z80/aslex.c diff --git a/ChangeLog b/ChangeLog index f4ab4caa..e5cf333e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2007-12-28 Borut Razem + + * as/asxxsrc/aslex.c: moved from as/mcs51/aslex.c; + introduced (readlin) - long lines are turuncated + * as/hc08/as_hc08.dsp, as/mcs51/asx8051.dsp, as/z80/as_gbz80.dsp, + as/z80/as_z80.dsp, as/hc08/Makefile.in, as/mcs51/Makefile.in, + as/z80/Makefile.in: moved aslex.c to asxxsrc + * as/hc08/aslex.c, as/z80/aslex.c: deleted + * as/z80/asmain.c, as/hc08/asmain.c, as/mcs51/asmain.c: + added missing initialization of a_addr field + 2007-12-22 Borut Razem * src/SDCC.lex: fixed bug #1852894: # character hangs the compiler diff --git a/as/asxxsrc/aslex.c b/as/asxxsrc/aslex.c new file mode 100644 index 00000000..41031ebb --- /dev/null +++ b/as/asxxsrc/aslex.c @@ -0,0 +1,556 @@ +/* aslex.c */ + +/* + * (C) Copyright 1989-1995 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + * + * 28-Oct-97 JLH bug in getst(): sign extend on ~(SPACE|ILL) + * causes infinite loop + */ + +/* + * Extensions: P. Felber, M. Hope + */ + +#include +#include +#include +#include "asm.h" + +/*)Module aslex.c + * + * The module aslex.c includes the general lexical + * analysis routines for the assembler. + * + * aslex.c contains the following functions: + * char endline() + * char get() + * VOID getid(id,c) + * int as_getline() + * int getmap() + * char getnb() + * VOID getst() + * int more() + * VOID unget(c) + * + * aslex.c contains no local/static variables + */ + +/*)Function VOID getid(id,c) + * + * char * id a pointer to a string of + * maximum length NCPS + * int c mode flag + * >=0 this is first character to + * copy to the string buffer + * <0 skip white space, first + * character must be a LETTER + * + * The function getid() scans the current assembler-source text line + * from the current position copying the next LETTER | DIGIT string + * into the external string buffer (id). The string ends when a non + * LETTER or DIGIT character is found. The maximum number of + * characters copied is NCPS. If the input string is larger than + * NCPS characters then the string is truncated, if the input string + * is shorter than NCPS characters then the string is NULL filled. + * If the mode argument (c) is >=0 then (c) is the first character + * copied to the string buffer, if (c) is <0 then intervening white + * space (SPACES and TABS) are skipped and the first character found + * must be a LETTER else a 'q' error terminates the parse of this + * assembler-source text line. + * + * local variables: + * char * p pointer to external string buffer + * int c current character value + * + * global variables: + * char ctype[] a character array which defines the + * type of character being processed. + * This index is the character + * being processed. + * + * called functions: + * char get() aslex.c + * char getnb() aslex.c + * VOID unget() aslex.c + * + * side effects: + * use of getnb(), get(), and unget() updates the + * global pointer ip, the position in the current + * assembler-source text line. + */ + +VOID +getid(id, c) +register int c; +char *id; +{ + register char *p; + + if (c < 0) { + c = getnb(); + if ((ctype[c] & LETTER) == 0) + qerr(); + } + p = id; + do { + if (p < &id[NCPS]) + *p++ = c; + } while (ctype[c=get()] & (LETTER|DIGIT)); + unget(c); + while (p < &id[NCPS]) + *p++ = 0; +} + +/*)Function VOID getst(id,c) + * + * char * id a pointer to a string of + * maximum length NCPS + * int c mode flag + * >=0 this is first character to + * copy to the string buffer + * <0 skip white space, first + * character must be a LETTER + * + * The function getnbid() scans the current assembler-source text line + * from the current position copying the next character string into + * the external string buffer (id). The string ends when a SPACE or + * ILL character is found. The maximum number of + * characters copied is NCPS. If the input string is larger than + * NCPS characters then the string is truncated, if the input string + * is shorter than NCPS characters then the string is NULL filled. + * If the mode argument (c) is >=0 then (c) is the first character + * copied to the string buffer, if (c) is <0 then intervening white + * space (SPACES and TABS) are skipped and the first character found + * must be a LETTER else a 'q' error terminates the parse of this + * assembler-source text line. + * + * local variables: + * char * p pointer to external string buffer + * int c current character value + * + * global variables: + * char ctype[] a character array which defines the + * type of character being processed. + * This index is the character + * being processed. + * + * called functions: + * char get() aslex.c + * char getnb() aslex.c + * VOID unget() aslex.c + * + * side effects: + * use of getnb(), get(), and unget() updates the + * global pointer ip, the position in the current + * assembler-source text line. + */ + +VOID +getst(id, c) +register int c; +char *id; +{ + register char *p; + + if (c < 0) { + c = getnb(); + if ((ctype[c] & LETTER) == 0) + qerr(); + } + p = id; + do { + if (p < &id[NCPS]) + *p++ = c; + } while (ctype[c=get()] & (0xFF - (SPACE|ILL))); + unget(c); + while (p < &id[NCPS]) + *p++ = 0; +} + +/*)Function char getnb() + * + * The function getnb() scans the current assembler-source + * text line returning the first character not a SPACE or TAB. + * + * local variables: + * int c current character from + * assembler-source text line + * + * global variables: + * none + * + * called functions: + * char get() aslex.c + * + * side effects: + * use of get() updates the global pointer ip, the position + * in the current assembler-source text line + */ + +char +getnb() +{ + register int c; + + while ((c=get()) == ' ' || c == '\t') + ; + return (c); +} + +/*)Function char get() + * + * The function get() returns the next character in the + * assembler-source text line, at the end of the line a + * NULL character is returned. + * + * local variables: + * int c current character from + * assembler-source text line + * + * global variables: + * char * ip pointer into the current + * assembler-source text line + * + * called functions: + * none + * + * side effects: + * updates ip to the next character position in the + * assembler-source text line. If ip is at the end of the + * line, ip is not updated. + */ + +char +get() +{ + register int c; + + if ((c = *ip) != 0) + ++ip; + return (c); +} + +/*)Function VOID unget(c) + * + * int c value of last character read from + * assembler-source text line + * + * If (c) is not a NULL character then the global pointer ip + * is updated to point to the preceeding character in the + * assembler-source text line. + * + * NOTE: This function does not push the character (c) + * back into the assembler-source text line, only + * the pointer ip is changed. + * + * local variables: + * int c last character read from + * assembler-source text line + * + * global variables: + * char * ip position into the current + * assembler-source text line + * + * called functions: + * none + * + * side effects: + * ip decremented by 1 character position + */ + +VOID +unget(c) +{ + if (c) + if (ip != ib) + --ip; +} + +/*)Function int getmap(d) + * + * int d value to compare with the + * assembler-source text line character + * + * The function getmap() converts the 'C' style characters \b, \f, + * \n, \r, and \t to their equivalent ascii values and also + * converts 'C' style octal constants '\123' to their equivalent + * numeric values. If the first character is equivalent to (d) then + * a (-1) is returned, if the end of the line is detected then + * a 'q' error terminates the parse for this line, or if the first + * character is not a \ then the character value is returned. + * + * local variables: + * int c value of character from the + * assembler-source text line + * int n looping counter + * int v current value of numeric conversion + * + * global variables: + * none + * + * called functions: + * char get() aslex.c + * + * side effects: + * use of get() updates the global pointer ip the position + * in the current assembler-source text line + */ + +int +getmap(d) +{ + register int c, n, v; + + if ((c=get()) == '\0') + qerr(); + if (c == d) + return (-1); + if (c == '\\') { + c = get(); + switch (c) { + + case 'b': + c = '\b'; + break; + + case 'f': + c = '\f'; + break; + + case 'n': + c = '\n'; + break; + + case 'r': + c = '\r'; + break; + + case 't': + c = '\t'; + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + n = 0; + v = 0; + while (++n<=3 && c>='0' && c<='7') { + v = (v<<3) + c - '0'; + c = get(); + } + unget(c); + c = v; + break; + } + } + return (c); +} + +/*)Function char * readlin() + * + * char * str poinetr to beginning of the buffer + * size_t n size of the buffer + * FILE * infp input file pointer + * + * The function readlin() reads a line from a file to the buffer s. + * The buffer length is n. If the line is truncterd to n -1 caharecters + * if it is longer the n - 1 characters. + * Trailing LF or CR/LF are removed from str, if present. + * + * local variables: + * int c character read from the file + * char *s buffer pointer + * satic char eof_f EOF flag + * + * global variables: + * none + * + * called functions: + * int getc c-library + */ + +char * +readlin(char *str, int n, FILE *infp) +{ + int c; + char *s; + static char eof_f = 0; + + if (eof_f) + { + eof_f = 0; + return NULL; + } + + s = str; + while (--n && (c = getc(infp)) != '\n' && c != EOF) + *s++ = c; + + /* chop CR */ + if (s > str && *(s - 1) == '\r') + --s; + + /* terminate the line */ + *s = '\0'; + + /* eat characters until the end of line */ + while (c != '\n' && c != EOF) + c = getc(infp); + + /* if the EOF is not at the beginning of the line, return the line; + return NULL at the next call of redlin */ + if (c == EOF) + { + if (s == str) + return NULL; + eof_f = 1; + } + + return str; +} + +/*)Function int as_getline() + * + * The function as_getline() reads a line of assembler-source text + * from an assembly source text file or an include file. + * Lines of text are processed from assembler-source files until + * all files have been read. If an include file is opened then + * lines of text are read from the include file (or nested + * include file) until the end of the include file is found. + * The input text line is copied into the global string ib[] + * and converted to a NULL terminated string. The function + * as_getline() returns a (1) after succesfully reading a line + * or a (0) if all files have been read. + * + * local variables: + * int i string length + * + * global variables: + * char ib[] string buffer containing + * assembler-source text line + * char ifp[] array of file handles for + * include files + * int incfil index for ifp[] specifies + * active include file + * int incline[] array of include file + * line numbers + * char sfp[] array of file handles for + * assembler source files + * int cfile index for sfp[] specifies + * active source file + * int srcline[] array of source file + * line numbers + * int inpfil maximum input file index + * + * called functions: + * int fclose() c-library + * char * fgets() c-library + * int strlen() c-library + * + * side effects: + * include file will be closed at detection of end of file. + * the next sequential source file may be selected. + * the global file indexes incfil or cfile may be changed. + * The respective source line or include line counter + * will be updated. + */ + +int +as_getline() +{ +loop: if (incfil >= 0) { + if (readlin(ib, sizeof ib, ifp[incfil]) == NULL) { + fclose(ifp[incfil]); + ifp[incfil--] = NULL; + lop = NLPP; + goto loop; + } else { + ++incline[incfil]; + } + } else { + if (readlin(ib, sizeof ib, sfp[cfile]) == NULL) { + if (++cfile <= inpfil) { + srcline[cfile] = 0; + goto loop; + } + return (0); + } else { + ++srcline[cfile]; + } + } + return (1); +} + +/*)Function int more() + * + * The function more() scans the assembler-source text line + * skipping white space (SPACES and TABS) and returns a (0) + * if the end of the line or a comment delimeter (;) is found, + * or a (1) if their are additional characters in the line. + * + * local variables: + * int c next character from the + * assembler-source text line + * + * global variables: + * none + * + * called functions: + * char getnb() aslex.c + * VOID unget() aslex.c + * + * side effects: + * use of getnb() and unget() updates the global pointer ip + * the position in the current assembler-source text line + */ + +int +more() +{ + register int c; + + c = getnb(); + unget(c); + return( (c == '\0' || c == ';') ? 0 : 1 ); +} + +/*)Function char endline() + * + * The function endline() scans the assembler-source text line + * skipping white space (SPACES and TABS) and returns the next + * character or a (0) if the end of the line is found or a + * comment delimiter (;) is found. + * + * local variables: + * int c next character from the + * assembler-source text line + * + * global variables: + * none + * + * called functions: + * char getnb() aslex.c + * + * side effects: + * use of getnb() updates the global pointer ip the + * position in the current assembler-source text line + */ + +char +endline() +{ + register int c; + + c = getnb(); + return( (c == '\0' || c == ';') ? 0 : c ); +} diff --git a/as/hc08/Makefile.in b/as/hc08/Makefile.in index 66cf01f7..65ab660f 100644 --- a/as/hc08/Makefile.in +++ b/as/hc08/Makefile.in @@ -42,9 +42,9 @@ OBJDIR = obj ASXXLIB = $(srcdir)/../asxxsrc -ASXXLIBSRC = strcmpi.c assym.c +ASXXLIBSRC = strcmpi.c assym.c aslex.c -SRC = asmain.c aslex.c assubr.c asnoice.c \ +SRC = asmain.c assubr.c asnoice.c \ asexpr.c asdata.c aslist.c asout.c \ m08ext.c m08pst.c m08mch.c m08adr.c diff --git a/as/hc08/as_hc08.dsp b/as/hc08/as_hc08.dsp index 72dbadee..8cd7b59c 100644 --- a/as/hc08/as_hc08.dsp +++ b/as/hc08/as_hc08.dsp @@ -95,7 +95,7 @@ SOURCE=.\asexpr.c # End Source File # Begin Source File -SOURCE=.\aslex.c +SOURCE=..\asxxsrc\aslex.c # End Source File # Begin Source File diff --git a/as/hc08/aslex.c b/as/hc08/aslex.c deleted file mode 100644 index 42a66ab1..00000000 --- a/as/hc08/aslex.c +++ /dev/null @@ -1,520 +0,0 @@ -/* aslex.c */ - -/* - * (C) Copyright 1989-1995 - * All Rights Reserved - * - * Alan R. Baldwin - * 721 Berkeley St. - * Kent, Ohio 44240 - * - * 28-Oct-97 JLH bug in getst(): sign extend on ~(SPACE|ILL) - * causes infinite loop - */ - -#include -#include -#include -#include "asm.h" - -/*)Module aslex.c - * - * The module aslex.c includes the general lexical - * analysis routines for the assembler. - * - * aslex.c contains the following functions: - * char endline() - * char get() - * VOID getid(id,c) - * int as_getline() - * int getmap() - * char getnb() - * VOID getst() - * int more() - * VOID unget(c) - * - * aslex.c contains no local/static variables - */ - -/*)Function VOID getid(id,c) - * - * char * id a pointer to a string of - * maximum length NCPS - * int c mode flag - * >=0 this is first character to - * copy to the string buffer - * <0 skip white space, first - * character must be a LETTER - * - * The function getid() scans the current assembler-source text line - * from the current position copying the next LETTER | DIGIT string - * into the external string buffer (id). The string ends when a non - * LETTER or DIGIT character is found. The maximum number of - * characters copied is NCPS. If the input string is larger than - * NCPS characters then the string is truncated, if the input string - * is shorter than NCPS characters then the string is NULL filled. - * If the mode argument (c) is >=0 then (c) is the first character - * copied to the string buffer, if (c) is <0 then intervening white - * space (SPACES and TABS) are skipped and the first character found - * must be a LETTER else a 'q' error terminates the parse of this - * assembler-source text line. - * - * local variables: - * char * p pointer to external string buffer - * int c current character value - * - * global variables: - * char ctype[] a character array which defines the - * type of character being processed. - * This index is the character - * being processed. - * - * called functions: - * char get() aslex.c - * char getnb() aslex.c - * VOID unget() aslex.c - * - * side effects: - * use of getnb(), get(), and unget() updates the - * global pointer ip, the position in the current - * assembler-source text line. - */ - -VOID -getid(id, c) -register int c; -char *id; -{ - register char *p; - - if (c < 0) { - c = getnb(); - if ((ctype[c] & LETTER) == 0) - qerr(); - } - p = id; - do { - if (p < &id[NCPS]) - *p++ = c; - } while (ctype[c=get()] & (LETTER|DIGIT)); - unget(c); - while (p < &id[NCPS]) - *p++ = 0; -} - -/*)Function VOID getst(id,c) - * - * char * id a pointer to a string of - * maximum length NCPS - * int c mode flag - * >=0 this is first character to - * copy to the string buffer - * <0 skip white space, first - * character must be a LETTER - * - * The function getnbid() scans the current assembler-source text line - * from the current position copying the next character string into - * the external string buffer (id). The string ends when a SPACE or - * ILL character is found. The maximum number of - * characters copied is NCPS. If the input string is larger than - * NCPS characters then the string is truncated, if the input string - * is shorter than NCPS characters then the string is NULL filled. - * If the mode argument (c) is >=0 then (c) is the first character - * copied to the string buffer, if (c) is <0 then intervening white - * space (SPACES and TABS) are skipped and the first character found - * must be a LETTER else a 'q' error terminates the parse of this - * assembler-source text line. - * - * local variables: - * char * p pointer to external string buffer - * int c current character value - * - * global variables: - * char ctype[] a character array which defines the - * type of character being processed. - * This index is the character - * being processed. - * - * called functions: - * char get() aslex.c - * char getnb() aslex.c - * VOID unget() aslex.c - * - * side effects: - * use of getnb(), get(), and unget() updates the - * global pointer ip, the position in the current - * assembler-source text line. - */ - -VOID -getst(id, c) -register int c; -char *id; -{ - register char *p; - - if (c < 0) { - c = getnb(); - if ((ctype[c] & LETTER) == 0) - qerr(); - } - p = id; - do { - if (p < &id[NCPS]) - *p++ = c; - } while (ctype[c=get()] & (0xFF - (SPACE|ILL))); - unget(c); - while (p < &id[NCPS]) - *p++ = 0; -} - -/*)Function char getnb() - * - * The function getnb() scans the current assembler-source - * text line returning the first character not a SPACE or TAB. - * - * local variables: - * int c current character from - * assembler-source text line - * - * global variables: - * none - * - * called functions: - * char get() aslex.c - * - * side effects: - * use of get() updates the global pointer ip, the position - * in the current assembler-source text line - */ - -char -getnb() -{ - register int c; - - while ((c=get()) == ' ' || c == '\t') - ; - return (c); -} - -/*)Function char get() - * - * The function get() returns the next character in the - * assembler-source text line, at the end of the line a - * NULL character is returned. - * - * local variables: - * int c current character from - * assembler-source text line - * - * global variables: - * char * ip pointer into the current - * assembler-source text line - * - * called functions: - * none - * - * side effects: - * updates ip to the next character position in the - * assembler-source text line. If ip is at the end of the - * line, ip is not updated. - */ - -char -get() -{ - register int c; - - if ((c = *ip) != 0) - ++ip; - return (c); -} - -/*)Function VOID unget(c) - * - * int c value of last character read from - * assembler-source text line - * - * If (c) is not a NULL character then the global pointer ip - * is updated to point to the preceeding character in the - * assembler-source text line. - * - * NOTE: This function does not push the character (c) - * back into the assembler-source text line, only - * the pointer ip is changed. - * - * local variables: - * int c last character read from - * assembler-source text line - * - * global variables: - * char * ip position into the current - * assembler-source text line - * - * called functions: - * none - * - * side effects: - * ip decremented by 1 character position - */ - -VOID -unget(c) -{ - if (c) - if (ip != ib) - --ip; -} - -/*)Function int getmap(d) - * - * int d value to compare with the - * assembler-source text line character - * - * The function getmap() converts the 'C' style characters \b, \f, - * \n, \r, and \t to their equivalent ascii values and also - * converts 'C' style octal constants '\123' to their equivalent - * numeric values. If the first character is equivalent to (d) then - * a (-1) is returned, if the end of the line is detected then - * a 'q' error terminates the parse for this line, or if the first - * character is not a \ then the character value is returned. - * - * local variables: - * int c value of character from the - * assembler-source text line - * int n looping counter - * int v current value of numeric conversion - * - * global variables: - * none - * - * called functions: - * char get() aslex.c - * - * side effects: - * use of get() updates the global pointer ip the position - * in the current assembler-source text line - */ - -int -getmap(d) -{ - register int c, n, v; - - if ((c=get()) == '\0') - qerr(); - if (c == d) - return (-1); - if (c == '\\') { - c = get(); - switch (c) { - - case 'b': - c = '\b'; - break; - - case 'f': - c = '\f'; - break; - - case 'n': - c = '\n'; - break; - - case 'r': - c = '\r'; - break; - - case 't': - c = '\t'; - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - n = 0; - v = 0; - while (++n<=3 && c>='0' && c<='7') { - v = (v<<3) + c - '0'; - c = get(); - } - unget(c); - c = v; - break; - } - } - return (c); -} - -/*)Function int as_getline() - * - * The function as_getline() reads a line of assembler-source text - * from an assembly source text file or an include file. - * Lines of text are processed from assembler-source files until - * all files have been read. If an include file is opened then - * lines of text are read from the include file (or nested - * include file) until the end of the include file is found. - * The input text line is copied into the global string ib[] - * and converted to a NULL terminated string. The function - * as_getline() returns a (1) after succesfully reading a line - * or a (0) if all files have been read. - * - * local variables: - * int i string length - * - * global variables: - * char ib[] string buffer containing - * assembler-source text line - * char ifp[] array of file handles for - * include files - * int incfil index for ifp[] specifies - * active include file - * int incline[] array of include file - * line numbers - * char sfp[] array of file handles for - * assembler source files - * int cfile index for sfp[] specifies - * active source file - * int srcline[] array of source file - * line numbers - * int inpfil maximum input file index - * - * called functions: - * int fclose() c-library - * char * fgets() c-library - * int strlen() c-library - * - * side effects: - * include file will be closed at detection of end of file. - * the next sequential source file may be selected. - * the global file indexes incfil or cfile may be changed. - * The respective source line or include line counter - * will be updated. - */ - -int -as_getline() -{ -loop: if (incfil >= 0) { - if (fgets(ib, sizeof ib, ifp[incfil]) == NULL) { - fclose(ifp[incfil--]); - lop = NLPP; - goto loop; - } else { - ++incline[incfil]; - } - } else { - if (fgets(ib, sizeof ib, sfp[cfile]) == NULL) { - if (++cfile <= inpfil) { - srcline[cfile] = 0; - goto loop; - } - return (0); - } else { - ++srcline[cfile]; - } - } - chop_crlf(ib); - return (1); -} - -/*)Function int more() - * - * The function more() scans the assembler-source text line - * skipping white space (SPACES and TABS) and returns a (0) - * if the end of the line or a comment delimeter (;) is found, - * or a (1) if their are additional characters in the line. - * - * local variables: - * int c next character from the - * assembler-source text line - * - * global variables: - * none - * - * called functions: - * char getnb() aslex.c - * VOID unget() aslex.c - * - * side effects: - * use of getnb() and unget() updates the global pointer ip - * the position in the current assembler-source text line - */ - -int -more() -{ - register int c; - - c = getnb(); - unget(c); - return( (c == '\0' || c == ';') ? 0 : 1 ); -} - -/*)Function char endline() - * - * The function endline() scans the assembler-source text line - * skipping white space (SPACES and TABS) and returns the next - * character or a (0) if the end of the line is found or a - * comment delimiter (;) is found. - * - * local variables: - * int c next character from the - * assembler-source text line - * - * global variables: - * none - * - * called functions: - * char getnb() aslex.c - * - * side effects: - * use of getnb() updates the global pointer ip the - * position in the current assembler-source text line - */ - -char -endline() -{ - register int c; - - c = getnb(); - return( (c == '\0' || c == ';') ? 0 : c ); -} - -/*)Function VOID chop_crlf(str) - * - * char *str string to chop - * - * The function chop_crlf() removes trailing LF or CR/LF from - * str, if present. - * - * local variables: - * int i string length - * - * global variables: - * none - * - * functions called: - * none - * - * side effects: - * none - */ - -VOID -chop_crlf(str) -char *str; -{ - register int i; - - i = strlen(str); - if (i >= 1 && str[i-1] == '\n') str[i-1] = 0; - if (i >= 2 && str[i-2] == '\r') str[i-2] = 0; -} diff --git a/as/hc08/asmain.c b/as/hc08/asmain.c index 633786b7..3621249a 100644 --- a/as/hc08/asmain.c +++ b/as/hc08/asmain.c @@ -18,133 +18,133 @@ #include "asm.h" -/*)Module asmain.c +/*)Module asmain.c * - * The module asmain.c includes the command argument parser, - * the three pass sequencer, and the machine independent - * assembler parsing code. + * The module asmain.c includes the command argument parser, + * the three pass sequencer, and the machine independent + * assembler parsing code. * - * asmain.c contains the following functions: - * VOID main(argc, argv) - * VOID asexit() - * VOID asmbl() - * FILE * afile(fn, ft, wf) - * VOID newdot(nap) - * VOID phase(ap, a) - * VOID usage() + * asmain.c contains the following functions: + * VOID main(argc, argv) + * VOID asexit() + * VOID asmbl() + * FILE * afile(fn, ft, wf) + * VOID newdot(nap) + * VOID phase(ap, a) + * VOID usage() * - * asmain.c contains the array char *usetxt[] which - * references the usage text strings printed by usage(). + * asmain.c contains the array char *usetxt[] which + * references the usage text strings printed by usage(). */ -/*)Function VOID main(argc, argv) +/*)Function VOID main(argc, argv) * - * int argc argument count - * char * argv array of pointers to argument strings + * int argc argument count + * char * argv array of pointers to argument strings * - * The function main() is the entry point to the assembler. - * The purpose of main() is to (1) parse the command line - * arguments for options and source file specifications and - * (2) to process the source files through the 3 pass assembler. - * Before each assembler pass various variables are initialized - * and source files are rewound to their beginning. During each - * assembler pass each assembler-source text line is processed. - * After each assembler pass the assembler information is flushed - * to any opened output files and the if-else-endif processing - * is checked for proper termination. + * The function main() is the entry point to the assembler. + * The purpose of main() is to (1) parse the command line + * arguments for options and source file specifications and + * (2) to process the source files through the 3 pass assembler. + * Before each assembler pass various variables are initialized + * and source files are rewound to their beginning. During each + * assembler pass each assembler-source text line is processed. + * After each assembler pass the assembler information is flushed + * to any opened output files and the if-else-endif processing + * is checked for proper termination. * - * The function main() is also responsible for opening all - * output files (REL, LST, and SYM), sequencing the global (-g) - * and all-global (-a) variable definitions, and dumping the - * REL file header information. + * The function main() is also responsible for opening all + * output files (REL, LST, and SYM), sequencing the global (-g) + * and all-global (-a) variable definitions, and dumping the + * REL file header information. * - * local variables: - * char * p pointer to argument string - * int c character from argument string - * int i argument loop counter - * area * ap pointer to area structure + * local variables: + * char * p pointer to argument string + * int c character from argument string + * int i argument loop counter + * area * ap pointer to area structure * - * global variables: - * int aflag -a, make all symbols global flag - * char afn[] afile() constructed filespec - * area * areap pointer to an area structure - * int cb[] array of assembler output values - * int cbt[] array of assembler relocation types - * describing the data in cb[] - * int cfile current file handle index - * of input assembly files - * int * cp pointer to assembler output array cb[] - * int * cpt pointer to assembler relocation type - * output array cbt[] - * char eb[] array of generated error codes - * char * ep pointer into error list array eb[] - * int fflag -f(f), relocations flagged flag - * int flevel IF-ELSE-ENDIF flag will be non - * zero for false conditional case - * Addr_T fuzz tracks pass to pass changes in the - * address of symbols caused by - * variable length instruction formats - * int gflag -g, make undefined symbols global flag - * char ib[] assembler-source text line - * int inpfil count of assembler - * input files specified - * int ifcnd[] array of IF statement condition - * values (0 = FALSE) indexed by tlevel - * int iflvl[] array of IF-ELSE-ENDIF flevel - * values indexed by tlevel - * int incfil current file handle index - * for include files - * char * ip pointer into the assembler-source - * text line in ib[] - * jmp_buf jump_env compiler dependent structure - * used by setjmp() and longjmp() - * int lflag -l, generate listing flag - * int line current assembler source - * line number - * int lop current line number on page - * int oflag -o, generate relocatable output flag - * int jflag -j, generate debug info flag - * int page current page number - * int pflag enable listing pagination - * int pass assembler pass number - * int radix current number conversion radix: - * 2 (binary), 8 (octal), 10 (decimal), - * 16 (hexadecimal) - * int sflag -s, generate symbol table flag - * char srcfn[][] array of source file names - * int srcline[] current source file line - * char stb[] Subtitle string buffer - * sym * symp pointer to a symbol structure - * int tlevel current conditional level - * int xflag -x, listing radix flag - * FILE * lfp list output file handle - * FILE * ofp relocation output file handle - * FILE * tfp symbol table output file handle - * FILE * sfp[] array of assembler-source file handles + * global variables: + * int aflag -a, make all symbols global flag + * char afn[] afile() constructed filespec + * area * areap pointer to an area structure + * int cb[] array of assembler output values + * int cbt[] array of assembler relocation types + * describing the data in cb[] + * int cfile current file handle index + * of input assembly files + * int * cp pointer to assembler output array cb[] + * int * cpt pointer to assembler relocation type + * output array cbt[] + * char eb[] array of generated error codes + * char * ep pointer into error list array eb[] + * int fflag -f(f), relocations flagged flag + * int flevel IF-ELSE-ENDIF flag will be non + * zero for false conditional case + * Addr_T fuzz tracks pass to pass changes in the + * address of symbols caused by + * variable length instruction formats + * int gflag -g, make undefined symbols global flag + * char ib[] assembler-source text line + * int inpfil count of assembler + * input files specified + * int ifcnd[] array of IF statement condition + * values (0 = FALSE) indexed by tlevel + * int iflvl[] array of IF-ELSE-ENDIF flevel + * values indexed by tlevel + * int incfil current file handle index + * for include files + * char * ip pointer into the assembler-source + * text line in ib[] + * jmp_buf jump_env compiler dependent structure + * used by setjmp() and longjmp() + * int lflag -l, generate listing flag + * int line current assembler source + * line number + * int lop current line number on page + * int oflag -o, generate relocatable output flag + * int jflag -j, generate debug info flag + * int page current page number + * int pflag enable listing pagination + * int pass assembler pass number + * int radix current number conversion radix: + * 2 (binary), 8 (octal), 10 (decimal), + * 16 (hexadecimal) + * int sflag -s, generate symbol table flag + * char srcfn[][] array of source file names + * int srcline[] current source file line + * char stb[] Subtitle string buffer + * sym * symp pointer to a symbol structure + * int tlevel current conditional level + * int xflag -x, listing radix flag + * FILE * lfp list output file handle + * FILE * ofp relocation output file handle + * FILE * tfp symbol table output file handle + * FILE * sfp[] array of assembler-source file handles * - * called functions: - * FILE * afile() asmain.c - * VOID allglob() assym.c - * VOID asexit() asmain.c - * VOID diag() assubr.c - * VOID err() assubr.c - * int fprintf() c-library - * int as_getline() aslex.c - * VOID list() aslist.c - * VOID lstsym() aslist.c - * VOID minit() ___mch.c - * VOID newdot() asmain.c - * VOID outchk() asout.c - * VOID outgsd() asout.c - * int rewind() c-library - * int setjmp() c-library - * VOID symglob() assym.c - * VOID syminit() assym.c - * VOID usage() asmain.c + * called functions: + * FILE * afile() asmain.c + * VOID allglob() assym.c + * VOID asexit() asmain.c + * VOID diag() assubr.c + * VOID err() assubr.c + * int fprintf() c-library + * int as_getline() aslex.c + * VOID list() aslist.c + * VOID lstsym() aslist.c + * VOID minit() ___mch.c + * VOID newdot() asmain.c + * VOID outchk() asout.c + * VOID outgsd() asout.c + * int rewind() c-library + * int setjmp() c-library + * VOID symglob() assym.c + * VOID syminit() assym.c + * VOID usage() asmain.c * - * side effects: - * Completion of main() completes the assembly process. - * REL, LST, and/or SYM files may be generated. + * side effects: + * Completion of main() completes the assembly process. + * REL, LST, and/or SYM files may be generated. */ int fatalErrors=0; @@ -154,145 +154,145 @@ int main(argc, argv) char *argv[]; { - register char *p; - register int c, i; - struct area *ap; - - /*fprintf(stdout, "\n");*/ - inpfil = -1; - pflag = 1; - for (i=1; i= 0) - usage(); - ++p; - while ((c = *p++) != 0) - switch(c) { - - case 'a': - case 'A': - ++aflag; - break; - - case 'c': - case 'C': - ++cflag; - break; - - case 'g': - case 'G': - ++gflag; - break; - - case 'j': /* JLH: debug info */ - case 'J': - ++jflag; - ++oflag; /* force object */ - break; - - case 'l': - case 'L': - ++lflag; - break; - - case 'o': - case 'O': - ++oflag; - break; - - case 's': - case 'S': - ++sflag; - break; - - case 'p': - case 'P': - pflag = 0; - break; - - case 'x': - case 'X': - xflag = 0; - break; - - case 'q': - case 'Q': - xflag = 1; - break; - - case 'd': - case 'D': - xflag = 2; - break; - - case 'f': - case 'F': - ++fflag; - break; - - default: - usage(); - } - } else { - if (++inpfil == MAXFIL) { - fprintf(stderr, "too many input files\n"); - asexit(1); - } - sfp[inpfil] = afile(p, "", 0); - strcpy(srcfn[inpfil],afn); - if (inpfil == 0) { - if (lflag) - lfp = afile(p, "lst", 1); - if (oflag) { - ofp = afile(p, "rel", 1); - // save the file name if we have to delete it on error - strcpy(relFile,afn); - } - if (sflag) - tfp = afile(p, "sym", 1); - } - } - } - if (inpfil < 0) - usage(); - syminit(); - for (pass=0; pass<3; ++pass) { - if (gflag && pass == 1) - symglob(); - if (aflag && pass == 1) - allglob(); - if (oflag && pass == 2) - outgsd(); - flevel = 0; - tlevel = 0; - ifcnd[0] = 0; - iflvl[0] = 0; - radix = 10; - srcline[0] = 0; - page = 0; - stb[0] = 0; - lop = NLPP; - cfile = 0; - incfil = -1; - for (i = 0; i <= inpfil; i++) - rewind(sfp[i]); - ap = areap; - while (ap) { - ap->a_fuzz = 0; - ap->a_size = 0; - ap = ap->a_ap; - } - fuzz = 0; - dot.s_addr = 0; - dot.s_area = &dca; - symp = ˙ - minit(); - while (as_getline()) { - cp = cb; - cpt = cbt; - ep = eb; - ip = ib; + register char *p; + register int c, i; + struct area *ap; + + /*fprintf(stdout, "\n");*/ + inpfil = -1; + pflag = 1; + for (i=1; i= 0) + usage(); + ++p; + while ((c = *p++) != 0) + switch(c) { + + case 'a': + case 'A': + ++aflag; + break; + + case 'c': + case 'C': + ++cflag; + break; + + case 'g': + case 'G': + ++gflag; + break; + + case 'j': /* JLH: debug info */ + case 'J': + ++jflag; + ++oflag; /* force object */ + break; + + case 'l': + case 'L': + ++lflag; + break; + + case 'o': + case 'O': + ++oflag; + break; + + case 's': + case 'S': + ++sflag; + break; + + case 'p': + case 'P': + pflag = 0; + break; + + case 'x': + case 'X': + xflag = 0; + break; + + case 'q': + case 'Q': + xflag = 1; + break; + + case 'd': + case 'D': + xflag = 2; + break; + + case 'f': + case 'F': + ++fflag; + break; + + default: + usage(); + } + } else { + if (++inpfil == MAXFIL) { + fprintf(stderr, "too many input files\n"); + asexit(1); + } + sfp[inpfil] = afile(p, "", 0); + strcpy(srcfn[inpfil],afn); + if (inpfil == 0) { + if (lflag) + lfp = afile(p, "lst", 1); + if (oflag) { + ofp = afile(p, "rel", 1); + // save the file name if we have to delete it on error + strcpy(relFile,afn); + } + if (sflag) + tfp = afile(p, "sym", 1); + } + } + } + if (inpfil < 0) + usage(); + syminit(); + for (pass=0; pass<3; ++pass) { + if (gflag && pass == 1) + symglob(); + if (aflag && pass == 1) + allglob(); + if (oflag && pass == 2) + outgsd(); + flevel = 0; + tlevel = 0; + ifcnd[0] = 0; + iflvl[0] = 0; + radix = 10; + srcline[0] = 0; + page = 0; + stb[0] = 0; + lop = NLPP; + cfile = 0; + incfil = -1; + for (i = 0; i <= inpfil; i++) + rewind(sfp[i]); + ap = areap; + while (ap) { + ap->a_fuzz = 0; + ap->a_size = 0; + ap = ap->a_ap; + } + fuzz = 0; + dot.s_addr = 0; + dot.s_area = &dca; + symp = ˙ + minit(); + while (as_getline()) { + cp = cb; + cpt = cbt; + ep = eb; + ip = ib; /* JLH: if line begins with ";!", then * pass this comment on to the output file @@ -300,731 +300,732 @@ char *argv[]; if (oflag && (pass == 1) && (ip[0] == ';') && (ip[1] == '!')) { - fprintf(ofp, "%s\n", ip ); + fprintf(ofp, "%s\n", ip ); } - - if (setjmp(jump_env) == 0) - asmbl(); - - if (pass == 2) { - diag(); - list(); - } - } - newdot(dot.s_area); /* Flush area info */ - if (flevel || tlevel) - err('i'); - } - if (oflag) - outchk(HUGE, HUGE); /* Flush */ - if (sflag) { - lstsym(tfp); - } else - if (lflag) { - lstsym(lfp); - } - //printf ("aserr: %d\n", aserr); - //printf ("fatalErrors: %d\n", fatalErrors); - asexit(fatalErrors); - return 0; // hush the compiler + + if (setjmp(jump_env) == 0) + asmbl(); + + if (pass == 2) { + diag(); + list(); + } + } + newdot(dot.s_area); /* Flush area info */ + if (flevel || tlevel) + err('i'); + } + if (oflag) + outchk(HUGE, HUGE); /* Flush */ + if (sflag) { + lstsym(tfp); + } else + if (lflag) { + lstsym(lfp); + } + //printf ("aserr: %d\n", aserr); + //printf ("fatalErrors: %d\n", fatalErrors); + asexit(fatalErrors); + return 0; // hush the compiler } -/*)Function VOID asexit(i) +/*)Function VOID asexit(i) * - * int i exit code + * int i exit code * - * The function asexit() explicitly closes all open - * files and then terminates the program. + * The function asexit() explicitly closes all open + * files and then terminates the program. * - * local variables: - * int j loop counter + * local variables: + * int j loop counter * - * global variables: - * FILE * ifp[] array of include-file file handles - * FILE * lfp list output file handle - * FILE * ofp relocation output file handle - * FILE * tfp symbol table output file handle - * FILE * sfp[] array of assembler-source file handles + * global variables: + * FILE * ifp[] array of include-file file handles + * FILE * lfp list output file handle + * FILE * ofp relocation output file handle + * FILE * tfp symbol table output file handle + * FILE * sfp[] array of assembler-source file handles * - * functions called: - * int fclose() c-library - * VOID exit() c-library + * functions called: + * int fclose() c-library + * VOID exit() c-library * - * side effects: - * All files closed. Program terminates. + * side effects: + * All files closed. Program terminates. */ VOID asexit(i) int i; { - int j; - - if (lfp != NULL) fclose(lfp); - if (ofp != NULL) fclose(ofp); - if (tfp != NULL) fclose(tfp); - - for (j=0; j= 0) { - n = 10*n + d; - c = get(); - } - if (c != '$' || get() != ':') - qerr(); - tp = symp->s_tsym; - if (pass == 0) { - while (tp) { - if (n == tp->t_num) { - tp->t_flg |= S_MDF; - break; - } - tp = tp->t_lnk; - } - if (tp == NULL) { - tp=(struct tsym *) new (sizeof(struct tsym)); - tp->t_lnk = symp->s_tsym; - tp->t_num = n; - tp->t_flg = 0; - tp->t_area = dot.s_area; - tp->t_addr = dot.s_addr; - symp->s_tsym = tp; - } - } else { - while (tp) { - if (n == tp->t_num) { - break; - } - tp = tp->t_lnk; - } - if (tp) { - if (pass == 1) { - fuzz = tp->t_addr - dot.s_addr; - tp->t_area = dot.s_area; - tp->t_addr = dot.s_addr; - } else { - phase(tp->t_area, tp->t_addr); - if (tp->t_flg & S_MDF) - err('m'); - } - } else { - err('u'); - } - } - lmode = ALIST; - goto loop; - } - /* - * If the first character is a letter then assume a label, - * symbol, assembler directive, or assembler mnemonic is - * being processed. - */ - if ((ctype[c] & LETTER) == 0) { - if (flevel) { - return; - } else { - qerr(); - } - } - getid(id, c); - c = getnb(); - /* - * If the next character is a : then a label is being processed. - * A double :: defines a global label. If this is new label - * then create a symbol structure. - * pass 0: - * Flag multiply defined labels. - * pass 1: - * Load area, address, and fuzz values - * into structure symp. - * pass 2: - * Check for assembler phase error and - * multiply defined error. - */ - if (c == ':') { - if (flevel) - return; - if ((c = get()) != ':') { - unget(c); - c = 0; - } - symp = lookup(id); - if (symp == &dot) - err('.'); - if (pass == 0) - if ((symp->s_type != S_NEW) && - ((symp->s_flag & S_ASG) == 0)) - symp->s_flag |= S_MDF; - if (pass != 2) { - fuzz = symp->s_addr - dot.s_addr; - symp->s_type = S_USER; - symp->s_area = dot.s_area; - symp->s_addr = dot.s_addr; - } else { - if (symp->s_flag & S_MDF) - err('m'); - phase(symp->s_area, symp->s_addr); - } - if (c) { - symp->s_flag |= S_GBL; - } - lmode = ALIST; - goto loop; - } - /* - * If the next character is a = then an equate is being processed. - * A double == defines a global equate. If this is new variable - * then create a symbol structure. - */ - if (c == '=') { - if (flevel) - return; - if ((c = get()) != '=') { - unget(c); - c = 0; - } - clrexpr(&e1); - expr(&e1, 0); - sp = lookup(id); - if (sp == &dot) { - outall(); - if (e1.e_flag || e1.e_base.e_ap != dot.s_area) - err('.'); - } else - if (sp->s_type != S_NEW && (sp->s_flag & S_ASG) == 0) { - err('m'); - } - sp->s_type = S_USER; - sp->s_area = e1.e_base.e_ap; - sp->s_addr = laddr = e1.e_addr; - sp->s_flag |= S_ASG; - if (c) { - sp->s_flag |= S_GBL; - } - lmode = ELIST; - goto loop; - } - unget(c); - lmode = flevel ? SLIST : CLIST; - if ((mp = mlookup(id)) == NULL) { - if (!flevel) - err('o'); - return; - } - /* - * If we have gotten this far then we have found an - * assembler directive or an assembler mnemonic. - * - * Check for .if, .else, .endif, and .page directives - * which are not controlled by the conditional flags - */ - switch (mp->m_type) { - - case S_IF: - n = absexpr(); - if (tlevel < MAXIF) { - ++tlevel; - ifcnd[tlevel] = n; - iflvl[tlevel] = flevel; - if (n == 0) { - ++flevel; - } - } else { - err('i'); - } - lmode = ELIST; - laddr = n; - return; - - case S_ELSE: - if (ifcnd[tlevel]) { - if (++flevel > (iflvl[tlevel]+1)) { - err('i'); - } - } else { - if (--flevel < iflvl[tlevel]) { - err('i'); - } - } - lmode = SLIST; - return; - - case S_ENDIF: - if (tlevel) { - flevel = iflvl[tlevel--]; - } else { - err('i'); - } - lmode = SLIST; - return; - - case S_PAGE: - lop = NLPP; - lmode = NLIST; - return; - - default: - break; - } - if (flevel) - return; - /* - * If we are not in a false state for .if/.else then - * process the assembler directives here. - */ - switch (mp->m_type) { - - case S_EVEN: - outall(); - laddr = dot.s_addr = (dot.s_addr + 1) & ~1; - lmode = ALIST; - break; - - case S_ODD: - outall(); - laddr = dot.s_addr |= 1; - lmode = ALIST; - break; - - case S_BYTE: - case S_WORD: - do { - clrexpr(&e1); - expr(&e1, 0); - if (mp->m_type == S_BYTE) { - outrb(&e1, R_NORM); - } else { - outrw(&e1, R_NORM); - } - } while ((c = getnb()) == ','); - unget(c); - break; - - case S_ULEB128: - case S_SLEB128: - do { - Addr_T val = absexpr(); - int bit = sizeof(val)*8 - 1; - int impliedBit; - - if (mp->m_type == S_ULEB128) { - impliedBit = 0; - } else { - impliedBit = (val & (1 << bit)) ? 1 : 0; - } - while ((bit>0) && (((val & (1 << bit)) ? 1 : 0) == impliedBit)) { - bit--; - } - if (mp->m_type == S_SLEB128) { - bit++; - } - while (bit>=0) { - if (bit<7) { - outab(val & 0x7f); - } else { - outab(0x80 | (val & 0x7f)); - } - bit -= 7; - val >>= 7; - } - } while ((c = getnb()) == ','); - unget(c); - break; - - case S_ASCII: - case S_ASCIZ: - if ((d = getnb()) == '\0') - qerr(); - while ((c = getmap(d)) >= 0) - outab(c); - if (mp->m_type == S_ASCIZ) - outab(0); - break; - - case S_ASCIS: - if ((d = getnb()) == '\0') - qerr(); - c = getmap(d); - while (c >= 0) { - if ((n = getmap(d)) >= 0) { - outab(c); - } else { - outab(c | 0x80); - } - c = n; - } - break; - - case S_BLK: - clrexpr(&e1); - expr(&e1, 0); - outchk(HUGE,HUGE); - dot.s_addr += e1.e_addr*mp->m_valu; - lmode = BLIST; - break; - - case S_TITLE: - p = tb; - if ((c = getnb()) != 0) { - do { - if (p < &tb[NTITL-1]) - *p++ = c; - } while ((c = get()) != 0); - } - *p = 0; - unget(c); - lmode = SLIST; - break; - - case S_SBTL: - p = stb; - if ((c = getnb()) != 0) { - do { - if (p < &stb[NSBTL-1]) - *p++ = c; - } while ((c = get()) != 0); - } - *p = 0; - unget(c); - lmode = SLIST; - break; - - case S_MODUL: - getst(id, getnb()); // a module can start with a digit - if (pass == 0) { - if (module[0]) { - err('m'); - } else { - strncpy(module, id, NCPS); - } - } - lmode = SLIST; - break; + if ((c=endline()) == 0) { return; } + /* + * If the first character is a digit then assume + * a local symbol is being specified. The symbol + * must end with $: to be valid. + * pass 0: + * Construct a tsym structure at the first + * occurance of the symbol. Flag the symbol + * as multiply defined if not the first occurance. + * pass 1: + * Load area, address, and fuzz values + * into structure tsym. + * pass 2: + * Check for assembler phase error and + * multiply defined error. + */ + if (ctype[c] & DIGIT) { + if (flevel) + return; + n = 0; + while ((d = digit(c, 10)) >= 0) { + n = 10*n + d; + c = get(); + } + if (c != '$' || get() != ':') + qerr(); + tp = symp->s_tsym; + if (pass == 0) { + while (tp) { + if (n == tp->t_num) { + tp->t_flg |= S_MDF; + break; + } + tp = tp->t_lnk; + } + if (tp == NULL) { + tp=(struct tsym *) new (sizeof(struct tsym)); + tp->t_lnk = symp->s_tsym; + tp->t_num = n; + tp->t_flg = 0; + tp->t_area = dot.s_area; + tp->t_addr = dot.s_addr; + symp->s_tsym = tp; + } + } else { + while (tp) { + if (n == tp->t_num) { + break; + } + tp = tp->t_lnk; + } + if (tp) { + if (pass == 1) { + fuzz = tp->t_addr - dot.s_addr; + tp->t_area = dot.s_area; + tp->t_addr = dot.s_addr; + } else { + phase(tp->t_area, tp->t_addr); + if (tp->t_flg & S_MDF) + err('m'); + } + } else { + err('u'); + } + } + lmode = ALIST; + goto loop; + } + /* + * If the first character is a letter then assume a label, + * symbol, assembler directive, or assembler mnemonic is + * being processed. + */ + if ((ctype[c] & LETTER) == 0) { + if (flevel) { + return; + } else { + qerr(); + } + } + getid(id, c); + c = getnb(); + /* + * If the next character is a : then a label is being processed. + * A double :: defines a global label. If this is new label + * then create a symbol structure. + * pass 0: + * Flag multiply defined labels. + * pass 1: + * Load area, address, and fuzz values + * into structure symp. + * pass 2: + * Check for assembler phase error and + * multiply defined error. + */ + if (c == ':') { + if (flevel) + return; + if ((c = get()) != ':') { + unget(c); + c = 0; + } + symp = lookup(id); + if (symp == &dot) + err('.'); + if (pass == 0) + if ((symp->s_type != S_NEW) && + ((symp->s_flag & S_ASG) == 0)) + symp->s_flag |= S_MDF; + if (pass != 2) { + fuzz = symp->s_addr - dot.s_addr; + symp->s_type = S_USER; + symp->s_area = dot.s_area; + symp->s_addr = dot.s_addr; + } else { + if (symp->s_flag & S_MDF) + err('m'); + phase(symp->s_area, symp->s_addr); + } + if (c) { + symp->s_flag |= S_GBL; + } + lmode = ALIST; + goto loop; + } + /* + * If the next character is a = then an equate is being processed. + * A double == defines a global equate. If this is new variable + * then create a symbol structure. + */ + if (c == '=') { + if (flevel) + return; + if ((c = get()) != '=') { + unget(c); + c = 0; + } + clrexpr(&e1); + expr(&e1, 0); + sp = lookup(id); + if (sp == &dot) { + outall(); + if (e1.e_flag || e1.e_base.e_ap != dot.s_area) + err('.'); + } else + if (sp->s_type != S_NEW && (sp->s_flag & S_ASG) == 0) { + err('m'); + } + sp->s_type = S_USER; + sp->s_area = e1.e_base.e_ap; + sp->s_addr = laddr = e1.e_addr; + sp->s_flag |= S_ASG; + if (c) { + sp->s_flag |= S_GBL; + } + lmode = ELIST; + goto loop; + } + unget(c); + lmode = flevel ? SLIST : CLIST; + if ((mp = mlookup(id)) == NULL) { + if (!flevel) + err('o'); + return; + } + /* + * If we have gotten this far then we have found an + * assembler directive or an assembler mnemonic. + * + * Check for .if, .else, .endif, and .page directives + * which are not controlled by the conditional flags + */ + switch (mp->m_type) { + + case S_IF: + n = absexpr(); + if (tlevel < MAXIF) { + ++tlevel; + ifcnd[tlevel] = n; + iflvl[tlevel] = flevel; + if (n == 0) { + ++flevel; + } + } else { + err('i'); + } + lmode = ELIST; + laddr = n; + return; + + case S_ELSE: + if (ifcnd[tlevel]) { + if (++flevel > (iflvl[tlevel]+1)) { + err('i'); + } + } else { + if (--flevel < iflvl[tlevel]) { + err('i'); + } + } + lmode = SLIST; + return; + + case S_ENDIF: + if (tlevel) { + flevel = iflvl[tlevel--]; + } else { + err('i'); + } + lmode = SLIST; + return; + + case S_PAGE: + lop = NLPP; + lmode = NLIST; + return; + + default: + break; + } + if (flevel) + return; + /* + * If we are not in a false state for .if/.else then + * process the assembler directives here. + */ + switch (mp->m_type) { + + case S_EVEN: + outall(); + laddr = dot.s_addr = (dot.s_addr + 1) & ~1; + lmode = ALIST; + break; + + case S_ODD: + outall(); + laddr = dot.s_addr |= 1; + lmode = ALIST; + break; + + case S_BYTE: + case S_WORD: + do { + clrexpr(&e1); + expr(&e1, 0); + if (mp->m_type == S_BYTE) { + outrb(&e1, R_NORM); + } else { + outrw(&e1, R_NORM); + } + } while ((c = getnb()) == ','); + unget(c); + break; + + case S_ULEB128: + case S_SLEB128: + do { + Addr_T val = absexpr(); + int bit = sizeof(val)*8 - 1; + int impliedBit; + + if (mp->m_type == S_ULEB128) { + impliedBit = 0; + } else { + impliedBit = (val & (1 << bit)) ? 1 : 0; + } + while ((bit>0) && (((val & (1 << bit)) ? 1 : 0) == impliedBit)) { + bit--; + } + if (mp->m_type == S_SLEB128) { + bit++; + } + while (bit>=0) { + if (bit<7) { + outab(val & 0x7f); + } else { + outab(0x80 | (val & 0x7f)); + } + bit -= 7; + val >>= 7; + } + } while ((c = getnb()) == ','); + unget(c); + break; + + case S_ASCII: + case S_ASCIZ: + if ((d = getnb()) == '\0') + qerr(); + while ((c = getmap(d)) >= 0) + outab(c); + if (mp->m_type == S_ASCIZ) + outab(0); + break; + + case S_ASCIS: + if ((d = getnb()) == '\0') + qerr(); + c = getmap(d); + while (c >= 0) { + if ((n = getmap(d)) >= 0) { + outab(c); + } else { + outab(c | 0x80); + } + c = n; + } + break; + + case S_BLK: + clrexpr(&e1); + expr(&e1, 0); + outchk(HUGE,HUGE); + dot.s_addr += e1.e_addr*mp->m_valu; + lmode = BLIST; + break; + + case S_TITLE: + p = tb; + if ((c = getnb()) != 0) { + do { + if (p < &tb[NTITL-1]) + *p++ = c; + } while ((c = get()) != 0); + } + *p = 0; + unget(c); + lmode = SLIST; + break; + + case S_SBTL: + p = stb; + if ((c = getnb()) != 0) { + do { + if (p < &stb[NSBTL-1]) + *p++ = c; + } while ((c = get()) != 0); + } + *p = 0; + unget(c); + lmode = SLIST; + break; + + case S_MODUL: + getst(id, getnb()); // a module can start with a digit + if (pass == 0) { + if (module[0]) { + err('m'); + } else { + strncpy(module, id, NCPS); + } + } + lmode = SLIST; + break; case S_OPTSDCC: - p = optsdcc; - if ((c = getnb()) != 0) { - do { - if (p < &optsdcc[NINPUT-1]) - *p++ = c; - } while ((c = get()) != 0); - } - *p = 0; - unget(c); - lmode = SLIST; + p = optsdcc; + if ((c = getnb()) != 0) { + do { + if (p < &optsdcc[NINPUT-1]) + *p++ = c; + } while ((c = get()) != 0); + } + *p = 0; + unget(c); + lmode = SLIST; /*if (pass == 0) printf("optsdcc=%s\n", optsdcc);*/ break; - case S_GLOBL: - do { - getid(id, -1); - sp = lookup(id); - sp->s_flag |= S_GBL; - } while ((c = getnb()) == ','); - unget(c); - lmode = SLIST; - break; - - case S_DAREA: - getid(id, -1); - uaf = 0; - uf = A_CON|A_REL; - if ((c = getnb()) == '(') { - do { - getid(opt, -1); - mp = mlookup(opt); - if (mp && mp->m_type == S_ATYP) { - ++uaf; - uf |= mp->m_valu; - } else { - err('u'); - } - } while ((c = getnb()) == ','); - if (c != ')') - qerr(); - } else { - unget(c); - } - if ((ap = alookup(id)) != NULL) { - if (uaf && uf != ap->a_flag) - err('m'); - } else { - ap = (struct area *) new (sizeof(struct area)); - ap->a_ap = areap; - strncpy(ap->a_id, id, NCPS); - ap->a_ref = areap->a_ref + 1; - ap->a_size = 0; - ap->a_fuzz = 0; - ap->a_flag = uaf ? uf : (A_CON|A_REL); - areap = ap; - } - newdot(ap); - lmode = SLIST; - break; - - case S_ORG: - if (dot.s_area->a_flag & A_ABS) { - outall(); - laddr = dot.s_addr = dot.s_org = absexpr(); - } else { - err('o'); - } - outall(); - lmode = ALIST; - break; - - case S_RADIX: - if (more()) { - switch (getnb()) { - case 'b': - case 'B': - radix = 2; - break; - case '@': - case 'o': - case 'O': - case 'q': - case 'Q': - radix = 8; - break; - case 'd': - case 'D': - radix = 10; - break; - case 'h': - case 'H': - case 'x': - case 'X': - radix = 16; - break; - default: - radix = 10; - qerr(); - break; - } - } else { - radix = 10; - } - lmode = SLIST; - break; - - case S_INCL: - d = getnb(); - p = fn; - while ((c = get()) != d) { - if (p < &fn[PATH_MAX-1]) { - *p++ = c; - } else { - break; - } - } - *p = 0; - if ((++incfil == MAXINC) || - (ifp[incfil] = fopen(fn, "r")) == NULL) { - --incfil; - err('i'); - } else { - lop = NLPP; - incline[incfil] = 0; - strcpy(incfn[incfil],fn); - } - lmode = SLIST; - break; - - case S_FLAT24: - if (more()) - { - getst(id, -1); - - if (!as_strcmpi(id, "on")) - { - /* Quick sanity check: size of - * Addr_T must be at least 24 bits. - */ - if (sizeof(Addr_T) < 3) - { - warnBanner(); - fprintf(stderr, - "Cannot enable Flat24 mode: " - "host system must have 24 bit " - "or greater integers.\n"); - } - else - { - flat24Mode = 1; - } - } - else if (!as_strcmpi(id, "off")) - { - flat24Mode = 0; - } - else - { - qerr(); - } - } - else - { - qerr(); - } - lmode = SLIST; - #if 0 - printf("as8051: ds390 flat mode %sabled.\n", - flat24Mode ? "en" : "dis"); - #endif - break; - - - /* - * If not an assembler directive then go to - * the machine dependent function which handles - * all the assembler mnemonics. - */ - default: - machine(mp); - /* if cdb information then generate the line info */ - if (cflag && (pass == 1)) - DefineCDB_Line(); + case S_GLOBL: + do { + getid(id, -1); + sp = lookup(id); + sp->s_flag |= S_GBL; + } while ((c = getnb()) == ','); + unget(c); + lmode = SLIST; + break; + + case S_DAREA: + getid(id, -1); + uaf = 0; + uf = A_CON|A_REL; + if ((c = getnb()) == '(') { + do { + getid(opt, -1); + mp = mlookup(opt); + if (mp && mp->m_type == S_ATYP) { + ++uaf; + uf |= mp->m_valu; + } else { + err('u'); + } + } while ((c = getnb()) == ','); + if (c != ')') + qerr(); + } else { + unget(c); + } + if ((ap = alookup(id)) != NULL) { + if (uaf && uf != ap->a_flag) + err('m'); + } else { + ap = (struct area *) new (sizeof(struct area)); + ap->a_ap = areap; + strncpy(ap->a_id, id, NCPS); + ap->a_ref = areap->a_ref + 1; + ap->a_addr = 0; + ap->a_size = 0; + ap->a_fuzz = 0; + ap->a_flag = uaf ? uf : (A_CON|A_REL); + areap = ap; + } + newdot(ap); + lmode = SLIST; + break; + + case S_ORG: + if (dot.s_area->a_flag & A_ABS) { + outall(); + laddr = dot.s_addr = dot.s_org = absexpr(); + } else { + err('o'); + } + outall(); + lmode = ALIST; + break; + + case S_RADIX: + if (more()) { + switch (getnb()) { + case 'b': + case 'B': + radix = 2; + break; + case '@': + case 'o': + case 'O': + case 'q': + case 'Q': + radix = 8; + break; + case 'd': + case 'D': + radix = 10; + break; + case 'h': + case 'H': + case 'x': + case 'X': + radix = 16; + break; + default: + radix = 10; + qerr(); + break; + } + } else { + radix = 10; + } + lmode = SLIST; + break; + + case S_INCL: + d = getnb(); + p = fn; + while ((c = get()) != d) { + if (p < &fn[PATH_MAX-1]) { + *p++ = c; + } else { + break; + } + } + *p = 0; + if ((++incfil == MAXINC) || + (ifp[incfil] = fopen(fn, "r")) == NULL) { + --incfil; + err('i'); + } else { + lop = NLPP; + incline[incfil] = 0; + strcpy(incfn[incfil],fn); + } + lmode = SLIST; + break; + + case S_FLAT24: + if (more()) + { + getst(id, -1); + + if (!as_strcmpi(id, "on")) + { + /* Quick sanity check: size of + * Addr_T must be at least 24 bits. + */ + if (sizeof(Addr_T) < 3) + { + warnBanner(); + fprintf(stderr, + "Cannot enable Flat24 mode: " + "host system must have 24 bit " + "or greater integers.\n"); + } + else + { + flat24Mode = 1; + } + } + else if (!as_strcmpi(id, "off")) + { + flat24Mode = 0; + } + else + { + qerr(); + } + } + else + { + qerr(); + } + lmode = SLIST; + #if 0 + printf("as8051: ds390 flat mode %sabled.\n", + flat24Mode ? "en" : "dis"); + #endif + break; + + + /* + * If not an assembler directive then go to + * the machine dependent function which handles + * all the assembler mnemonics. + */ + default: + machine(mp); + /* if cdb information then generate the line info */ + if (cflag && (pass == 1)) + DefineCDB_Line(); /* JLH: if -j, generate a line number symbol */ if (jflag && (pass == 1)) @@ -1032,49 +1033,49 @@ loop: DefineNoICE_Line(); } - } - goto loop; + } + goto loop; } -/*)Function FILE * afile(fn, ft, wf) +/*)Function FILE * afile(fn, ft, wf) * - * char * fn file specification string - * char * ft file type string - * int wf read(0)/write(1) flag + * char * fn file specification string + * char * ft file type string + * int wf read(0)/write(1) flag * - * The function afile() opens a file for reading or writing. - * (1) If the file type specification string ft - * is not NULL then a file specification is - * constructed with the file path\name in fn - * and the extension in ft. - * (2) If the file type specification string ft - * is NULL then the file specification is - * constructed from fn. If fn does not have - * a file type then the default source file - * type dsft is appended to the file specification. + * The function afile() opens a file for reading or writing. + * (1) If the file type specification string ft + * is not NULL then a file specification is + * constructed with the file path\name in fn + * and the extension in ft. + * (2) If the file type specification string ft + * is NULL then the file specification is + * constructed from fn. If fn does not have + * a file type then the default source file + * type dsft is appended to the file specification. * - * afile() returns a file handle for the opened file or aborts - * the assembler on an open error. + * afile() returns a file handle for the opened file or aborts + * the assembler on an open error. * - * local variables: - * int c character value - * FILE * fp filehandle for opened file - * char * p1 pointer to filespec string fn - * char * p2 pointer to filespec string fb - * char * p3 pointer to filetype string ft + * local variables: + * int c character value + * FILE * fp filehandle for opened file + * char * p1 pointer to filespec string fn + * char * p2 pointer to filespec string fb + * char * p3 pointer to filetype string ft * - * global variables: - * char afn[] afile() constructed filespec - * char dsft[] default assembler file type string - * char afn[] constructed file specification string + * global variables: + * char afn[] afile() constructed filespec + * char dsft[] default assembler file type string + * char afn[] constructed file specification string * - * functions called: - * VOID asexit() asmain.c - * FILE * fopen() c_library - * int fprintf() c_library + * functions called: + * VOID asexit() asmain.c + * FILE * fopen() c_library + * int fprintf() c_library * - * side effects: - * File is opened for read or write. + * side effects: + * File is opened for read or write. */ FILE * @@ -1083,127 +1084,127 @@ char *fn; char *ft; int wf; { - register char *p2, *p3; - register int c; - FILE *fp; - - p2 = afn; - p3 = ft; - - strcpy (afn, fn); - p2 = strrchr (afn, FSEPX); // search last '.' - if (!p2) - p2 = afn + strlen (afn); - if (p2 > &afn[PATH_MAX-4]) // truncate filename, if it's too long - p2 = &afn[PATH_MAX-4]; - *p2++ = FSEPX; - - // choose a file-extension - if (*p3 == 0) { // extension supplied? - p3 = strrchr (fn, FSEPX); // no: extension in fn? - if (p3) - ++p3; - else - p3 = dsft; // no: default extension - } - - while ((c = *p3++) != 0) { // strncpy - if (p2 < &afn[PATH_MAX-1]) - *p2++ = c; - } - *p2++ = 0; - - if ((fp = fopen(afn, wf?"w":"r")) == NULL) { - fprintf(stderr, "%s: cannot %s.\n", afn, wf?"create":"open"); - asexit(1); - } - return (fp); + register char *p2, *p3; + register int c; + FILE *fp; + + p2 = afn; + p3 = ft; + + strcpy (afn, fn); + p2 = strrchr (afn, FSEPX); // search last '.' + if (!p2) + p2 = afn + strlen (afn); + if (p2 > &afn[PATH_MAX-4]) // truncate filename, if it's too long + p2 = &afn[PATH_MAX-4]; + *p2++ = FSEPX; + + // choose a file-extension + if (*p3 == 0) { // extension supplied? + p3 = strrchr (fn, FSEPX); // no: extension in fn? + if (p3) + ++p3; + else + p3 = dsft; // no: default extension + } + + while ((c = *p3++) != 0) { // strncpy + if (p2 < &afn[PATH_MAX-1]) + *p2++ = c; + } + *p2++ = 0; + + if ((fp = fopen(afn, wf?"w":"r")) == NULL) { + fprintf(stderr, "%s: cannot %s.\n", afn, wf?"create":"open"); + asexit(1); + } + return (fp); } -/*)Function VOID newdot(nap) +/*)Function VOID newdot(nap) * - * area * nap pointer to the new area structure + * area * nap pointer to the new area structure * - * The function newdot(): - * (1) copies the current values of fuzz and the last - * address into the current area referenced by dot - * (2) loads dot with the pointer to the new area and - * loads the fuzz and last address parameters - * (3) outall() is called to flush any remaining - * bufferred code from the old area to the output + * The function newdot(): + * (1) copies the current values of fuzz and the last + * address into the current area referenced by dot + * (2) loads dot with the pointer to the new area and + * loads the fuzz and last address parameters + * (3) outall() is called to flush any remaining + * bufferred code from the old area to the output * - * local variables: - * area * oap pointer to old area + * local variables: + * area * oap pointer to old area * - * global variables: - * sym dot defined as sym[0] - * Addr_T fuzz tracks pass to pass changes in the - * address of symbols caused by - * variable length instruction formats + * global variables: + * sym dot defined as sym[0] + * Addr_T fuzz tracks pass to pass changes in the + * address of symbols caused by + * variable length instruction formats * - * functions called: - * none + * functions called: + * none * - * side effects: - * Current area saved, new area loaded, buffers flushed. + * side effects: + * Current area saved, new area loaded, buffers flushed. */ VOID newdot(nap) register struct area *nap; { - register struct area *oap; - - oap = dot.s_area; - /* fprintf (stderr, "%s dot.s_area->a_size: %d dot.s_addr: %d\n", - oap->a_id, dot.s_area->a_size, dot.s_addr); */ - oap->a_fuzz = fuzz; - if (oap->a_flag & A_OVR) { - // the size of an overlay is the biggest size encountered - if (oap->a_size < dot.s_addr) { - oap->a_size = dot.s_addr; - } - } else if (oap->a_flag & A_ABS) { - oap->a_addr = dot.s_org; - oap->a_size = dot.s_addr - dot.s_org; - } else { - oap->a_addr = 0; - oap->a_size = dot.s_addr; - } - if (nap->a_flag & A_OVR) { - // a new overlay starts at 0, no fuzz - dot.s_addr = 0; - fuzz = 0; - } else { - dot.s_addr = nap->a_size; - fuzz = nap->a_fuzz; - } - dot.s_area = nap; - outall(); + register struct area *oap; + + oap = dot.s_area; + /* fprintf (stderr, "%s dot.s_area->a_size: %d dot.s_addr: %d\n", + oap->a_id, dot.s_area->a_size, dot.s_addr); */ + oap->a_fuzz = fuzz; + if (oap->a_flag & A_OVR) { + // the size of an overlay is the biggest size encountered + if (oap->a_size < dot.s_addr) { + oap->a_size = dot.s_addr; + } + } else if (oap->a_flag & A_ABS) { + oap->a_addr = dot.s_org; + oap->a_size = dot.s_addr - dot.s_org; + } else { + oap->a_addr = 0; + oap->a_size = dot.s_addr; + } + if (nap->a_flag & A_OVR) { + // a new overlay starts at 0, no fuzz + dot.s_addr = 0; + fuzz = 0; + } else { + dot.s_addr = nap->a_size; + fuzz = nap->a_fuzz; + } + dot.s_area = nap; + outall(); } -/*)Function VOID phase(ap, a) +/*)Function VOID phase(ap, a) * - * area * ap pointer to area - * Addr_T a address in area + * area * ap pointer to area + * Addr_T a address in area * - * Function phase() compares the area ap and address a - * with the current area dot.s_area and address dot.s_addr - * to determine if the position of the symbol has changed - * between assembler passes. + * Function phase() compares the area ap and address a + * with the current area dot.s_area and address dot.s_addr + * to determine if the position of the symbol has changed + * between assembler passes. * - * local variables: - * none + * local variables: + * none * - * global varaibles: - * sym * dot defined as sym[0] + * global varaibles: + * sym * dot defined as sym[0] * - * functions called: - * none + * functions called: + * none * - * side effects: - * The p error is invoked if the area and/or address - * has changed. + * side effects: + * The p error is invoked if the area and/or address + * has changed. */ VOID @@ -1211,56 +1212,56 @@ phase(ap, a) struct area *ap; Addr_T a; { - if (ap != dot.s_area || a != dot.s_addr) - err('p'); + if (ap != dot.s_area || a != dot.s_addr) + err('p'); } char *usetxt[] = { - "Usage: [-dqxjgalopsf] file1 [file2 file3 ...]", - " d decimal listing", - " q octal listing", - " x hex listing (default)", - " j add line number and debug information to file", /* JLH */ - " g undefined symbols made global", - " a all user symbols made global", - " l create list output file1[LST]", - " o create object output file1[REL]", - " s create symbol output file1[SYM]", - " p disable listing pagination", - " f flag relocatable references by ` in listing file", - " ff flag relocatable references by mode in listing file", - "", - 0 + "Usage: [-dqxjgalopsf] file1 [file2 file3 ...]", + " d decimal listing", + " q octal listing", + " x hex listing (default)", + " j add line number and debug information to file", /* JLH */ + " g undefined symbols made global", + " a all user symbols made global", + " l create list output file1[LST]", + " o create object output file1[REL]", + " s create symbol output file1[SYM]", + " p disable listing pagination", + " f flag relocatable references by ` in listing file", + " ff flag relocatable references by mode in listing file", + "", + 0 }; -/*)Function VOID usage() +/*)Function VOID usage() * - * The function usage() outputs to the stderr device the - * assembler name and version and a list of valid assembler options. + * The function usage() outputs to the stderr device the + * assembler name and version and a list of valid assembler options. * - * local variables: - * char ** dp pointer to an array of - * text string pointers. + * local variables: + * char ** dp pointer to an array of + * text string pointers. * - * global variables: - * char cpu[] assembler type string - * char * usetxt[] array of string pointers + * global variables: + * char cpu[] assembler type string + * char * usetxt[] array of string pointers * - * functions called: - * VOID asexit() asmain.c - * int fprintf() c_library + * functions called: + * VOID asexit() asmain.c + * int fprintf() c_library * - * side effects: - * program is terminated + * side effects: + * program is terminated */ VOID usage() { - register char **dp; + register char **dp; - fprintf(stderr, "\nASxxxx Assembler %s (%s)\n\n", VERSION, cpu); - for (dp = usetxt; *dp; dp++) - fprintf(stderr, "%s\n", *dp); - asexit(1); + fprintf(stderr, "\nASxxxx Assembler %s (%s)\n\n", VERSION, cpu); + for (dp = usetxt; *dp; dp++) + fprintf(stderr, "%s\n", *dp); + asexit(1); } diff --git a/as/mcs51/Makefile.in b/as/mcs51/Makefile.in index 28d3d92b..279c5deb 100644 --- a/as/mcs51/Makefile.in +++ b/as/mcs51/Makefile.in @@ -42,9 +42,9 @@ OBJDIR = obj ASXXLIB = $(srcdir)/../asxxsrc -ASXXLIBSRC = strcmpi.c assym.c +ASXXLIBSRC = strcmpi.c assym.c aslex.c -SRC = asmain.c aslex.c assubr.c asnoice.c \ +SRC = asmain.c assubr.c asnoice.c \ asexpr.c asdata.c aslist.c asout.c \ i51ext.c i51pst.c i51mch.c i51adr.c diff --git a/as/mcs51/aslex.c b/as/mcs51/aslex.c deleted file mode 100644 index 42a66ab1..00000000 --- a/as/mcs51/aslex.c +++ /dev/null @@ -1,520 +0,0 @@ -/* aslex.c */ - -/* - * (C) Copyright 1989-1995 - * All Rights Reserved - * - * Alan R. Baldwin - * 721 Berkeley St. - * Kent, Ohio 44240 - * - * 28-Oct-97 JLH bug in getst(): sign extend on ~(SPACE|ILL) - * causes infinite loop - */ - -#include -#include -#include -#include "asm.h" - -/*)Module aslex.c - * - * The module aslex.c includes the general lexical - * analysis routines for the assembler. - * - * aslex.c contains the following functions: - * char endline() - * char get() - * VOID getid(id,c) - * int as_getline() - * int getmap() - * char getnb() - * VOID getst() - * int more() - * VOID unget(c) - * - * aslex.c contains no local/static variables - */ - -/*)Function VOID getid(id,c) - * - * char * id a pointer to a string of - * maximum length NCPS - * int c mode flag - * >=0 this is first character to - * copy to the string buffer - * <0 skip white space, first - * character must be a LETTER - * - * The function getid() scans the current assembler-source text line - * from the current position copying the next LETTER | DIGIT string - * into the external string buffer (id). The string ends when a non - * LETTER or DIGIT character is found. The maximum number of - * characters copied is NCPS. If the input string is larger than - * NCPS characters then the string is truncated, if the input string - * is shorter than NCPS characters then the string is NULL filled. - * If the mode argument (c) is >=0 then (c) is the first character - * copied to the string buffer, if (c) is <0 then intervening white - * space (SPACES and TABS) are skipped and the first character found - * must be a LETTER else a 'q' error terminates the parse of this - * assembler-source text line. - * - * local variables: - * char * p pointer to external string buffer - * int c current character value - * - * global variables: - * char ctype[] a character array which defines the - * type of character being processed. - * This index is the character - * being processed. - * - * called functions: - * char get() aslex.c - * char getnb() aslex.c - * VOID unget() aslex.c - * - * side effects: - * use of getnb(), get(), and unget() updates the - * global pointer ip, the position in the current - * assembler-source text line. - */ - -VOID -getid(id, c) -register int c; -char *id; -{ - register char *p; - - if (c < 0) { - c = getnb(); - if ((ctype[c] & LETTER) == 0) - qerr(); - } - p = id; - do { - if (p < &id[NCPS]) - *p++ = c; - } while (ctype[c=get()] & (LETTER|DIGIT)); - unget(c); - while (p < &id[NCPS]) - *p++ = 0; -} - -/*)Function VOID getst(id,c) - * - * char * id a pointer to a string of - * maximum length NCPS - * int c mode flag - * >=0 this is first character to - * copy to the string buffer - * <0 skip white space, first - * character must be a LETTER - * - * The function getnbid() scans the current assembler-source text line - * from the current position copying the next character string into - * the external string buffer (id). The string ends when a SPACE or - * ILL character is found. The maximum number of - * characters copied is NCPS. If the input string is larger than - * NCPS characters then the string is truncated, if the input string - * is shorter than NCPS characters then the string is NULL filled. - * If the mode argument (c) is >=0 then (c) is the first character - * copied to the string buffer, if (c) is <0 then intervening white - * space (SPACES and TABS) are skipped and the first character found - * must be a LETTER else a 'q' error terminates the parse of this - * assembler-source text line. - * - * local variables: - * char * p pointer to external string buffer - * int c current character value - * - * global variables: - * char ctype[] a character array which defines the - * type of character being processed. - * This index is the character - * being processed. - * - * called functions: - * char get() aslex.c - * char getnb() aslex.c - * VOID unget() aslex.c - * - * side effects: - * use of getnb(), get(), and unget() updates the - * global pointer ip, the position in the current - * assembler-source text line. - */ - -VOID -getst(id, c) -register int c; -char *id; -{ - register char *p; - - if (c < 0) { - c = getnb(); - if ((ctype[c] & LETTER) == 0) - qerr(); - } - p = id; - do { - if (p < &id[NCPS]) - *p++ = c; - } while (ctype[c=get()] & (0xFF - (SPACE|ILL))); - unget(c); - while (p < &id[NCPS]) - *p++ = 0; -} - -/*)Function char getnb() - * - * The function getnb() scans the current assembler-source - * text line returning the first character not a SPACE or TAB. - * - * local variables: - * int c current character from - * assembler-source text line - * - * global variables: - * none - * - * called functions: - * char get() aslex.c - * - * side effects: - * use of get() updates the global pointer ip, the position - * in the current assembler-source text line - */ - -char -getnb() -{ - register int c; - - while ((c=get()) == ' ' || c == '\t') - ; - return (c); -} - -/*)Function char get() - * - * The function get() returns the next character in the - * assembler-source text line, at the end of the line a - * NULL character is returned. - * - * local variables: - * int c current character from - * assembler-source text line - * - * global variables: - * char * ip pointer into the current - * assembler-source text line - * - * called functions: - * none - * - * side effects: - * updates ip to the next character position in the - * assembler-source text line. If ip is at the end of the - * line, ip is not updated. - */ - -char -get() -{ - register int c; - - if ((c = *ip) != 0) - ++ip; - return (c); -} - -/*)Function VOID unget(c) - * - * int c value of last character read from - * assembler-source text line - * - * If (c) is not a NULL character then the global pointer ip - * is updated to point to the preceeding character in the - * assembler-source text line. - * - * NOTE: This function does not push the character (c) - * back into the assembler-source text line, only - * the pointer ip is changed. - * - * local variables: - * int c last character read from - * assembler-source text line - * - * global variables: - * char * ip position into the current - * assembler-source text line - * - * called functions: - * none - * - * side effects: - * ip decremented by 1 character position - */ - -VOID -unget(c) -{ - if (c) - if (ip != ib) - --ip; -} - -/*)Function int getmap(d) - * - * int d value to compare with the - * assembler-source text line character - * - * The function getmap() converts the 'C' style characters \b, \f, - * \n, \r, and \t to their equivalent ascii values and also - * converts 'C' style octal constants '\123' to their equivalent - * numeric values. If the first character is equivalent to (d) then - * a (-1) is returned, if the end of the line is detected then - * a 'q' error terminates the parse for this line, or if the first - * character is not a \ then the character value is returned. - * - * local variables: - * int c value of character from the - * assembler-source text line - * int n looping counter - * int v current value of numeric conversion - * - * global variables: - * none - * - * called functions: - * char get() aslex.c - * - * side effects: - * use of get() updates the global pointer ip the position - * in the current assembler-source text line - */ - -int -getmap(d) -{ - register int c, n, v; - - if ((c=get()) == '\0') - qerr(); - if (c == d) - return (-1); - if (c == '\\') { - c = get(); - switch (c) { - - case 'b': - c = '\b'; - break; - - case 'f': - c = '\f'; - break; - - case 'n': - c = '\n'; - break; - - case 'r': - c = '\r'; - break; - - case 't': - c = '\t'; - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - n = 0; - v = 0; - while (++n<=3 && c>='0' && c<='7') { - v = (v<<3) + c - '0'; - c = get(); - } - unget(c); - c = v; - break; - } - } - return (c); -} - -/*)Function int as_getline() - * - * The function as_getline() reads a line of assembler-source text - * from an assembly source text file or an include file. - * Lines of text are processed from assembler-source files until - * all files have been read. If an include file is opened then - * lines of text are read from the include file (or nested - * include file) until the end of the include file is found. - * The input text line is copied into the global string ib[] - * and converted to a NULL terminated string. The function - * as_getline() returns a (1) after succesfully reading a line - * or a (0) if all files have been read. - * - * local variables: - * int i string length - * - * global variables: - * char ib[] string buffer containing - * assembler-source text line - * char ifp[] array of file handles for - * include files - * int incfil index for ifp[] specifies - * active include file - * int incline[] array of include file - * line numbers - * char sfp[] array of file handles for - * assembler source files - * int cfile index for sfp[] specifies - * active source file - * int srcline[] array of source file - * line numbers - * int inpfil maximum input file index - * - * called functions: - * int fclose() c-library - * char * fgets() c-library - * int strlen() c-library - * - * side effects: - * include file will be closed at detection of end of file. - * the next sequential source file may be selected. - * the global file indexes incfil or cfile may be changed. - * The respective source line or include line counter - * will be updated. - */ - -int -as_getline() -{ -loop: if (incfil >= 0) { - if (fgets(ib, sizeof ib, ifp[incfil]) == NULL) { - fclose(ifp[incfil--]); - lop = NLPP; - goto loop; - } else { - ++incline[incfil]; - } - } else { - if (fgets(ib, sizeof ib, sfp[cfile]) == NULL) { - if (++cfile <= inpfil) { - srcline[cfile] = 0; - goto loop; - } - return (0); - } else { - ++srcline[cfile]; - } - } - chop_crlf(ib); - return (1); -} - -/*)Function int more() - * - * The function more() scans the assembler-source text line - * skipping white space (SPACES and TABS) and returns a (0) - * if the end of the line or a comment delimeter (;) is found, - * or a (1) if their are additional characters in the line. - * - * local variables: - * int c next character from the - * assembler-source text line - * - * global variables: - * none - * - * called functions: - * char getnb() aslex.c - * VOID unget() aslex.c - * - * side effects: - * use of getnb() and unget() updates the global pointer ip - * the position in the current assembler-source text line - */ - -int -more() -{ - register int c; - - c = getnb(); - unget(c); - return( (c == '\0' || c == ';') ? 0 : 1 ); -} - -/*)Function char endline() - * - * The function endline() scans the assembler-source text line - * skipping white space (SPACES and TABS) and returns the next - * character or a (0) if the end of the line is found or a - * comment delimiter (;) is found. - * - * local variables: - * int c next character from the - * assembler-source text line - * - * global variables: - * none - * - * called functions: - * char getnb() aslex.c - * - * side effects: - * use of getnb() updates the global pointer ip the - * position in the current assembler-source text line - */ - -char -endline() -{ - register int c; - - c = getnb(); - return( (c == '\0' || c == ';') ? 0 : c ); -} - -/*)Function VOID chop_crlf(str) - * - * char *str string to chop - * - * The function chop_crlf() removes trailing LF or CR/LF from - * str, if present. - * - * local variables: - * int i string length - * - * global variables: - * none - * - * functions called: - * none - * - * side effects: - * none - */ - -VOID -chop_crlf(str) -char *str; -{ - register int i; - - i = strlen(str); - if (i >= 1 && str[i-1] == '\n') str[i-1] = 0; - if (i >= 2 && str[i-2] == '\r') str[i-2] = 0; -} diff --git a/as/mcs51/asmain.c b/as/mcs51/asmain.c index 9e4b3890..180dd74a 100644 --- a/as/mcs51/asmain.c +++ b/as/mcs51/asmain.c @@ -932,6 +932,7 @@ loop: ap->a_ap = areap; strncpy(ap->a_id, id, NCPS); ap->a_ref = areap->a_ref + 1; + ap->a_addr = 0; ap->a_size = 0; ap->a_fuzz = 0; ap->a_flag = uaf ? uf : (A_CON|A_REL); diff --git a/as/mcs51/asx8051.dsp b/as/mcs51/asx8051.dsp index 745c46d1..5b40ddb9 100644 --- a/as/mcs51/asx8051.dsp +++ b/as/mcs51/asx8051.dsp @@ -96,7 +96,7 @@ SOURCE=.\asexpr.c # End Source File # Begin Source File -SOURCE=.\aslex.c +SOURCE=..\asxxsrc\aslex.c # End Source File # Begin Source File diff --git a/as/z80/Makefile.in b/as/z80/Makefile.in index fbb4c183..63360141 100644 --- a/as/z80/Makefile.in +++ b/as/z80/Makefile.in @@ -9,9 +9,9 @@ OBJDIR = obj$(EXT) ASXXLIB = $(srcdir)/../asxxsrc -ASXXLIBSRC = strcmpi.c assym.c +ASXXLIBSRC = strcmpi.c assym.c aslex.c -SRC = asdata.c asexpr.c aslex.c aslist.c asmain.c asout.c \ +SRC = asdata.c asexpr.c aslist.c asmain.c asout.c \ assubr.c z80adr.c z80ext.c z80mch.c z80pst.c ASSOURCES = $(SRC) $(ASXXLIBSRC:%.c=$(ASXXLIB)/%.c) diff --git a/as/z80/as_gbz80.dsp b/as/z80/as_gbz80.dsp index d8c604ae..4aba0c35 100644 --- a/as/z80/as_gbz80.dsp +++ b/as/z80/as_gbz80.dsp @@ -98,8 +98,7 @@ SOURCE=.\asexpr.c # End Source File # Begin Source File -SOURCE=.\aslex.c -# ADD CPP /D "GAMEBOY" +SOURCE=..\asxxsrc\aslex.c # End Source File # Begin Source File diff --git a/as/z80/as_z80.dsp b/as/z80/as_z80.dsp index 01d16385..b4b706fe 100644 --- a/as/z80/as_z80.dsp +++ b/as/z80/as_z80.dsp @@ -96,7 +96,7 @@ SOURCE=.\asexpr.c # End Source File # Begin Source File -SOURCE=.\aslex.c +SOURCE=..\asxxsrc\aslex.c # End Source File # Begin Source File diff --git a/as/z80/aslex.c b/as/z80/aslex.c deleted file mode 100644 index 0a4323ec..00000000 --- a/as/z80/aslex.c +++ /dev/null @@ -1,502 +0,0 @@ -/* aslex.c */ - -/* - * (C) Copyright 1989-1995 - * All Rights Reserved - * - * Alan R. Baldwin - * 721 Berkeley St. - * Kent, Ohio 44240 - */ - -/* - * Extensions: P. Felber, M. Hope - */ - -#include -#include -#include - -#include "asm.h" - -/*)Module aslex.c - * - * The module aslex.c includes the general lexical - * analysis routines for the assembler. - * - * aslex.c contains the following functions: - * char endline() - * char get() - * VOID getid(id,c) - * int as_getline() - * int getmap() - * char getnb() - * VOID getst() - * int more() - * VOID unget(c) - * - * aslex.c contains no local/static variables - */ - -/*)Function VOID getid(id,c) - * - * char * id a pointer to a string of - * maximum length NCPS - * int c mode flag - * >=0 this is first character to - * copy to the string buffer - * <0 skip white space, first - * character must be a LETTER - * - * The function getid() scans the current assembler-source text line - * from the current position copying the next LETTER | DIGIT string - * into the external string buffer (id). The string ends when a non - * LETTER or DIGIT character is found. The maximum number of - * characters copied is NCPS. If the input string is larger than - * NCPS characters then the string is truncated, if the input string - * is shorter than NCPS characters then the string is NULL filled. - * If the mode argument (c) is >=0 then (c) is the first character - * copied to the string buffer, if (c) is <0 then intervening white - * space (SPACES and TABS) are skipped and the first character found - * must be a LETTER else a 'q' error terminates the parse of this - * assembler-source text line. - * - * local variables: - * char * p pointer to external string buffer - * int c current character value - * - * global variables: - * char ctype[] a character array which defines the - * type of character being processed. - * This index is the character - * being processed. - * - * called functions: - * char get() aslex.c - * char getnb() aslex.c - * VOID unget() aslex.c - * - * side effects: - * use of getnb(), get(), and unget() updates the - * global pointer ip, the position in the current - * assembler-source text line. - */ - -VOID -getid(id, c) -register int c; -char *id; -{ - register char *p; - - if (c < 0) { - c = getnb(); - if ((ctype[c] & LETTER) == 0) - qerr(); - } - p = id; - do { - if (p < &id[NCPS]) - *p++ = c; - } while (ctype[c=get()] & (LETTER|DIGIT)); - unget(c); - while (p < &id[NCPS]) - *p++ = 0; -} - -/*)Function VOID getst(id,c) - * - * char * id a pointer to a string of - * maximum length NCPS - * int c mode flag - * >=0 this is first character to - * copy to the string buffer - * <0 skip white space, first - * character must be a LETTER - * - * The function getnbid() scans the current assembler-source text line - * from the current position copying the next character string into - * the external string buffer (id). The string ends when a SPACE or - * ILL character is found. The maximum number of - * characters copied is NCPS. If the input string is larger than - * NCPS characters then the string is truncated, if the input string - * is shorter than NCPS characters then the string is NULL filled. - * If the mode argument (c) is >=0 then (c) is the first character - * copied to the string buffer, if (c) is <0 then intervening white - * space (SPACES and TABS) are skipped and the first character found - * must be a LETTER else a 'q' error terminates the parse of this - * assembler-source text line. - * - * local variables: - * char * p pointer to external string buffer - * int c current character value - * - * global variables: - * char ctype[] a character array which defines the - * type of character being processed. - * This index is the character - * being processed. - * - * called functions: - * char get() aslex.c - * char getnb() aslex.c - * VOID unget() aslex.c - * - * side effects: - * use of getnb(), get(), and unget() updates the - * global pointer ip, the position in the current - * assembler-source text line. - */ - -VOID -getst(id, c) -register int c; -char *id; -{ - register char *p; - - if (c < 0) { - c = getnb(); - if ((ctype[c] & LETTER) == 0) - qerr(); - } - p = id; - do { - if (p < &id[NCPS]) - *p++ = c; - } while (ctype[c=get()] & (0xFF - (SPACE|ILL))); - unget(c); - while (p < &id[NCPS]) - *p++ = 0; -} - -/*)Function char getnb() - * - * The function getnb() scans the current assembler-source - * text line returning the first character not a SPACE or TAB. - * - * local variables: - * int c current character from - * assembler-source text line - * - * global variables: - * none - * - * called functions: - * char get() aslex.c - * - * side effects: - * use of get() updates the global pointer ip, the position - * in the current assembler-source text line - */ - -char -getnb() -{ - register int c; - - while ((c=get()) == ' ' || c == '\t') - ; - return (c); -} - -/*)Function char get() - * - * The function get() returns the next character in the - * assembler-source text line, at the end of the line a - * NULL character is returned. - * - * local variables: - * int c current character from - * assembler-source text line - * - * global variables: - * char * ip pointer into the current - * assembler-source text line - * - * called functions: - * none - * - * side effects: - * updates ip to the next character position in the - * assembler-source text line. If ip is at the end of the - * line, ip is not updated. - */ - -char -get() -{ - register int c; - - if ((c = *ip) != 0) - ++ip; - return (c); -} - -/*)Function VOID unget(c) - * - * int c value of last character read from - * assembler-source text line - * - * If (c) is not a NULL character then the global pointer ip - * is updated to point to the preceeding character in the - * assembler-source text line. - * - * NOTE: This function does not push the character (c) - * back into the assembler-source text line, only - * the pointer ip is changed. - * - * local variables: - * int c last character read from - * assembler-source text line - * - * global variables: - * char * ip position into the current - * assembler-source text line - * - * called functions: - * none - * - * side effects: - * ip decremented by 1 character position - */ - -VOID -unget(c) -{ - if (c) - if (ip != ib) - --ip; -} - -/*)Function int getmap(d) - * - * int d value to compare with the - * assembler-source text line character - * - * The function getmap() converts the 'C' style characters \b, \f, - * \n, \r, and \t to their equivalent ascii values and also - * converts 'C' style octal constants '\123' to their equivalent - * numeric values. If the first character is equivalent to (d) then - * a (-1) is returned, if the end of the line is detected then - * a 'q' error terminates the parse for this line, or if the first - * character is not a \ then the character value is returned. - * - * local variables: - * int c value of character from the - * assembler-source text line - * int n looping counter - * int v current value of numeric conversion - * - * global variables: - * none - * - * called functions: - * char get() aslex.c - * - * side effects: - * use of get() updates the global pointer ip the position - * in the current assembler-source text line - */ - -int -getmap(d) -{ - register int c, n, v; - - if ((c=get()) == '\0') - qerr(); - if (c == d) - return (-1); - if (c == '\\') { - c = get(); - switch (c) { - - case 'b': - c = '\b'; - break; - - case 'f': - c = '\f'; - break; - - case 'n': - c = '\n'; - break; - - case 'r': - c = '\r'; - break; - - case 't': - c = '\t'; - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - n = 0; - v = 0; - while (++n<=3 && c>='0' && c<='7') { - v = (v<<3) + c - '0'; - c = get(); - } - unget(c); - c = v; - break; - } - } - return (c); -} - -/*)Function int as_getline() - * - * The function as_getline() reads a line of assembler-source text - * from an assembly source text file or an include file. - * Lines of text are processed from assembler-source files until - * all files have been read. If an include file is opened then - * lines of text are read from the include file (or nested - * include file) until the end of the include file is found. - * The input text line is copied into the global string ib[] - * and converted to a NULL terminated string. The function - * as_getline() returns a (1) after succesfully reading a line - * or a (0) if all files have been read. - * - * local variables: - * int i string length - * - * global variables: - * char ib[] string buffer containing - * assembler-source text line - * char ifp[] array of file handles for - * include files - * int incfil index for ifp[] specifies - * active include file - * int incline[] array of include file - * line numbers - * char sfp[] array of file handles for - * assembler source files - * int cfile index for sfp[] specifies - * active source file - * int srcline[] array of source file - * line numbers - * int inpfil maximum input file index - * - * called functions: - * int fclose() c-library - * char * fgets() c-library - * int strlen() c-library - * - * side effects: - * include file will be closed at detection of end of file. - * the next sequential source file may be selected. - * the global file indexes incfil or cfile may be changed. - * The respective source line or include line counter - * will be updated. - */ - -int -as_getline() -{ -register int i; - -loop: if (incfil >= 0) { - if (fgets(ib, sizeof ib, ifp[incfil]) == NULL) { -#ifdef SDK - fclose(ifp[incfil]); - ifp[incfil--] = NULL; -#else /* SDK */ - fclose(ifp[incfil--]); -#endif /* SDK */ - lop = NLPP; - goto loop; - } else { - ++incline[incfil]; - } - } else { - if (fgets(ib, sizeof ib, sfp[cfile]) == NULL) { - if (++cfile <= inpfil) { - srcline[cfile] = 0; - goto loop; - } - return (0); - } else { - ++srcline[cfile]; - } - } - i = strlen(ib) - 1; - if (ib[i] == '\n') - ib[i] = 0; - if (i >= 1 && ib[i-1] == '\r') - ib[i-1] = 0; - return (1); -} - -/*)Function int more() - * - * The function more() scans the assembler-source text line - * skipping white space (SPACES and TABS) and returns a (0) - * if the end of the line or a comment delimeter (;) is found, - * or a (1) if their are additional characters in the line. - * - * local variables: - * int c next character from the - * assembler-source text line - * - * global variables: - * none - * - * called functions: - * char getnb() aslex.c - * VOID unget() aslex.c - * - * side effects: - * use of getnb() and unget() updates the global pointer ip - * the position in the current assembler-source text line - */ - -int -more() -{ - register int c; - - c = getnb(); - unget(c); - return( (c == '\0' || c == ';') ? 0 : 1 ); -} - -/*)Function char endline() - * - * The function endline() scans the assembler-source text line - * skipping white space (SPACES and TABS) and returns the next - * character or a (0) if the end of the line is found or a - * comment delimiter (;) is found. - * - * local variables: - * int c next character from the - * assembler-source text line - * - * global variables: - * none - * - * called functions: - * char getnb() aslex.c - * - * side effects: - * use of getnb() updates the global pointer ip the - * position in the current assembler-source text line - */ - -char -endline() -{ - register int c; - - c = getnb(); - return( (c == '\0' || c == ';') ? 0 : c ); -} diff --git a/as/z80/asmain.c b/as/z80/asmain.c index 9e6c6381..85b53825 100644 --- a/as/z80/asmain.c +++ b/as/z80/asmain.c @@ -915,6 +915,7 @@ loop: ap->a_ap = areap; ap->a_id = strsto(id); ap->a_ref = areap->a_ref + 1; + ap->a_addr = 0; ap->a_size = 0; ap->a_fuzz = 0; ap->a_flag = uaf ? uf : (A_CON|A_REL); -- 2.30.2