From: borutr Date: Mon, 12 Nov 2007 20:38:53 +0000 (+0000) Subject: * as\z80\asmain.c, as\z80\asm.h, as\z80\assym.c, as\z80\asdata.c: X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=1f71631153812aab04fb42a816aa14606f0cf3de;p=fw%2Fsdcc * as\z80\asmain.c, as\z80\asm.h, as\z80\assym.c, as\z80\asdata.c: fixed bug #1817005 - as-z80 chokes on long labels git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4961 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index eec19768..726da989 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2007-11-12 Borut Razem + + * as\z80\asmain.c, as\z80\asm.h, as\z80\assym.c, as\z80\asdata.c: + fixed bug #1817005 - as-z80 chokes on long labels + 2007-11-10 Maarten Brock * as/hc08/asmain.c, diff --git a/as/z80/asdata.c b/as/z80/asdata.c index 2daf953b..4b14c4f3 100644 --- a/as/z80/asdata.c +++ b/as/z80/asdata.c @@ -15,267 +15,264 @@ #include "asm.h" -/*)Module asdata.c +/*)Module asdata.c * - * The module asdata.c contains the global constants, - * structures, and variables used in the assembler. + * The module asdata.c contains the global constants, + * structures, and variables used in the assembler. */ -int aserr; /* ASxxxx error counter - */ -jmp_buf jump_env; /* compiler dependent structure - * used by setjmp() and longjmp() - */ -int inpfil; /* count of assembler - * input files specified - */ -int incfil; /* current file handle index - * for include files - */ -int cfile; /* current file handle index - * of input assembly files - */ -int flevel; /* IF-ELSE-ENDIF flag will be non - * zero for false conditional case - */ -int tlevel; /* current conditional level - */ -int ifcnd[MAXIF+1]; /* array of IF statement condition - * values (0 = FALSE) indexed by tlevel - */ -int iflvl[MAXIF+1]; /* array of IF-ELSE-ENDIF flevel - * values indexed by tlevel - */ +int aserr; /* ASxxxx error counter + */ +jmp_buf jump_env; /* compiler dependent structure + * used by setjmp() and longjmp() + */ +int inpfil; /* count of assembler + * input files specified + */ +int incfil; /* current file handle index + * for include files + */ +int cfile; /* current file handle index + * of input assembly files + */ +int flevel; /* IF-ELSE-ENDIF flag will be non + * zero for false conditional case + */ +int tlevel; /* current conditional level + */ +int ifcnd[MAXIF+1]; /* array of IF statement condition + * values (0 = FALSE) indexed by tlevel + */ +int iflvl[MAXIF+1]; /* array of IF-ELSE-ENDIF flevel + * values indexed by tlevel + */ -char afn[FILSPC]; /* afile temporary file name - */ -char srcfn[MAXFIL][FILSPC]; /* array of source file names - */ -int srcline[MAXFIL]; /* source line number - */ -char incfn[MAXINC][FILSPC]; /* array of include file names - */ -int incline[MAXINC]; /* include line number - */ +char afn[FILSPC]; /* afile temporary file name + */ +char srcfn[MAXFIL][FILSPC]; /* array of source file names + */ +int srcline[MAXFIL]; /* source line number + */ +char incfn[MAXINC][FILSPC]; /* array of include file names + */ +int incline[MAXINC]; /* include line number + */ -int radix; /* current number conversion radix: - * 2 (binary), 8 (octal), 10 (decimal), - * 16 (hexadecimal) - */ -int line; /* current assembler source - * line number - */ -int page; /* current page number - */ -int lop; /* current line number on page - */ -int pass; /* assembler pass number - */ -int lflag; /* -l, generate listing flag - */ -int gflag; /* -g, make undefined symbols global flag - */ -int aflag; /* -a, make all symbols global flag - */ -int oflag; /* -o, generate relocatable output flag - */ -int sflag; /* -s, generate symbol table flag - */ -int pflag; /* -p, enable listing pagination - */ -int xflag; /* -x, listing radix flag - */ -int fflag; /* -f(f), relocations flagged flag - */ -Addr_T laddr; /* address of current assembler line - * or value of .if argument - */ -Addr_T fuzz; /* tracks pass to pass changes in the - * address of symbols caused by - * variable length instruction formats - */ -int lmode; /* listing mode - */ -char *ep; /* pointer into error list - * array eb[NERR] - */ -char eb[NERR]; /* array of generated error codes - */ -char *ip; /* pointer into the assembler-source - * text line in ib[] - */ -char ib[NINPUT]; /* assembler-source text line - */ -char *cp; /* pointer to assembler output - * array cb[] - */ -char cb[NCODE]; /* array of assembler output values - */ -int *cpt; /* pointer to assembler relocation type - * output array cbt[] - */ -int cbt[NCODE]; /* array of assembler relocation types - * describing the data in cb[] - */ -char tb[NTITL]; /* Title string buffer - */ -char stb[NSBTL]; /* Subtitle string buffer - */ -char optsdcc[NINPUT]; /* sdcc compile options - */ +int radix; /* current number conversion radix: + * 2 (binary), 8 (octal), 10 (decimal), + * 16 (hexadecimal) + */ +int line; /* current assembler source + * line number + */ +int page; /* current page number + */ +int lop; /* current line number on page + */ +int pass; /* assembler pass number + */ +int lflag; /* -l, generate listing flag + */ +int gflag; /* -g, make undefined symbols global flag + */ +int aflag; /* -a, make all symbols global flag + */ +int oflag; /* -o, generate relocatable output flag + */ +int sflag; /* -s, generate symbol table flag + */ +int pflag; /* -p, enable listing pagination + */ +int xflag; /* -x, listing radix flag + */ +int fflag; /* -f(f), relocations flagged flag + */ +Addr_T laddr; /* address of current assembler line + * or value of .if argument + */ +Addr_T fuzz; /* tracks pass to pass changes in the + * address of symbols caused by + * variable length instruction formats + */ +int lmode; /* listing mode + */ +char *ep; /* pointer into error list + * array eb[NERR] + */ +char eb[NERR]; /* array of generated error codes + */ +char *ip; /* pointer into the assembler-source + * text line in ib[] + */ +char ib[NINPUT]; /* assembler-source text line + */ +char *cp; /* pointer to assembler output + * array cb[] + */ +char cb[NCODE]; /* array of assembler output values + */ +int *cpt; /* pointer to assembler relocation type + * output array cbt[] + */ +int cbt[NCODE]; /* array of assembler relocation types + * describing the data in cb[] + */ +char tb[NTITL]; /* Title string buffer + */ +char stb[NSBTL]; /* Subtitle string buffer + */ +char optsdcc[NINPUT]; /* sdcc compile options + */ -char symtbl[] = { "Symbol Table" }; -char aretbl[] = { "Area Table" }; +char symtbl[] = { "Symbol Table" }; +char aretbl[] = { "Area Table" }; -char module[NCPS]; /* module name string - */ +char module[NCPS]; /* module name string + */ /* - * The mne structure is a linked list of the assembler - * mnemonics and directives. The list of mnemonics and - * directives contained in the device dependent file - * xxxpst.c are hashed and linked into NHASH lists in - * module assym.c by syminit(). The structure contains - * the mnemonic/directive name, a subtype which directs - * the evaluation of this mnemonic/directive, a flag which - * is used to detect the end of the mnemonic/directive - * list in xxxpst.c, and a value which is normally - * associated with the assembler mnemonic base instruction - * value. + * The mne structure is a linked list of the assembler + * mnemonics and directives. The list of mnemonics and + * directives contained in the device dependent file + * xxxpst.c are hashed and linked into NHASH lists in + * module assym.c by syminit(). The structure contains + * the mnemonic/directive name, a subtype which directs + * the evaluation of this mnemonic/directive, a flag which + * is used to detect the end of the mnemonic/directive + * list in xxxpst.c, and a value which is normally + * associated with the assembler mnemonic base instruction + * value. * - * struct mne - * { - * struct mne *m_mp; Hash link - * char m_id[NCPS]; Mnemonic - * char m_type; Mnemonic subtype - * char m_flag; Mnemonic flags - * Addr_T m_valu; Value - * }; + * struct mne + * { + * struct mne *m_mp; Hash link + * char m_id[NCPS]; Mnemonic + * char m_type; Mnemonic subtype + * char m_flag; Mnemonic flags + * Addr_T m_valu; Value + * }; */ -struct mne *mnehash[NHASH]; +struct mne *mnehash[NHASH]; /* - * The sym structure is a linked list of symbols defined - * in the assembler source files. The first symbol is "." - * defined here. The entry 'struct tsym *s_tsym' - * links any temporary symbols following this symbol and - * preceeding the next normal symbol. The structure also - * contains the symbol's name, type (USER or NEW), flag - * (global, assigned, and multiply defined), a pointer - * to the area structure defining where the symbol is - * located, a reference number assigned by outgsd() in - * asout.c, and the symbols address relative to the base - * address of the area where the symbol is located. + * The sym structure is a linked list of symbols defined + * in the assembler source files. The first symbol is "." + * defined here. The entry 'struct tsym *s_tsym' + * links any temporary symbols following this symbol and + * preceeding the next normal symbol. The structure also + * contains the symbol's name, type (USER or NEW), flag + * (global, assigned, and multiply defined), a pointer + * to the area structure defining where the symbol is + * located, a reference number assigned by outgsd() in + * asout.c, and the symbols address relative to the base + * address of the area where the symbol is located. * - * struct sym - * { - * struct sym *s_sp; Hash link - * struct tsym *s_tsym; Temporary symbol link - * char s_id[NCPS]; Symbol - * char s_type; Symbol subtype - * char s_flag; Symbol flags - * struct area *s_area; Area line, 0 if absolute - * int s_ref; Ref. number - * Addr_T s_addr; Address - * }; + * struct sym + * { + * struct sym *s_sp; Hash link + * struct tsym *s_tsym; Temporary symbol link + * char s_id[NCPS]; Symbol + * char s_type; Symbol subtype + * char s_flag; Symbol flags + * struct area *s_area; Area line, 0 if absolute + * int s_ref; Ref. number + * Addr_T s_addr; Address + * }; */ -struct sym sym[] = { - { NULL, NULL, ".", S_USER, S_END, NULL, 0, } +struct sym sym[] = { + { NULL, NULL, ".", S_USER, S_END, NULL, 0, } }; -struct sym *symp; /* pointer to a symbol structure - */ -struct sym *symhash[NHASH]; /* array of pointers to NHASH - * linked symbol lists - */ +struct sym *symp; /* pointer to a symbol structure + */ +struct sym *symhash[NHASH]; /* array of pointers to NHASH + * linked symbol lists + */ /* - * The area structure contains the parameter values for a - * specific program or data section. The area structure - * is a linked list of areas. The initial default area - * is "_CODE" defined here, the next area structure - * will be linked to this structure through the structure - * element 'struct area *a_ep'. The structure contains the - * area name, area reference number ("_CODE" is 0) determined - * by the order of .area directives, area size determined - * from the total code and/or data in an area, area fuzz is - * an variable used to track pass to pass changes in the - * area size caused by variable length instruction formats, - * and area flags which specify the area's relocation type. + * The area structure contains the parameter values for a + * specific program or data section. The area structure + * is a linked list of areas. The initial default area + * is "_CODE" defined here, the next area structure + * will be linked to this structure through the structure + * element 'struct area *a_ep'. The structure contains the + * area name, area reference number ("_CODE" is 0) determined + * by the order of .area directives, area size determined + * from the total code and/or data in an area, area fuzz is + * an variable used to track pass to pass changes in the + * area size caused by variable length instruction formats, + * and area flags which specify the area's relocation type. * - * struct area - * { - * struct area *a_ap; Area link - * char a_id[NCPS]; Area Name - * int a_ref; Reference number - * Addr_T a_size; Area size - * Addr_T a_fuzz; Area fuzz - * int a_flag; Area flags - * }; + * struct area + * { + * struct area *a_ap; Area link + * char *a_id; Area Name + * int a_ref; Reference number + * Addr_T a_size; Area size + * Addr_T a_fuzz; Area fuzz + * int a_flag; Area flags + * }; */ -struct area area[] = { - { NULL, "_CODE", 0, 0, 0, A_CON|A_REL } +struct area area[] = { + { NULL, "_CODE", 0, 0, 0, A_CON|A_REL } }; -struct area *areap; /* pointer to an area structure - */ +struct area *areap; /* pointer to an area structure + */ -FILE *lfp; /* list output file handle - */ -FILE *ofp; /* relocation output file handle - */ -FILE *tfp; /* symbol table output file handle - */ -FILE *sfp[MAXFIL]; /* array of assembler-source file handles - */ -FILE *ifp[MAXINC]; /* 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[MAXFIL]; /* array of assembler-source file handles + */ +FILE *ifp[MAXINC]; /* array of include-file file handles + */ /* - * array of character types, one per - * ASCII character + * array of character types, one per + * ASCII character */ -unsigned char ctype[128] = { -/*NUL*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*BS*/ ILL, SPACE, ILL, ILL, SPACE, ILL, ILL, ILL, -/*DLE*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*CAN*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, -/*SPC*/ SPACE, ETC, ETC, ETC, LETTER, BINOP, BINOP, ETC, -/*(*/ ETC, ETC, BINOP, BINOP, ETC, BINOP, LETTER, BINOP, -/*0*/ DGT2, DGT2, DGT8, DGT8, DGT8, DGT8, DGT8, DGT8, -/*8*/ DGT10, DGT10, ETC, ETC, BINOP, ETC, BINOP, ETC, -/*@*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, -/*H*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*P*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*X*/ LETTER, LETTER, LETTER, ETC, ETC, ETC, BINOP, LETTER, -/*`*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, -/*h*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*p*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, -/*x*/ LETTER, LETTER, LETTER, ETC, BINOP, ETC, ETC, ETC +unsigned char ctype[128] = { +/*NUL*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*BS*/ ILL, SPACE, ILL, ILL, SPACE, ILL, ILL, ILL, +/*DLE*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*CAN*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*SPC*/ SPACE, ETC, ETC, ETC, LETTER, BINOP, BINOP, ETC, +/*(*/ ETC, ETC, BINOP, BINOP, ETC, BINOP, LETTER, BINOP, +/*0*/ DGT2, DGT2, DGT8, DGT8, DGT8, DGT8, DGT8, DGT8, +/*8*/ DGT10, DGT10, ETC, ETC, BINOP, ETC, BINOP, ETC, +/*@*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, +/*H*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*P*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*X*/ LETTER, LETTER, LETTER, ETC, ETC, ETC, BINOP, LETTER, +/*`*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, +/*h*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*p*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*x*/ LETTER, LETTER, LETTER, ETC, BINOP, ETC, ETC, ETC }; /* - * an array of characters which - * perform the case translation function + * an array of characters which + * perform the case translation function */ -#if CASE_SENSITIVE -#else -char ccase[128] = { -/*NUL*/ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', -/*BS*/ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', -/*DLE*/ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', -/*CAN*/ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', -/*SPC*/ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', -/*(*/ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', -/*0*/ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', -/*8*/ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', -/*@*/ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', -/*H*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', -/*P*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', -/*X*/ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', -/*`*/ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', -/*h*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', -/*p*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', -/*x*/ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177' -}; -#endif +char ccase[128] = { +/*NUL*/ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', +/*BS*/ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', +/*DLE*/ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', +/*CAN*/ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', +/*SPC*/ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', +/*(*/ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', +/*0*/ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', +/*8*/ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', +/*@*/ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', +/*H*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', +/*P*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', +/*X*/ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', +/*`*/ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', +/*h*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', +/*p*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', +/*x*/ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177' +}; diff --git a/as/z80/asm.h b/as/z80/asm.h index 812f20bc..af0c054a 100644 --- a/as/z80/asm.h +++ b/as/z80/asm.h @@ -7,598 +7,604 @@ * Alan R. Baldwin * 721 Berkeley St. * Kent, Ohio 44240 + * + * 10-Nov-07 borutr: + * - add proto for strsto + * - change s_id from [NCPS] to pointer + * - change m_id from [NCPS] to pointer + * - change a_id from [NCPS] to pointer + * - change NCPS to 80 + * - case sensitive + * - always define "ccase" */ /* * Extensions: P. Felber */ -#define VERSION "V01.75" +#define VERSION "V01.75" /* * Case Sensitivity Flag */ -#define CASE_SENSITIVE 1 +#define CASE_SENSITIVE 1 -/*)Module asm.h +/*)Module asm.h * - * The module asm.h contains the definitions for constants, - * structures, global variables, and ASxxxx functions - * contained in the ASxxxx.c files. The two functions - * and three global variables from the machine dependent - * files are also defined. + * The module asm.h contains the definitions for constants, + * structures, global variables, and ASxxxx functions + * contained in the ASxxxx.c files. The two functions + * and three global variables from the machine dependent + * files are also defined. */ /* - * compiler/operating system specific definitions + * compiler/operating system specific definitions */ /* DECUS C void definition */ /* File/extension seperator */ -#ifdef decus -#define VOID char -#define FSEPX '.' +#ifdef decus +#define VOID char +#define FSEPX '.' #endif /* PDOS C void definition */ /* File/extension seperator */ -#ifdef PDOS -#define VOID char -#define FSEPX ':' +#ifdef PDOS +#define VOID char +#define FSEPX ':' #endif /* Default void definition */ /* File/extension seperator */ -#ifndef VOID -#define VOID void -#define FSEPX '.' -#define OTHERSYSTEM +#ifndef VOID +#define VOID void +#define FSEPX '.' +#define OTHERSYSTEM #endif /* * Assembler definitions. */ -#define LFTERM '(' /* Left expression delimeter */ -#define RTTERM ')' /* Right expression delimeter */ +#define LFTERM '(' /* Left expression delimeter */ +#define RTTERM ')' /* Right expression delimeter */ #ifdef SDK -#define NCPS 32 /* characters per symbol */ +#define NCPS 80 /* characters per symbol */ #else /* SDK */ -#define NCPS 8 /* Chars. per symbol */ +#define NCPS 8 /* Chars. per symbol */ #endif /* SDK */ -/* #define NCPS 32 */ /* Chars. per symbol */ -#define HUGE 1000 /* A huge number */ -#define NERR 3 /* Errors per line */ -#define NINPUT 1024 /* Input buffer size */ -#define NCODE 128 /* Listing code buffer size */ -#define NTITL 64 /* Title buffer size */ -#define NSBTL 64 /* SubTitle buffer size */ -#define NHASH 64 /* Buckets in hash table */ -#define HMASK 077 /* Hash mask */ -#define NLPP 60 /* Lines per page */ -#define MAXFIL 6 /* Maximum command line input files */ -#define MAXINC 6 /* Maximum nesting of include files */ -#define MAXIF 10 /* Maximum nesting of if/else/endif */ -#define FILSPC 256 /* Chars. in filespec */ - -#define NLIST 0 /* No listing */ -#define SLIST 1 /* Source only */ -#define ALIST 2 /* Address only */ -#define BLIST 3 /* Address only with allocation */ -#define CLIST 4 /* Code */ -#define ELIST 5 /* Equate only */ - -#define dot sym[0] /* Dot, current loc */ -#define dca area[0] /* Dca, default code area */ - - -typedef unsigned int Addr_T; +/* #define NCPS 32 */ /* Chars. per symbol */ +#define HUGE 1000 /* A huge number */ +#define NERR 3 /* Errors per line */ +#define NINPUT 1024 /* Input buffer size */ +#define NCODE 128 /* Listing code buffer size */ +#define NTITL 64 /* Title buffer size */ +#define NSBTL 64 /* SubTitle buffer size */ +#define NHASH 64 /* Buckets in hash table */ +#define HMASK 077 /* Hash mask */ +#define NLPP 60 /* Lines per page */ +#define MAXFIL 6 /* Maximum command line input files */ +#define MAXINC 6 /* Maximum nesting of include files */ +#define MAXIF 10 /* Maximum nesting of if/else/endif */ +#define FILSPC 256 /* Chars. in filespec */ + +#define NLIST 0 /* No listing */ +#define SLIST 1 /* Source only */ +#define ALIST 2 /* Address only */ +#define BLIST 3 /* Address only with allocation */ +#define CLIST 4 /* Code */ +#define ELIST 5 /* Equate only */ + +#define dot sym[0] /* Dot, current loc */ +#define dca area[0] /* Dca, default code area */ + + +typedef unsigned int Addr_T; /* - * The area structure contains the parameter values for a - * specific program or data section. The area structure - * is a linked list of areas. The initial default area - * is "_CODE" defined in asdata.c, the next area structure - * will be linked to this structure through the structure - * element 'struct area *a_ap'. The structure contains the - * area name, area reference number ("_CODE" is 0) determined - * by the order of .area directives, area size determined - * from the total code and/or data in an area, area fuzz is - * a variable used to track pass to pass changes in the - * area size caused by variable length instruction formats, - * and area flags which specify the area's relocation type. + * The area structure contains the parameter values for a + * specific program or data section. The area structure + * is a linked list of areas. The initial default area + * is "_CODE" defined in asdata.c, the next area structure + * will be linked to this structure through the structure + * element 'struct area *a_ap'. The structure contains the + * area name, area reference number ("_CODE" is 0) determined + * by the order of .area directives, area size determined + * from the total code and/or data in an area, area fuzz is + * a variable used to track pass to pass changes in the + * area size caused by variable length instruction formats, + * and area flags which specify the area's relocation type. */ -struct area +struct area { - struct area *a_ap; /* Area link */ - char a_id[NCPS]; /* Area Name */ - int a_ref; /* Ref. number */ - Addr_T a_size; /* Area size */ - Addr_T a_fuzz; /* Area fuzz */ - int a_flag; /* Area flags */ + struct area *a_ap; /* Area link */ + char *a_id; /* Area Name */ + int a_ref; /* Ref. number */ + Addr_T a_size; /* Area size */ + Addr_T a_fuzz; /* Area fuzz */ + int a_flag; /* Area flags */ }; /* - * The "A_" area constants define values used in - * generating the assembler area output data. + * The "A_" area constants define values used in + * generating the assembler area output data. * * Area flags * - * 7 6 5 4 3 2 1 0 - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * | | | | PAG | ABS | OVR | | | - * +-----+-----+-----+-----+-----+-----+-----+-----+ + * 7 6 5 4 3 2 1 0 + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | | | | PAG | ABS | OVR | | | + * +-----+-----+-----+-----+-----+-----+-----+-----+ */ -#define A_CON 000 /* Concatenating */ -#define A_OVR 004 /* Overlaying */ -#define A_REL 000 /* Relocatable */ -#define A_ABS 010 /* absolute */ -#define A_NOPAG 000 /* Non-Paged */ -#define A_PAG 020 /* Paged */ +#define A_CON 000 /* Concatenating */ +#define A_OVR 004 /* Overlaying */ +#define A_REL 000 /* Relocatable */ +#define A_ABS 010 /* absolute */ +#define A_NOPAG 000 /* Non-Paged */ +#define A_PAG 020 /* Paged */ /* - * The "R_" relocation constants define values used in - * generating the assembler relocation output data for - * areas, symbols, and code. + * The "R_" relocation constants define values used in + * generating the assembler relocation output data for + * areas, symbols, and code. * * Relocation flags * - * 7 6 5 4 3 2 1 0 - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * | MSB | PAGn| PAG0| USGN| BYT2| PCR | SYM | BYT | - * +-----+-----+-----+-----+-----+-----+-----+-----+ + * 7 6 5 4 3 2 1 0 + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | MSB | PAGn| PAG0| USGN| BYT2| PCR | SYM | BYT | + * +-----+-----+-----+-----+-----+-----+-----+-----+ */ -#define R_WORD 0000 /* 16 bit */ -#define R_BYTE 0001 /* 8 bit */ +#define R_WORD 0000 /* 16 bit */ +#define R_BYTE 0001 /* 8 bit */ -#define R_AREA 0000 /* Base type */ -#define R_SYM 0002 +#define R_AREA 0000 /* Base type */ +#define R_SYM 0002 -#define R_NORM 0000 /* PC adjust */ -#define R_PCR 0004 +#define R_NORM 0000 /* PC adjust */ +#define R_PCR 0004 -#define R_BYT1 0000 /* Byte count for R_BYTE = 1 */ -#define R_BYT2 0010 /* Byte count for R_BYTE = 2 */ +#define R_BYT1 0000 /* Byte count for R_BYTE = 1 */ +#define R_BYT2 0010 /* Byte count for R_BYTE = 2 */ -#define R_SGND 0000 /* Signed Byte */ -#define R_USGN 0020 /* Unsigned Byte */ +#define R_SGND 0000 /* Signed Byte */ +#define R_USGN 0020 /* Unsigned Byte */ -#define R_NOPAG 0000 /* Page Mode */ -#define R_PAG0 0040 /* Page '0' */ -#define R_PAG 0100 /* Page 'nnn' */ +#define R_NOPAG 0000 /* Page Mode */ +#define R_PAG0 0040 /* Page '0' */ +#define R_PAG 0100 /* Page 'nnn' */ -#define R_LSB 0000 /* low byte */ -#define R_MSB 0200 /* high byte */ +#define R_LSB 0000 /* low byte */ +#define R_MSB 0200 /* high byte */ /* * Listing Control Flags */ -#define R_HIGH 0040000 /* High Byte */ -#define R_RELOC 0100000 /* Relocation */ +#define R_HIGH 0040000 /* High Byte */ +#define R_RELOC 0100000 /* Relocation */ -#define R_DEF 00 /* Global def. */ -#define R_REF 01 /* Global ref. */ -#define R_REL 00 /* Relocatable */ -#define R_ABS 02 /* Absolute */ -#define R_GBL 00 /* Global */ -#define R_LCL 04 /* Local */ +#define R_DEF 00 /* Global def. */ +#define R_REF 01 /* Global ref. */ +#define R_REL 00 /* Relocatable */ +#define R_ABS 02 /* Absolute */ +#define R_GBL 00 /* Global */ +#define R_LCL 04 /* Local */ /* - * The mne structure is a linked list of the assembler - * mnemonics and directives. The list of mnemonics and - * directives contained in the device dependent file - * xxxpst.c are hashed and linked into NHASH lists in - * module assym.c by syminit(). The structure contains - * the mnemonic/directive name, a subtype which directs - * the evaluation of this mnemonic/directive, a flag which - * is used to detect the end of the mnemonic/directive - * list in xxxpst.c, and a value which is normally - * associated with the assembler mnemonic base instruction - * value. + * The mne structure is a linked list of the assembler + * mnemonics and directives. The list of mnemonics and + * directives contained in the device dependent file + * xxxpst.c are hashed and linked into NHASH lists in + * module assym.c by syminit(). The structure contains + * the mnemonic/directive name, a subtype which directs + * the evaluation of this mnemonic/directive, a flag which + * is used to detect the end of the mnemonic/directive + * list in xxxpst.c, and a value which is normally + * associated with the assembler mnemonic base instruction + * value. */ -struct mne +struct mne { - struct mne *m_mp; /* Hash link */ - char m_id[NCPS]; /* Mnemonic */ - char m_type; /* Mnemonic subtype */ - char m_flag; /* Mnemonic flags */ - Addr_T m_valu; /* Value */ + struct mne *m_mp; /* Hash link */ + char *m_id; /* Mnemonic */ + char m_type; /* Mnemonic subtype */ + char m_flag; /* Mnemonic flags */ + Addr_T m_valu; /* Value */ }; /* - * The sym structure is a linked list of symbols defined - * in the assembler source files. The first symbol is "." - * defined in asdata.c. The entry 'struct tsym *s_tsym' - * links any temporary symbols following this symbol and - * preceeding the next normal symbol. The structure also - * contains the symbol's name, type (USER or NEW), flag - * (global, assigned, and multiply defined), a pointer - * to the area structure defining where the symbol is - * located, a reference number assigned by outgsd() in - * asout.c, and the symbols address relative to the base - * address of the area where the symbol is located. + * The sym structure is a linked list of symbols defined + * in the assembler source files. The first symbol is "." + * defined in asdata.c. The entry 'struct tsym *s_tsym' + * links any temporary symbols following this symbol and + * preceeding the next normal symbol. The structure also + * contains the symbol's name, type (USER or NEW), flag + * (global, assigned, and multiply defined), a pointer + * to the area structure defining where the symbol is + * located, a reference number assigned by outgsd() in + * asout.c, and the symbols address relative to the base + * address of the area where the symbol is located. */ -struct sym +struct sym { - struct sym *s_sp; /* Hash link */ - struct tsym *s_tsym; /* Temporary symbol link */ - char s_id[NCPS]; /* Symbol */ - char s_type; /* Symbol subtype */ - char s_flag; /* Symbol flags */ - struct area *s_area; /* Area line, 0 if absolute */ - int s_ref; /* Ref. number */ - Addr_T s_addr; /* Address */ + struct sym *s_sp; /* Hash link */ + struct tsym *s_tsym; /* Temporary symbol link */ + char *s_id; /* Symbol */ + char s_type; /* Symbol subtype */ + char s_flag; /* Symbol flags */ + struct area *s_area; /* Area line, 0 if absolute */ + int s_ref; /* Ref. number */ + Addr_T s_addr; /* Address */ }; -#define S_GBL 01 /* Global */ -#define S_ASG 02 /* Assigned */ -#define S_MDF 04 /* Mult. def */ -#define S_END 010 /* End mark for pst. */ - -#define S_NEW 0 /* New name */ -#define S_USER 1 /* User name */ - /* unused slot */ - /* unused slot */ - /* unused slot */ - -#define S_BYTE 5 /* .byte */ -#define S_WORD 6 /* .word */ -#define S_ASCII 7 /* .ascii */ -#define S_ASCIZ 8 /* .asciz */ -#define S_BLK 9 /* .blkb or .blkw */ -#define S_INCL 10 /* .include */ -#define S_DAREA 11 /* .area */ -#define S_ATYP 12 /* .area type */ -#define S_AREA 13 /* .area name */ -#define S_GLOBL 14 /* .globl */ -#define S_PAGE 15 /* .page */ -#define S_TITLE 16 /* .title */ -#define S_SBTL 17 /* .sbttl */ -#define S_IF 18 /* .if */ -#define S_ELSE 19 /* .else */ -#define S_ENDIF 20 /* .endif */ -#define S_EVEN 21 /* .even */ -#define S_ODD 22 /* .odd */ -#define S_RADIX 23 /* .radix */ -#define S_ORG 24 /* .org */ -#define S_MODUL 25 /* .module */ -#define S_ASCIS 26 /* .ascis */ +#define S_GBL 01 /* Global */ +#define S_ASG 02 /* Assigned */ +#define S_MDF 04 /* Mult. def */ +#define S_END 010 /* End mark for pst. */ + +#define S_NEW 0 /* New name */ +#define S_USER 1 /* User name */ + /* unused slot */ + /* unused slot */ + /* unused slot */ + +#define S_BYTE 5 /* .byte */ +#define S_WORD 6 /* .word */ +#define S_ASCII 7 /* .ascii */ +#define S_ASCIZ 8 /* .asciz */ +#define S_BLK 9 /* .blkb or .blkw */ +#define S_INCL 10 /* .include */ +#define S_DAREA 11 /* .area */ +#define S_ATYP 12 /* .area type */ +#define S_AREA 13 /* .area name */ +#define S_GLOBL 14 /* .globl */ +#define S_PAGE 15 /* .page */ +#define S_TITLE 16 /* .title */ +#define S_SBTL 17 /* .sbttl */ +#define S_IF 18 /* .if */ +#define S_ELSE 19 /* .else */ +#define S_ENDIF 20 /* .endif */ +#define S_EVEN 21 /* .even */ +#define S_ODD 22 /* .odd */ +#define S_RADIX 23 /* .radix */ +#define S_ORG 24 /* .org */ +#define S_MODUL 25 /* .module */ +#define S_ASCIS 26 /* .ascis */ #ifdef SDK # define S_FLOAT 27 /* .df */ #endif -#define S_OPTSDCC 28 /* .optsdcc */ +#define S_OPTSDCC 28 /* .optsdcc */ /* - * The tsym structure is a linked list of temporary - * symbols defined in the assembler source files following - * a normal symbol. The structure contains the temporary - * symbols number, a flag (multiply defined), a pointer to the - * area structure defining where the temporary structure - * is located, and the temporary symbol's address relative - * to the base address of the area where the symbol - * is located. + * The tsym structure is a linked list of temporary + * symbols defined in the assembler source files following + * a normal symbol. The structure contains the temporary + * symbols number, a flag (multiply defined), a pointer to the + * area structure defining where the temporary structure + * is located, and the temporary symbol's address relative + * to the base address of the area where the symbol + * is located. */ -struct tsym +struct tsym { - struct tsym *t_lnk; /* Link to next */ - int t_num; /* 0-lots$ */ - char t_flg; /* flags */ - struct area *t_area; /* Area */ - Addr_T t_addr; /* Address */ + struct tsym *t_lnk; /* Link to next */ + int t_num; /* 0-lots$ */ + char t_flg; /* flags */ + struct area *t_area; /* Area */ + Addr_T t_addr; /* Address */ }; /* - * External Definitions for all Global Variables + * External Definitions for all Global Variables */ -extern int aserr; /* ASxxxx error counter - */ -extern jmp_buf jump_env; /* compiler dependent structure - * used by setjmp() and longjmp() - */ -extern int inpfil; /* count of assembler - * input files specified - */ -extern int incfil; /* current file handle index - * for include files - */ -extern int cfile; /* current file handle index - * of input assembly files - */ -extern int flevel; /* IF-ELSE-ENDIF flag will be non - * zero for false conditional case - */ -extern int tlevel; /* current conditional level - */ -extern int ifcnd[MAXIF+1]; /* array of IF statement condition - * values (0 = FALSE) indexed by tlevel - */ -extern int iflvl[MAXIF+1]; /* array of IF-ELSE-ENDIF flevel - * values indexed by tlevel - */ -extern char - afn[FILSPC]; /* afile() temporary filespec - */ -extern char - srcfn[MAXFIL][FILSPC]; /* array of source file names - */ -extern int - srcline[MAXFIL]; /* current source file line - */ -extern char - incfn[MAXINC][FILSPC]; /* array of include file names - */ -extern int - incline[MAXINC]; /* current include file line - */ -extern int radix; /* current number conversion radix: - * 2 (binary), 8 (octal), 10 (decimal), - * 16 (hexadecimal) - */ -extern int line; /* current assembler source - * line number - */ -extern int page; /* current page number - */ -extern int lop; /* current line number on page - */ -extern int pass; /* assembler pass number - */ -extern int lflag; /* -l, generate listing flag - */ -extern int gflag; /* -g, make undefined symbols global flag - */ -extern int aflag; /* -a, make all symbols global flag - */ -extern int oflag; /* -o, generate relocatable output flag - */ -extern int sflag; /* -s, generate symbol table flag - */ -extern int pflag; /* -p, enable listing pagination - */ -extern int xflag; /* -x, listing radix flag - */ -extern int fflag; /* -f(f), relocations flagged flag - */ -extern Addr_T laddr; /* address of current assembler line - * or value of .if argument - */ -extern Addr_T fuzz; /* tracks pass to pass changes in the - * address of symbols caused by - * variable length instruction formats - */ -extern int lmode; /* listing mode - */ -extern struct area area[]; /* array of 1 area - */ -extern struct area *areap; /* pointer to an area structure - */ -extern struct sym sym[]; /* array of 1 symbol - */ -extern struct sym *symp; /* pointer to a symbol structure - */ -extern struct sym *symhash[NHASH]; /* array of pointers to NHASH - * linked symbol lists - */ -extern struct mne *mnehash[NHASH]; /* array of pointers to NHASH - * linked mnemonic/directive lists - */ -extern char *ep; /* pointer into error list - * array eb[NERR] - */ -extern char eb[NERR]; /* array of generated error codes - */ -extern char *ip; /* pointer into the assembler-source - * text line in ib[] - */ -extern char ib[NINPUT]; /* assembler-source text line - */ -extern char *cp; /* pointer to assembler output - * array cb[] - */ -extern char cb[NCODE]; /* array of assembler output values - */ -extern int *cpt; /* pointer to assembler relocation type - * output array cbt[] - */ -extern int cbt[NCODE]; /* array of assembler relocation types - * describing the data in cb[] - */ -extern char tb[NTITL]; /* Title string buffer - */ -extern char stb[NSBTL]; /* Subtitle string buffer - */ -extern char optsdcc[NINPUT]; /* sdcc compile options - */ -extern char symtbl[]; /* string "Symbol Table" - */ -extern char aretbl[]; /* string "Area Table" - */ -extern char module[NCPS]; /* module name string - */ -extern FILE *lfp; /* list output file handle - */ -extern FILE *ofp; /* relocation output file handle - */ -extern FILE *tfp; /* symbol table output file handle - */ -extern FILE *sfp[MAXFIL]; /* array of assembler-source file handles - */ -extern FILE *ifp[MAXINC]; /* array of include-file file handles - */ -extern unsigned char ctype[128]; /* array of character types, one per - * ASCII character - */ - -#if CASE_SENSITIVE -#else -extern char ccase[128]; /* an array of characters which - * perform the case translation function - */ -#endif +extern int aserr; /* ASxxxx error counter + */ +extern jmp_buf jump_env; /* compiler dependent structure + * used by setjmp() and longjmp() + */ +extern int inpfil; /* count of assembler + * input files specified + */ +extern int incfil; /* current file handle index + * for include files + */ +extern int cfile; /* current file handle index + * of input assembly files + */ +extern int flevel; /* IF-ELSE-ENDIF flag will be non + * zero for false conditional case + */ +extern int tlevel; /* current conditional level + */ +extern int ifcnd[MAXIF+1]; /* array of IF statement condition + * values (0 = FALSE) indexed by tlevel + */ +extern int iflvl[MAXIF+1]; /* array of IF-ELSE-ENDIF flevel + * values indexed by tlevel + */ +extern char + afn[FILSPC]; /* afile() temporary filespec + */ +extern char + srcfn[MAXFIL][FILSPC]; /* array of source file names + */ +extern int + srcline[MAXFIL]; /* current source file line + */ +extern char + incfn[MAXINC][FILSPC]; /* array of include file names + */ +extern int + incline[MAXINC]; /* current include file line + */ +extern int radix; /* current number conversion radix: + * 2 (binary), 8 (octal), 10 (decimal), + * 16 (hexadecimal) + */ +extern int line; /* current assembler source + * line number + */ +extern int page; /* current page number + */ +extern int lop; /* current line number on page + */ +extern int pass; /* assembler pass number + */ +extern int lflag; /* -l, generate listing flag + */ +extern int gflag; /* -g, make undefined symbols global flag + */ +extern int aflag; /* -a, make all symbols global flag + */ +extern int oflag; /* -o, generate relocatable output flag + */ +extern int sflag; /* -s, generate symbol table flag + */ +extern int pflag; /* -p, enable listing pagination + */ +extern int xflag; /* -x, listing radix flag + */ +extern int fflag; /* -f(f), relocations flagged flag + */ +extern Addr_T laddr; /* address of current assembler line + * or value of .if argument + */ +extern Addr_T fuzz; /* tracks pass to pass changes in the + * address of symbols caused by + * variable length instruction formats + */ +extern int lmode; /* listing mode + */ +extern struct area area[]; /* array of 1 area + */ +extern struct area *areap; /* pointer to an area structure + */ +extern struct sym sym[]; /* array of 1 symbol + */ +extern struct sym *symp; /* pointer to a symbol structure + */ +extern struct sym *symhash[NHASH]; /* array of pointers to NHASH + * linked symbol lists + */ +extern struct mne *mnehash[NHASH]; /* array of pointers to NHASH + * linked mnemonic/directive lists + */ +extern char *ep; /* pointer into error list + * array eb[NERR] + */ +extern char eb[NERR]; /* array of generated error codes + */ +extern char *ip; /* pointer into the assembler-source + * text line in ib[] + */ +extern char ib[NINPUT]; /* assembler-source text line + */ +extern char *cp; /* pointer to assembler output + * array cb[] + */ +extern char cb[NCODE]; /* array of assembler output values + */ +extern int *cpt; /* pointer to assembler relocation type + * output array cbt[] + */ +extern int cbt[NCODE]; /* array of assembler relocation types + * describing the data in cb[] + */ +extern char tb[NTITL]; /* Title string buffer + */ +extern char stb[NSBTL]; /* Subtitle string buffer + */ +extern char optsdcc[NINPUT]; /* sdcc compile options + */ +extern char symtbl[]; /* string "Symbol Table" + */ +extern char aretbl[]; /* string "Area Table" + */ +extern char module[NCPS]; /* module name string + */ +extern FILE *lfp; /* list output file handle + */ +extern FILE *ofp; /* relocation output file handle + */ +extern FILE *tfp; /* symbol table output file handle + */ +extern FILE *sfp[MAXFIL]; /* array of assembler-source file handles + */ +extern FILE *ifp[MAXINC]; /* array of include-file file handles + */ +extern unsigned char ctype[128]; /* array of character types, one per + * ASCII character + */ +extern char ccase[128]; /* an array of characters which + * perform the case translation function + */ /* * Definitions for Character Types */ -#define SPACE 0000 -#define ETC 0000 -#define LETTER 0001 -#define DIGIT 0002 -#define BINOP 0004 -#define RAD2 0010 -#define RAD8 0020 -#define RAD10 0040 -#define RAD16 0100 -#define ILL 0200 - -#define DGT2 DIGIT|RAD16|RAD10|RAD8|RAD2 -#define DGT8 DIGIT|RAD16|RAD10|RAD8 -#define DGT10 DIGIT|RAD16|RAD10 -#define LTR16 LETTER|RAD16 +#define SPACE 0000 +#define ETC 0000 +#define LETTER 0001 +#define DIGIT 0002 +#define BINOP 0004 +#define RAD2 0010 +#define RAD8 0020 +#define RAD10 0040 +#define RAD16 0100 +#define ILL 0200 + +#define DGT2 DIGIT|RAD16|RAD10|RAD8|RAD2 +#define DGT8 DIGIT|RAD16|RAD10|RAD8 +#define DGT10 DIGIT|RAD16|RAD10 +#define LTR16 LETTER|RAD16 /* - * The exp structure is used to return the evaluation - * of an expression. The structure supports three valid - * cases: - * (1) The expression evaluates to a constant, - * mode = S_USER, flag = 0, addr contains the - * constant, and base = NULL. - * (2) The expression evaluates to a defined symbol - * plus or minus a constant, mode = S_USER, - * flag = 0, addr contains the constant, and - * base = pointer to area symbol. - * (3) The expression evaluates to a external - * global symbol plus or minus a constant, - * mode = S_NEW, flag = 1, addr contains the - * constant, and base = pointer to symbol. + * The exp structure is used to return the evaluation + * of an expression. The structure supports three valid + * cases: + * (1) The expression evaluates to a constant, + * mode = S_USER, flag = 0, addr contains the + * constant, and base = NULL. + * (2) The expression evaluates to a defined symbol + * plus or minus a constant, mode = S_USER, + * flag = 0, addr contains the constant, and + * base = pointer to area symbol. + * (3) The expression evaluates to a external + * global symbol plus or minus a constant, + * mode = S_NEW, flag = 1, addr contains the + * constant, and base = pointer to symbol. */ -struct expr +struct expr { - char e_mode; /* Address mode */ - char e_flag; /* Symbol flag */ - Addr_T e_addr; /* Address */ - union { - struct area *e_ap; - struct sym *e_sp; - } e_base; /* Rel. base */ - char e_rlcf; /* Rel. flags */ + char e_mode; /* Address mode */ + char e_flag; /* Symbol flag */ + Addr_T e_addr; /* Address */ + union { + struct area *e_ap; + struct sym *e_sp; + } e_base; /* Rel. base */ + char e_rlcf; /* Rel. flags */ }; /* C Library functions */ /* for reference only -extern VOID exit(); -extern int fclose(); -extern char * fgets(); -extern FILE * fopen(); -extern int fprintf(); -extern VOID longjmp(); -extern VOID * malloc(); -extern int printf(); -extern char putc(); -extern int rewind(); -extern int setjmp(); -extern int strcmp(); -extern char * strcpy(); -extern int strlen(); -extern char * strncpy(); +extern VOID exit(); +extern int fclose(); +extern char * fgets(); +extern FILE * fopen(); +extern int fprintf(); +extern VOID longjmp(); +extern VOID * malloc(); +extern int printf(); +extern char putc(); +extern int rewind(); +extern int setjmp(); +extern int strcmp(); +extern char * strcpy(); +extern int strlen(); +extern char * strncpy(); */ /* Machine independent functions */ /* asmain.c */ -extern FILE * afile(); -extern VOID asexit(); -extern VOID asmbl(); -extern int main(); -extern VOID newdot(); -extern VOID phase(); -extern VOID usage(); +extern FILE * afile(); +extern VOID asexit(); +extern VOID asmbl(); +extern int main(); +extern VOID newdot(); +extern VOID phase(); +extern VOID usage(); /* aslex.c */ -extern char endline(); -extern char get(); -extern VOID getid(); -extern int as_getline(); -extern int getmap(); -extern char getnb(); -extern VOID getst(); -extern int more(); -extern VOID unget(); +extern char endline(); +extern char get(); +extern VOID getid(); +extern int as_getline(); +extern int getmap(); +extern char getnb(); +extern VOID getst(); +extern int more(); +extern VOID unget(); /* assym.c */ -extern struct area * alookup(); -extern struct mne * mlookup(); -extern int hash(); -extern struct sym * lookup(); -extern VOID * new(); -extern int symeq(); -extern VOID syminit(); -extern VOID symglob(); -extern VOID allglob(); +extern struct area * alookup(); +extern struct mne * mlookup(); +extern int hash(); +extern struct sym * lookup(); +extern VOID * new(); +extern char * strsto(char *str); +extern int symeq(); +extern VOID syminit(); +extern VOID symglob(); +extern VOID allglob(); /* assubr.c */ -extern VOID aerr(); -extern VOID diag(); -extern VOID err(); -extern char * geterr(); -extern VOID qerr(); -extern VOID rerr(); +extern VOID aerr(); +extern VOID diag(); +extern VOID err(); +extern char * geterr(); +extern VOID qerr(); +extern VOID rerr(); /* asexpr.c */ -extern VOID abscheck(); -extern Addr_T absexpr(); -extern VOID clrexpr(); -extern int digit(); -extern int is_abs(); -extern VOID expr(); -extern int oprio(); -extern VOID term(); +extern VOID abscheck(); +extern Addr_T absexpr(); +extern VOID clrexpr(); +extern int digit(); +extern int is_abs(); +extern VOID expr(); +extern int oprio(); +extern VOID term(); /* aslist.c */ -extern VOID list(); -extern VOID list1(); -extern VOID list2(); -extern VOID lstsym(); -extern VOID slew(); +extern VOID list(); +extern VOID list1(); +extern VOID list2(); +extern VOID lstsym(); +extern VOID slew(); /* asout.c */ -extern int hibyte(); -extern int lobyte(); -extern VOID out(); -extern VOID outab(); -extern VOID outarea(); -extern VOID outaw(); -extern VOID outall(); -extern VOID outdot(); -extern VOID outbuf(); -extern VOID outchk(); -extern VOID outgsd(); -extern VOID outrb(); -extern VOID outrw(); -extern VOID outsym(); -extern VOID out_lb(); -extern VOID out_lw(); -extern VOID out_rw(); -extern VOID out_tw(); +extern int hibyte(); +extern int lobyte(); +extern VOID out(); +extern VOID outab(); +extern VOID outarea(); +extern VOID outaw(); +extern VOID outall(); +extern VOID outdot(); +extern VOID outbuf(); +extern VOID outchk(); +extern VOID outgsd(); +extern VOID outrb(); +extern VOID outrw(); +extern VOID outsym(); +extern VOID out_lb(); +extern VOID out_lw(); +extern VOID out_rw(); +extern VOID out_tw(); /* Machine dependent variables */ -extern char * cpu; -extern char * dsft; -extern int hilo; -extern struct mne mne[]; +extern char * cpu; +extern char * dsft; +extern int hilo; +extern struct mne mne[]; /* Machine dependent functions */ -extern VOID minit(); +extern VOID minit(); /* strcmpi.c */ -extern int as_strcmpi(const char *s1, const char *s2); -extern int as_strncmpi(const char *s1, const char *s2, size_t n); +extern int as_strcmpi(const char *s1, const char *s2); +extern int as_strncmpi(const char *s1, const char *s2, size_t n); diff --git a/as/z80/asmain.c b/as/z80/asmain.c index 8e3041f2..9e6c6381 100644 --- a/as/z80/asmain.c +++ b/as/z80/asmain.c @@ -25,1201 +25,1194 @@ #include "asm.h" #include "z80.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 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 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 main(int argc, char **argv) { - register char *p; - register int c, i; - struct area *ap; + register char *p; + register int c, i; + struct area *ap; - /* Check to make sure there are the right number of filenames */ - /* before openning any of them */ + /* Check to make sure there are the right number of filenames */ + /* before openning any of them */ #ifdef SDK - inpfil = -2; + inpfil = -2; #else /* SDK */ - inpfil = -1; + inpfil = -1; #endif /* SDK */ - for (i=1; i= 0) - usage(); - ++p; - while ((c = *p++) != 0) - switch(c) { - - case 'a': - case 'A': - ++aflag; - break; - - case 'g': - case 'G': - ++gflag; - 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 { + pflag = 1; + for (i=1; i= 0) + usage(); + ++p; + while ((c = *p++) != 0) + switch(c) { + + case 'a': + case 'A': + ++aflag; + break; + + case 'g': + case 'G': + ++gflag; + 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 { #ifdef SDK - if(inpfil != -2) { + if(inpfil != -2) { #endif /* SDK */ - if (++inpfil == MAXFIL) { - fprintf(stderr, "too many input files\n"); - asexit(1); - } - sfp[inpfil] = afile(p, "", 0); - strcpy(srcfn[inpfil],afn); + if (++inpfil == MAXFIL) { + fprintf(stderr, "too many input files\n"); + asexit(1); + } + sfp[inpfil] = afile(p, "", 0); + strcpy(srcfn[inpfil],afn); #ifdef SDK - } else - inpfil++; - if (inpfil == -1) { - if (lflag) - lfp = afile(p, "lst", 1); - if (oflag) - ofp = afile(p, "", 1); - if (sflag) - tfp = afile(p, "sym", 1); - } + } else + inpfil++; + if (inpfil == -1) { + if (lflag) + lfp = afile(p, "lst", 1); + if (oflag) + ofp = afile(p, "", 1); + if (sflag) + tfp = afile(p, "sym", 1); + } #else /* SDK */ - if (inpfil == 0) { - if (lflag) - lfp = afile(p, "LST", 1); - if (oflag) - ofp = afile(p, "REL", 1); - if (sflag) - tfp = afile(p, "SYM", 1); - } + if (inpfil == 0) { + if (lflag) + lfp = afile(p, "LST", 1); + if (oflag) + ofp = afile(p, "REL", 1); + if (sflag) + tfp = afile(p, "SYM", 1); + } #endif /* SDK */ - } - } - 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; - 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); - } - asexit(aserr != 0); - /* Never reached */ - return 0; + } + } + 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; + 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); + } + asexit(aserr != 0); + /* Never reached */ + return 0; } -/*)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; +asexit(int i) { - int j; + int j; - if (lfp != NULL) fclose(lfp); - if (ofp != NULL) fclose(ofp); - if (tfp != NULL) fclose(tfp); + 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) { + 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 { - 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; + 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; #ifdef SDK - case S_FLOAT: - do { - getid( readbuffer, ' ' ); /* Hack :) */ - if ((c=getnb())=='.') - { - getid(&readbuffer[strlen(readbuffer)],'.'); - } - else - unget(c); - - f1 = strtod( readbuffer, (char **)NULL ); - /* Convert f1 to a gb-lib type fp - * 24 bit mantissa followed by 7 bit exp and 1 bit sign - */ - - if (f1!=0) - { - - f2 = floor(log(fabs(f1))/log(2))+1; - mantissa = (unsigned int) ((0x1000000*fabs(f1))/exp(f2*log(2))) ; - mantissa &=0xffffff; - exponent = (unsigned int) (f2 + 0x40) ; - if (f1<0) - exponent |=0x80; - } - - else - { - mantissa=0; - exponent=0; - } - - outab(mantissa&0xff); - outab((mantissa>>8)&0xff); - outab((mantissa>>16)&0xff); - outab(exponent&0xff); - - } while ((c = getnb()) == ','); - unget(c); - break; + case S_FLOAT: + do { + getid( readbuffer, ' ' ); /* Hack :) */ + if ((c=getnb())=='.') + { + getid(&readbuffer[strlen(readbuffer)],'.'); + } + else + unget(c); + + f1 = strtod( readbuffer, (char **)NULL ); + /* Convert f1 to a gb-lib type fp + * 24 bit mantissa followed by 7 bit exp and 1 bit sign + */ + + if (f1!=0) + { + + f2 = floor(log(fabs(f1))/log(2))+1; + mantissa = (unsigned int) ((0x1000000*fabs(f1))/exp(f2*log(2))) ; + mantissa &=0xffffff; + exponent = (unsigned int) (f2 + 0x40) ; + if (f1<0) + exponent |=0x80; + } + + else + { + mantissa=0; + exponent=0; + } + + outab(mantissa&0xff); + outab((mantissa>>8)&0xff); + outab((mantissa>>16)&0xff); + outab(exponent&0xff); + + } while ((c = getnb()) == ','); + unget(c); + break; #endif - 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); - dot.s_addr += e1.e_addr*mp->m_valu; - outchk(HUGE,HUGE); - 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_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); + dot.s_addr += e1.e_addr*mp->m_valu; + outchk(HUGE,HUGE); + 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; 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 = 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[FILSPC-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; - - /* - * If not an assembler directive then go to - * the machine dependent function which handles - * all the assembler mnemonics. - */ - default: - machine(mp); - } - goto loop; + 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; + ap->a_id = strsto(id); + 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 = 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[FILSPC-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; + + /* + * If not an assembler directive then go to + * the machine dependent function which handles + * all the assembler mnemonics. + */ + default: + machine(mp); + } + 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 * -afile(fn, ft, wf) -char *fn; -char *ft; -int wf; +afile(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[FILSPC-4]) // truncate filename, if it's too long - p2 = &afn[FILSPC-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[FILSPC-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[FILSPC-4]) // truncate filename, if it's too long + p2 = &afn[FILSPC-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[FILSPC-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; +newdot(struct area *nap) { - register struct area *oap; - - oap = dot.s_area; - oap->a_fuzz = fuzz; - oap->a_size = dot.s_addr; - fuzz = nap->a_fuzz; - dot.s_area = nap; - dot.s_addr = nap->a_size; - outall(); + register struct area *oap; + + oap = dot.s_area; + oap->a_fuzz = fuzz; + oap->a_size = dot.s_addr; + fuzz = nap->a_fuzz; + dot.s_area = nap; + dot.s_addr = nap->a_size; + 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 -phase(ap, a) -struct area *ap; -Addr_T a; +phase(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[] = { #ifdef SDK - "Usage: [-dqxgalopsf] outfile file1 [file2 file3 ...]", + "Usage: [-dqxgalopsf] outfile file1 [file2 file3 ...]", #else /* SDK */ - "Usage: [-dqxgalopsf] file1 [file2 file3 ...]", + "Usage: [-dqxgalopsf] file1 [file2 file3 ...]", #endif /* SDK */ - " d decimal listing", - " q octal listing", - " x hex listing (default)", - " g undefined symbols made global", - " a all user symbols made global", + " d decimal listing", + " q octal listing", + " x hex listing (default)", + " g undefined symbols made global", + " a all user symbols made global", #ifdef SDK - " l create list output outfile[LST]", - " o create object output outfile[o]", - " s create symbol output outfile[SYM]", + " l create list output outfile[LST]", + " o create object output outfile[o]", + " s create symbol output outfile[SYM]", #else /* SDK */ - " l create list output file1[LST]", - " o create object output file1[REL]", - " s create symbol output file1[SYM]", + " l create list output file1[LST]", + " o create object output file1[REL]", + " s create symbol output file1[SYM]", #endif /* SDK */ - " p disable listing pagination", - " f flag relocatable references by ` in listing file", - " ff flag relocatable references by mode in listing file", - "", - 0 + " 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() +usage(void) { - 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/z80/assym.c b/as/z80/assym.c index 771f5320..13d175a8 100644 --- a/as/z80/assym.c +++ b/as/z80/assym.c @@ -7,6 +7,18 @@ * Alan R. Baldwin * 721 Berkeley St. * Kent, Ohio 44240 + * + * 10-Nov-07 borutr: + * - use strsto instead StoreString and include it in assym.c + * for compatibility with the original asxxxx + * - applied changes from 28-Oct-97 JLH: + * - lookup: Use StoreString for sym construction + * - change symeq() to do length-independent string compare + * - change hash() to do length-independent hash calculation + * - applied changes from 29-Oct-97 JLH: + * - make mnemonics case insensitive ALWAYS + * - make hash() case-insensitive always + * - replace symeq() call in mlookup with strcmpi */ #include @@ -15,427 +27,479 @@ #include #include "asm.h" -/*)Module assym.c +/*)Module assym.c * - * The module assym.c contains the functions that operate - * on the mnemonic/directive and symbol structures. + * The module assym.c contains the functions that operate + * on the mnemonic/directive and symbol structures. * - * assym.c contains the following functions: - * VOID allglob() - * area * alookup() - * int hash() - * sym * lookup() - * mne * mlookup() - * VOID * new() - * int symeq() - * VOID syminit() - * VOID symglob() + * assym.c contains the following functions: + * VOID allglob() + * area * alookup() + * int hash() + * sym * lookup() + * mne * mlookup() + * VOID * new() + * int symeq() + * VOID syminit() + * VOID symglob() * - * assym.c contains no local/static variables. + * assym.c contains no local/static variables. */ -/*)Function VOID syminit() - * - * The function syminit() is called early in the game - * to set up the hashtables. First all buckets in a - * table are cleared. Then a pass is made through - * the respective symbol lists, linking them into - * their hash buckets. Finally the base area pointer - * is set to 'dca'. - * - * local variables: - * int h computed hash value - * mne * mp pointer to a mne structure - * mne ** mpp pointer to an array of - * mne structure pointers - * sym * sp pointer to a sym structure - * sym ** spp pointer to an array of - * sym structure pointers - * - * global variables: - * area area[] single elememt area array - * area dca defined as area[0] - * mne * mnehash[] array of pointers to NHASH - * linked mnemonic/directive lists - * sym * symhash[] array of pointers to NHASH - * linked symbol lists - * - * functions called: - * none - * - * side effects: - * (1) The symbol hash tables are initialized, - * the only defined symbol is '.'. - * (2) The mnemonic/directive hash tables are - * initialized with the assembler directives - * and mnemonics found in the machine dependent - * file ___pst.c. - * (3) The area pointer is initialized to dca (area[0]). +/*)Function VOID syminit() + * + * The function syminit() is called early in the game + * to set up the hashtables. First all buckets in a + * table are cleared. Then a pass is made through + * the respective symbol lists, linking them into + * their hash buckets. Finally the base area pointer + * is set to 'dca'. + * + * local variables: + * int h computed hash value + * mne * mp pointer to a mne structure + * mne ** mpp pointer to an array of + * mne structure pointers + * sym * sp pointer to a sym structure + * sym ** spp pointer to an array of + * sym structure pointers + * + * global variables: + * area area[] single elememt area array + * area dca defined as area[0] + * mne * mnehash[] array of pointers to NHASH + * linked mnemonic/directive lists + * sym * symhash[] array of pointers to NHASH + * linked symbol lists + * + * functions called: + * none + * + * side effects: + * (1) The symbol hash tables are initialized, + * the only defined symbol is '.'. + * (2) The mnemonic/directive hash tables are + * initialized with the assembler directives + * and mnemonics found in the machine dependent + * file ___pst.c. + * (3) The area pointer is initialized to dca (area[0]). */ VOID -syminit() +syminit(void) { - register struct mne *mp; - struct mne **mpp; - register struct sym *sp; - struct sym **spp; - register int h; - - mpp = &mnehash[0]; - while (mpp < &mnehash[NHASH]) - *mpp++ = NULL; - mp = &mne[0]; - for (;;) { - h = hash(mp->m_id); - mp->m_mp = mnehash[h]; - mnehash[h] = mp; - if (mp->m_flag&S_END) - break; - ++mp; - } - - spp = &symhash[0]; - while (spp < &symhash[NHASH]) - *spp++ = NULL; - sp = &sym[0]; - for (;;) { - h = hash(sp->s_id); - sp->s_sp = symhash[h]; - symhash[h] = sp; - if (sp->s_flag&S_END) - break; - ++sp; - } - - areap = &dca; + register struct mne *mp; + struct mne **mpp; + register struct sym *sp; + struct sym **spp; + register int h; + + mpp = &mnehash[0]; + while (mpp < &mnehash[NHASH]) + *mpp++ = NULL; + mp = &mne[0]; + for (;;) { + h = hash(mp->m_id); + mp->m_mp = mnehash[h]; + mnehash[h] = mp; + if (mp->m_flag&S_END) + break; + ++mp; + } + + spp = &symhash[0]; + while (spp < &symhash[NHASH]) + *spp++ = NULL; + sp = &sym[0]; + for (;;) { + h = hash(sp->s_id); + sp->s_sp = symhash[h]; + symhash[h] = sp; + if (sp->s_flag&S_END) + break; + ++sp; + } + + areap = &dca; } -/*)Function area * alookup(id) +/*)Function area * alookup(id) * - * char * id area name string + * char * id area name string * - * The function alookup() searches the area list for a - * match with id. If the area is defined then a pointer - * to this area is returned else a NULL is returned. + * The function alookup() searches the area list for a + * match with id. If the area is defined then a pointer + * to this area is returned else a NULL is returned. * - * local variables: - * area * ap pointer to area structure + * local variables: + * area * ap pointer to area structure * - * global variables: - * area * areap pointer to an area structure + * global variables: + * area * areap pointer to an area structure * - * functions called: - * int symeq() assym.c + * functions called: + * int symeq() assym.c * - * side effects: - * none + * side effects: + * none */ struct area * -alookup(id) -char *id; +alookup(char *id) { - register struct area *ap; - - ap = areap; - while (ap) { - if (symeq(id, ap->a_id)) { - return (ap); - } - ap = ap->a_ap; - } - return(NULL); + register struct area *ap; + + ap = areap; + while (ap) { + if (symeq(id, ap->a_id)) { + return (ap); + } + ap = ap->a_ap; + } + return(NULL); } -/*)Function mne * mlookup(id) +/*)Function mne * mlookup(id) * - * char * id mnemonic/directive name string + * char * id mnemonic/directive name string * - * The function mlookup() searches the mnemonic/directive - * hash tables for a match returning a pointer to the - * mne structure else it returns a NULL. + * The function mlookup() searches the mnemonic/directive + * hash tables for a match returning a pointer to the + * mne structure else it returns a NULL. * - * local variables: - * mne * mp pointer to mne structure - * int h calculated hash value + * local variables: + * mne * mp pointer to mne structure + * int h calculated hash value * - * global variables: - * mne * mnehash[] array of pointers to NHASH - * linked mnemonic/directive lists + * global variables: + * mne * mnehash[] array of pointers to NHASH + * linked mnemonic/directive lists * - * functions called: - * none + * functions called: + * none * - * side effects: - * none + * side effects: + * none */ struct mne * -mlookup(id) -char *id; +mlookup(char *id) { - register struct mne *mp; - register int h; - - h = hash(id); - mp = mnehash[h]; - while (mp) { - if (as_strcmpi(id, mp->m_id) == 0) /* JLH: case insensitive */ - return (mp); - mp = mp->m_mp; - } - return (NULL); + register struct mne *mp; + register int h; + + h = hash(id); + mp = mnehash[h]; + while (mp) { + if (as_strcmpi(id, mp->m_id) == 0) /* JLH: case insensitive */ + return (mp); + mp = mp->m_mp; + } + return (NULL); } -/*)Function sym * lookup(id) +/*)Function sym * lookup(id) * - * char * id symbol name string + * char * id symbol name string * - * The function lookup() searches the symbol hash tables for - * a symbol name match returning a pointer to the sym structure. - * If the symbol is not found then a sym structure is created, - * initialized, and linked to the appropriate hash table. - * A pointer to this new sym structure is returned. + * The function lookup() searches the symbol hash tables for + * a symbol name match returning a pointer to the sym structure. + * If the symbol is not found then a sym structure is created, + * initialized, and linked to the appropriate hash table. + * A pointer to this new sym structure is returned. * - * local variables: - * int h computed hash value - * sym * sp pointer to a sym structure + * local variables: + * int h computed hash value + * sym * sp pointer to a sym structure * - * global varaibles: - * sym * symhash[] array of pointers to NHASH - * linked symbol lists + * global varaibles: + * sym * symhash[] array of pointers to NHASH + * linked symbol lists * - * functions called: - * int hash() assym.c - * VOID * new() assym.c - * int symeq() assym.c + * functions called: + * int hash() assym.c + * VOID * new() assym.c + * int symeq() assym.c * - * side effects: - * If the function new() fails to allocate space - * for the new sym structure the assembly terminates. + * side effects: + * If the function new() fails to allocate space + * for the new sym structure the assembly terminates. */ struct sym * -lookup(id) -char *id; +lookup(char *id) { - register struct sym *sp; - register int h; - - h = hash(id); - sp = symhash[h]; - while (sp) { - if (symeq(id, sp->s_id)) - return (sp); - sp = sp->s_sp; - } - sp = (struct sym *) new (sizeof(struct sym)); - sp->s_sp = symhash[h]; - symhash[h] = sp; - sp->s_tsym = NULL; - strncpy(sp->s_id, id, NCPS); - sp->s_type = S_NEW; - sp->s_flag = 0; - sp->s_area = NULL; - sp->s_ref = 0; - sp->s_addr = 0; - return (sp); + register struct sym *sp; + register int h; + + h = hash(id); + sp = symhash[h]; + while (sp) { + if (symeq(id, sp->s_id)) + return (sp); + sp = sp->s_sp; + } + sp = (struct sym *) new (sizeof(struct sym)); + sp->s_sp = symhash[h]; + symhash[h] = sp; + sp->s_tsym = NULL; + sp->s_id = strsto(id); + sp->s_type = S_NEW; + sp->s_flag = 0; + sp->s_area = NULL; + sp->s_ref = 0; + sp->s_addr = 0; + return (sp); } -/*)Function VOID symglob() +/*)Function VOID symglob() * - * The function symglob() will mark all symbols of - * type S_NEW as global. Called at the beginning of pass 1 - * if the assembly option -g was specified. + * The function symglob() will mark all symbols of + * type S_NEW as global. Called at the beginning of pass 1 + * if the assembly option -g was specified. * - * local variables: - * sym * sp pointer to a sym structure - * int i loop index + * local variables: + * sym * sp pointer to a sym structure + * int i loop index * - * global variables: - * sym * symhash[] array of pointers to NHASH - * linked symbol lists + * global variables: + * sym * symhash[] array of pointers to NHASH + * linked symbol lists * - * functions called: - * none + * functions called: + * none * - * side effects: - * Symbol types changed. + * side effects: + * Symbol types changed. */ VOID -symglob() +symglob(void) { - register struct sym *sp; - register int i; - - for (i=0; is_type == S_NEW) - sp->s_flag |= S_GBL; - sp = sp->s_sp; - } - } + register struct sym *sp; + register int i; + + for (i=0; is_type == S_NEW) + sp->s_flag |= S_GBL; + sp = sp->s_sp; + } + } } -/*)Function VOID allglob() +/*)Function VOID allglob() * - * The function allglob() will mark all symbols of - * type S_USER as global. Called at the beginning of pass 1 - * if the assembly option -a was specified. + * The function allglob() will mark all symbols of + * type S_USER as global. Called at the beginning of pass 1 + * if the assembly option -a was specified. * - * local variables: - * sym * sp pointer to a sym structure - * int i loop index + * local variables: + * sym * sp pointer to a sym structure + * int i loop index * - * global variables: - * sym * symhash[] array of pointers to NHASH - * linked symbol lists + * global variables: + * sym * symhash[] array of pointers to NHASH + * linked symbol lists * - * functions called: - * none + * functions called: + * none * - * side effects: - * Symbol types changed. + * side effects: + * Symbol types changed. */ VOID -allglob() +allglob(void) { - register struct sym *sp; - register int i; - - for (i=0; is_type == S_USER) - sp->s_flag |= S_GBL; - sp = sp->s_sp; - } - } + register struct sym *sp; + register int i; + + for (i=0; is_type == S_USER) + sp->s_flag |= S_GBL; + sp = sp->s_sp; + } + } } -/*)Function int symeq(p1, p2) +/*)Function int symeq(p1, p2) * - * char * p1 name string - * char * p2 name string + * char * p1 name string + * char * p2 name string * - * The function symeq() compares the two name strings for a match. - * The return value is 1 for a match and 0 for no match. + * The function symeq() compares the two name strings for a match. + * The return value is 1 for a match and 0 for no match. * - * local variables: - * int h loop counter + * local variables: + * int h loop counter * - * global variables: - * char ccase[] an array of characters which - * perform the case translation function + * global variables: + * char ccase[] an array of characters which + * perform the case translation function * - * functions called: - * none + * functions called: + * none * - * side effects: - * none + * side effects: + * none * */ int -symeq(p1, p2) -register char *p1, *p2; +symeq(char *p1, char *p2) { - register int n; - - n = NCPS; - do { - -#if CASE_SENSITIVE - if (*p1++ != *p2++) - return (0); +#if CASE_SENSITIVE + return (strcmp( p1, p2 ) == 0); #else - if (ccase[(unsigned char)(*p1++)] != ccase[(unsigned char)(*p2++)]) - return (0); + return (as_strcmpi( p1, p2 ) == 0); #endif - - } while (--n); - return (1); } -/*)Function int hash(p) +/*)Function int hash(p) * - * char * p pointer to string to hash + * char * p pointer to string to hash * - * The function hash() computes a hash code using the sum - * of all characters mod table size algorithm. + * The function hash() computes a hash code using the sum + * of all characters mod table size algorithm. * - * local variables: - * int h accumulated character sum - * int n loop counter + * local variables: + * int h accumulated character sum + * int n loop counter * - * global variables: - * char ccase[] an array of characters which - * perform the case translation function + * global variables: + * char ccase[] an array of characters which + * perform the case translation function * - * functions called: - * none + * functions called: + * none * - * side effects: - * none + * side effects: + * none */ int -hash(p) -register char *p; +hash(char *p) { - register int h, n; + register int h; + + h = 0; + while (*p) { + /* JLH: case insensitive hash: Doesn't much affect + * hashing, and allows same function for mnemonics and symbols + */ + h += ccase[(int)*p++]; + } + return (h&HMASK); +} - h = 0; - n = NCPS; - do { +/*)Function char * strsto(str) + * + * char * str pointer to string to save + * + * Allocate space for "str", copy str into new space. + * Return a pointer to the allocated string. + * + * This function based on code by + * John L. Hartman + * jhartman at compuserve dot com + * + * local variables: + * int l string length + 1 + * int bytes bytes remaining in buffer area + * char * p pointer to head of copied string + * char * pnext next location in buffer area + * + * global variables: + * none + * + * functions called: + * VOID * new() assym.c + * char * strncpy() c_library + * + * side effects: + * Space allocated for string, string copied + * to space. Out of Space terminates assembler. + */ -#if CASE_SENSITIVE - h += *p++; -#else - h += ccase[(unsigned char)(*p++)]; -#endif +/* + * To avoid wasting memory headers on small allocations, we + * allocate a big chunk and parcel it out as required. + * These static variables remember our hunk + */ - } while (--n); - return (h&HMASK); +#define STR_SPC 1024 +static char * pnext = NULL; +static int bytes = 0; + +char * +strsto(char *str) +{ + int l; + char *p; + + /* + * What we need, including a null. + */ + l = strlen(str) + 1; + + if (l > bytes) { + /* + * No space. Allocate a new hunk. + * We lose the pointer to any old hunk. + * We don't care, as the names are never deleted. + */ + pnext = (char *) new (STR_SPC); + bytes = STR_SPC; + } + + /* + * Copy the name and terminating null. + */ + p = pnext; + strncpy(p, str, l); + + pnext += l; + bytes -= l; + + return(p); } -/*)Function VOID * new(n) +/*)Function VOID * new(n) * - * unsigned int n allocation size in bytes + * unsigned int n allocation size in bytes * - * The function new() allocates n bytes of space and returns - * a pointer to this memory. If no space is available the - * assembly is terminated. + * The function new() allocates n bytes of space and returns + * a pointer to this memory. If no space is available the + * assembly is terminated. * - * local variables: - * VOID * p a general pointer + * local variables: + * VOID * p a general pointer * - * global variables: - * none + * global variables: + * none * - * functions called: - * VOID asexit() asmain.c - * int fprintf() c_library - * VOID * malloc() c_library + * functions called: + * VOID asexit() asmain.c + * int fprintf() c_library + * VOID * malloc() c_library * - * side effects: - * Memory is allocated, if allocation fails - * the assembly is terminated. + * side effects: + * Memory is allocated, if allocation fails + * the assembly is terminated. */ VOID * -new(n) -unsigned int n; +new(unsigned int n) { - register VOID *p; + register VOID *p; - if ((p = (VOID *) malloc(n)) == NULL) { - fprintf(stderr, "Out of space!\n"); - asexit(1); - } - return (p); + if ((p = (VOID *) malloc(n)) == NULL) { + fprintf(stderr, "Out of space!\n"); + asexit(1); + } + return (p); }