From 49cce96fba11282e4244187f15be418d5ae5bb8d Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Fri, 23 Nov 2012 10:39:09 -0600 Subject: [PATCH] Code cleanup and prepartion for 64-bit host fixes I removed a few functions that are better off being handled by the native system libraries (malloc for amem, strdup for nstring). Also, cleaned up files in preparation for removing pointers from the token stream--which is preventing RMAC from working on 64-bit systems. --- .gitignore | 10 + direct.c | 120 ++++---- direct.h | 2 +- expr.c | 44 +-- expr.h | 32 +-- macro.c | 830 +++++++++++++++++++++++++++++------------------------ macro.h | 2 +- mark.c | 3 +- procln.c | 265 +++++++++-------- rmac.c | 18 +- rmac.h | 241 ++++++++-------- sect.c | 109 +++---- sect.h | 88 +++--- symbol.c | 106 +++---- symbol.h | 1 - token.c | 560 +++++++++++++++++++++--------------- token.h | 4 +- version.h | 2 +- 18 files changed, 1319 insertions(+), 1118 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..430317f --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +68kgen +68kgen.o +68ktab.h +*.o +*~ +kwtab.h +mntab.h +risckw.h +rmac +kwgen diff --git a/direct.c b/direct.c index 95fd51b..8d4f3fd 100644 --- a/direct.c +++ b/direct.c @@ -21,72 +21,72 @@ #define DEF_KW #include "kwtab.h" -TOKEN exprbuf[128]; // Expression buffer +TOKEN exprbuf[128]; // Expression buffer // Directive handler table int (*dirtab[])() = { - d_org, // 0 org - d_even, // 1 even - d_unimpl, // 2 .6502 - d_68000, // 3 .68000 - d_bss, // 4 bss - d_data, // 5 data - d_text, // 6 text - d_abs, // 7 abs - d_comm, // 8 comm - d_init, // 9 init - d_cargs, // 10 cargs - d_goto, // 11 goto - d_dc, // 12 dc - d_ds, // 13 ds - d_undmac, // 14 undefmac - d_gpu, // 15 .gpu - d_dsp, // 16 .dsp - d_dcb, // 17 dcb - d_unimpl, // 18* set - d_unimpl, // 19* reg - d_unimpl, // 20 dump - d_incbin, // 21 .incbin //load - d_unimpl, // 22 disable - d_unimpl, // 23 enable - d_globl, // 24 globl - d_regbank0, // 25 .regbank0 - d_regbank1, // 26 .regbank1 - d_unimpl, // 27 xdef - d_assert, // 28 assert - d_unimpl, // 29* if - d_unimpl, // 30* endif - d_unimpl, // 31* endc - d_unimpl, // 32* iif - d_include, // 33 include - fpop, // 34 end - d_unimpl, // 35* macro - exitmac, // 36* exitm - d_unimpl, // 37* endm - d_list, // 38 list - d_nlist, // 39 nlist - d_long, // 40* rept - d_phrase, // 41* endr - d_dphrase, // 42 struct - d_qphrase, // 43 ends - d_title, // 44 title - d_subttl, // 45 subttl - eject, // 46 eject - d_unimpl, // 47 error - d_unimpl, // 48 warn - d_noclear, // 49 .noclear - d_equrundef, // 50 .equrundef/.regundef - d_ccundef, // 51 .ccundef - d_print, // 52 .print - d_gpumain, // 53 .gpumain - d_jpad, // 54 .jpad - d_nojpad, // 55 .nojpad - d_fail, // 56 .fail + d_org, // 0 org + d_even, // 1 even + d_unimpl, // 2 .6502 + d_68000, // 3 .68000 + d_bss, // 4 bss + d_data, // 5 data + d_text, // 6 text + d_abs, // 7 abs + d_comm, // 8 comm + d_init, // 9 init + d_cargs, // 10 cargs + d_goto, // 11 goto + d_dc, // 12 dc + d_ds, // 13 ds + d_undmac, // 14 undefmac + d_gpu, // 15 .gpu + d_dsp, // 16 .dsp + d_dcb, // 17 dcb + d_unimpl, // 18* set + d_unimpl, // 19* reg + d_unimpl, // 20 dump + d_incbin, // 21 .incbin //load + d_unimpl, // 22 disable + d_unimpl, // 23 enable + d_globl, // 24 globl + d_regbank0, // 25 .regbank0 + d_regbank1, // 26 .regbank1 + d_unimpl, // 27 xdef + d_assert, // 28 assert + d_unimpl, // 29* if + d_unimpl, // 30* endif + d_unimpl, // 31* endc + d_unimpl, // 32* iif + d_include, // 33 include + fpop, // 34 end + d_unimpl, // 35* macro + exitmac, // 36* exitm + d_unimpl, // 37* endm + d_list, // 38 list + d_nlist, // 39 nlist + d_long, // 40* rept + d_phrase, // 41* endr + d_dphrase, // 42 struct + d_qphrase, // 43 ends + d_title, // 44 title + d_subttl, // 45 subttl + eject, // 46 eject + d_unimpl, // 47 error + d_unimpl, // 48 warn + d_noclear, // 49 .noclear + d_equrundef, // 50 .equrundef/.regundef + d_ccundef, // 51 .ccundef + d_print, // 52 .print + d_gpumain, // 53 .gpumain + d_jpad, // 54 .jpad + d_nojpad, // 55 .nojpad + d_fail, // 56 .fail }; // -// .org - Set origin +// .fail - User abort // int d_fail(void) { @@ -881,7 +881,7 @@ int d_dc(WORD siz) defined = (WORD)(eattr & DEFINED); if ((challoc - ch_size) < 4) - chcheck(4L); + chcheck(4); switch (siz) { diff --git a/direct.h b/direct.h index 8bcc351..24961c3 100644 --- a/direct.h +++ b/direct.h @@ -13,7 +13,7 @@ // Globals, Externals etc extern TOKEN exprbuf[]; -extern int (*dirtab[])(); +extern int (* dirtab[])(); // Prototypes int d_even(void); diff --git a/expr.c b/expr.c index e7a5062..84018bd 100644 --- a/expr.c +++ b/expr.c @@ -16,38 +16,38 @@ #include "mach.h" #include "risca.h" -#define DEF_KW // Declare keyword values -#include "kwtab.h" // Incl generated keyword tables & defs +#define DEF_KW // Declare keyword values +#include "kwtab.h" // Incl generated keyword tables & defs -static char tokcl[128]; // Generated table of token classes -static VALUE evstk[EVSTACKSIZE]; // Evaluator value stack -static WORD evattr[EVSTACKSIZE]; // Evaluator attribute stack +static char tokcl[128]; // Generated table of token classes +static VALUE evstk[EVSTACKSIZE]; // Evaluator value stack +static WORD evattr[EVSTACKSIZE]; // Evaluator attribute stack // Token-class initialization list char itokcl[] = { - 0, // END - CONST, SYMBOL, 0, // ID - '(', '[', '{', 0, // OPAR - ')', ']', '}', 0, // CPAR - CR_DEFINED, CR_REFERENCED, // SUNARY (special unary) + 0, // END + CONST, SYMBOL, 0, // ID + '(', '[', '{', 0, // OPAR + ')', ']', '}', 0, // CPAR + CR_DEFINED, CR_REFERENCED, // SUNARY (special unary) CR_STREQ, CR_MACDEF, CR_DATE, CR_TIME, 0, - '!', '~', UNMINUS, 0, // UNARY - '*', '/', '%', 0, // MULT - '+', '-', 0, // ADD - SHL, SHR, 0, // SHIFT - LE, GE, '<', '>', NE, '=', 0, // REL - '&', 0, // AND - '^', 0, // XOR - '|', 0, // OR - 1 // (the end) + '!', '~', UNMINUS, 0, // UNARY + '*', '/', '%', 0, // MULT + '+', '-', 0, // ADD + SHL, SHR, 0, // SHIFT + LE, GE, '<', '>', NE, '=', 0, // REL + '&', 0, // AND + '^', 0, // XOR + '|', 0, // OR + 1 // (the end) }; char missym_error[] = "missing symbol"; char * str_error = "missing symbol or string"; // Convert expression to postfix -static TOKEN * tk; // Deposit tokens here +static TOKEN * tk; // Deposit tokens here SYM * lookup(); SYM * newsym(); @@ -78,10 +78,10 @@ void init_expr(void) for(i=0; i<128; ++i) // Mark all entries END tokcl[i] = END; - for(i=0, p=itokcl; *p!=1; ++p) + for(i=0, p=itokcl; *p!=1; p++) { if (*p == 0) - ++i; + i++; else tokcl[(int)(*p)] = (char)i; } diff --git a/expr.h b/expr.h index 89542a5..c8c1e85 100644 --- a/expr.h +++ b/expr.h @@ -12,23 +12,23 @@ #include "rmac.h" // Tunable definitions -#define STKSIZE 64 // Size of expression stacks -#define EVSTACKSIZE 64 // Expression evaluator stack size +#define STKSIZE 64 // Size of expression stacks +#define EVSTACKSIZE 64 // Expression evaluator stack size // Token classes in order of precedence -#define END 0 // End/beginning of input -#define ID 1 // Symbol or constant -#define OPAR 2 // ( -#define CPAR 3 // ) -#define SUNARY 4 // Special unary (^^defined, etc.) -#define UNARY 5 // Unary class: ! ~ - -#define MULT 6 // Multiplicative class: * / % -#define ADD 7 // Additive class: + - -#define SHIFT 8 // Shift class: << >> -#define REL 9 // Relational class: <= >= < > <> = != -#define AND 10 // Bitwise and: & -#define XOR 11 // Bitwise xor: ^ -#define OR 12 // Bitwise or: | +#define END 0 // End/beginning of input +#define ID 1 // Symbol or constant +#define OPAR 2 // ( +#define CPAR 3 // ) +#define SUNARY 4 // Special unary (^^defined, etc.) +#define UNARY 5 // Unary class: ! ~ - +#define MULT 6 // Multiplicative class: * / % +#define ADD 7 // Additive class: + - +#define SHIFT 8 // Shift class: << >> +#define REL 9 // Relational class: <= >= < > <> = != +#define AND 10 // Bitwise and: & +#define XOR 11 // Bitwise xor: ^ +#define OR 12 // Bitwise or: | // Prototypes void init_expr(void); @@ -37,4 +37,4 @@ int expr2(void); int expr(TOKEN *, VALUE *, WORD *, SYM **); int evexpr(TOKEN *, VALUE *, WORD *, SYM **); -#endif // __EXPR_H__ \ No newline at end of file +#endif // __EXPR_H__ diff --git a/macro.c b/macro.c index af105d9..8731fb8 100644 --- a/macro.c +++ b/macro.c @@ -16,122 +16,125 @@ #include "direct.h" #include "debug.h" -LONG curuniq; // Current macro's unique number -TOKEN **argp; // Free spot in argptrs[] -int macnum; // Unique number for macro definition +LONG curuniq; // Current macro's unique number +TOKEN ** argp; // Free spot in argptrs[] +int macnum; // Unique number for macro definition -static LONG macuniq; // Unique-per-macro number -static SYM *curmac; // Macro currently being defined -static char **curmln; // Previous macro line (or NULL) -static VALUE argno; // Formal argument count +static LONG macuniq; // Unique-per-macro number +static SYM * curmac; // Macro currently being defined +static char ** curmln; // Previous macro line (or NULL) +static VALUE argno; // Formal argument count + +static LONG * firstrpt; // First .rept line +static LONG * nextrpt; // Last .rept line +static int rptlevel; // .rept nesting level -static LONG *firstrpt; // First .rept line -static LONG *nextrpt; // Last .rept line -static int rptlevel; // .rept nesting level // -// --- Initialize Macro Processor ------------------------------------------------------------------ +// Initialize Macro Processor // - -void init_macro(void) { - macuniq = 0; - macnum = 1; - argp = NULL; - ib_macro(); +void init_macro(void) +{ + macuniq = 0; + macnum = 1; + argp = NULL; + ib_macro(); } + // -// ------------------------------------------------------------------------------------------------- // Exit from a Macro; // o pop any intervening include files and repeat blocks; // o restore argument stack; // o pop the macro. -// ------------------------------------------------------------------------------------------------- // +int exitmac(void) +{ + IMACRO * imacro; + TOKEN ** p; -int exitmac(void) { - IMACRO *imacro; - TOKEN **p; + // Pop intervening include files and .rept blocks + while (cur_inobj != NULL && cur_inobj->in_type != SRC_IMACRO) + fpop(); - // Pop intervening include files and .rept blocks - while(cur_inobj != NULL && cur_inobj->in_type != SRC_IMACRO) - fpop(); + if (cur_inobj == NULL) + fatal("too many ENDMs"); - if(cur_inobj == NULL) - fatal("too many ENDMs"); + // Restore + // o old arg context + // o old unique number + // ...and then pop the macro. - // Restore - // o old arg context - // o old unique number - // ...and then pop the macro. + imacro = cur_inobj->inobj.imacro; + curuniq = imacro->im_olduniq; - imacro = cur_inobj->inobj.imacro; - curuniq = imacro->im_olduniq; + p = --argp; + argp = (TOKEN **)*argp; - p = --argp; - argp = (TOKEN **)*argp; + fpop(); - fpop(); - - mjump_align = 0; + mjump_align = 0; - return(0); + return 0; } + // -// --- Add a Formal Argument to a Macro Definition ------------------------------------------------- +// Add a Formal Argument to a Macro Definition // +int defmac2(char * argname) +{ + SYM * arg; -int defmac2(char *argname) { - SYM *arg; - - if(lookup(argname, MACARG, (int)curmac->sattr) != NULL) - return(error("multiple formal argument definition")); - arg = newsym(argname, MACARG, (int)curmac->sattr); - arg->svalue = argno++; + if (lookup(argname, MACARG, (int)curmac->sattr) != NULL) + return(error("multiple formal argument definition")); + arg = newsym(argname, MACARG, (int)curmac->sattr); + arg->svalue = argno++; - return(OK); + return OK; } // -// ------------------------------------------------------------------------------------------------- -// Add a line to a macro definition; also print lines to listing file (if enabled). -// The last line of the macro (containing .endm) is not included in the macro. A label on that line -// will be lost. `endflg' is misleading here. It is -1 for all lines but the last one (.endm), -// when it is 0. -// ------------------------------------------------------------------------------------------------- +// Add a line to a macro definition; also print lines to listing file (if +// enabled). The last line of the macro (containing .endm) is not included in +// the macro. A label on that line will be lost. `endflg' is misleading here. +// It is -1 for all lines but the last one (.endm), when it is 0. // - -int defmac1(char *ln, int endflg) { - PTR p; - LONG len; - - if(list_flag) { - listeol(); // Flush previous source line - lstout('.'); // Mark macro definition with period - } - - if(endflg) { - len = strlen(ln) + 1 + sizeof(LONG); - p.cp = amem(len); - *p.lp = 0; - strcpy(p.cp + sizeof(LONG), ln); - - // Link line of text onto end of list - if(curmln == NULL) - curmac->svalue = (VALUE)p.cp; - else - *curmln = p.cp; - curmln = (char **)p.cp; - return(1); // Keep looking - } - else - return(0); // Stop looking at the end +int defmac1(char * ln, int endflg) +{ + PTR p; + LONG len; + + if (list_flag) + { + listeol(); // Flush previous source line + lstout('.'); // Mark macro definition with period + } + + if (endflg) + { + len = strlen(ln) + 1 + sizeof(LONG); +// p.cp = amem(len); + p.cp = malloc(len); + *p.lp = 0; + strcpy(p.cp + sizeof(LONG), ln); + + // Link line of text onto end of list + if (curmln == NULL) + curmac->svalue = (VALUE)p.cp; + else + *curmln = p.cp; + + curmln = (char **)p.cp; + return 1; // Keep looking + } + else + return 0; // Stop looking at the end } + // -// ------------------------------------------------------------------------------------------------- // Define macro // // macro foo arg1,arg2,... @@ -143,349 +146,414 @@ int defmac1(char *ln, int endflg) { // ----------------- // `defmac1' adds lines of text to the macro definition // `defmac2' processes the formal arguments (and sticks them into the symbol table) -// ------------------------------------------------------------------------------------------------- // +int defmac(void) +{ + char * p; + SYM * mac; + + // Setup entry in symbol table, make sure the macro isn't a duplicate entry, and that + // it doesn't override any processor mnemonic or assembler directive. + if (*tok++ != SYMBOL) + return error("missing symbol"); + + p = (char *)*tok++; + + if (lookup(p, MACRO, 0) != NULL) + return error("multiple macro definition"); + + curmac = mac = newsym(p, MACRO, 0); + mac->svalue = 0; + mac->sattr = (WORD)(macnum++); + + // Parse and define formal arguments in symbol table + if (*tok != EOL) + { + argno = 0; + symlist(defmac2); + at_eol(); + } -int defmac(void) { - char *p; - SYM *mac; - - // Setup entry in symbol table, make sure the macro isn't a duplicate entry, and that - // it doesn't override any processor mnemonic or assembler directive. - if(*tok++ != SYMBOL) return(error("missing symbol")); - p = (char *)*tok++; - if(lookup(p, MACRO, 0) != NULL) - return(error("multiple macro definition")); - - curmac = mac = newsym(p, MACRO, 0); - mac->svalue = 0; - mac->sattr = (WORD)(macnum++); - - // Parse and define formal arguments in symbol table - if(*tok != EOL) { - argno = 0; - symlist(defmac2); - at_eol(); - } - - // Suck in the macro definition; we're looking for an ENDM symbol on a line - // by itself to terminate the definition. - curmln = NULL; - lncatch(defmac1, "endm "); - - return(0); + // Suck in the macro definition; we're looking for an ENDM symbol on a line + // by itself to terminate the definition. + curmln = NULL; + lncatch(defmac1, "endm "); + + return 0; } + // -// --- Add lines to a .rept definition ------------------------------------------------------------- +// Add lines to a .rept definition // - -int defr1(char *ln, int kwno) { - LONG len; - LONG *p; - - if(list_flag) { - listeol(); // Flush previous source line - lstout('#'); // Mark this a 'rept' block - } - - switch(kwno) { - case 0: // .endr - if(--rptlevel == 0) - return(0); - goto addln; - case 1: // .rept - ++rptlevel; - default: - - addln: - - // Allocate length of line + 1('\0') + LONG - len = strlen(ln) + 1 + sizeof(LONG); - p = (LONG *)amem(len); - *p = 0; - - strcpy((char*)(p + 1), ln); - - if(nextrpt == NULL) { - firstrpt = p; // First line of rept statement - } else { - *nextrpt = (LONG)p; - } - nextrpt = p; - - return(rptlevel); - } +int defr1(char * ln, int kwno) +{ + LONG len; + LONG * p; + + if (list_flag) + { + listeol(); // Flush previous source line + lstout('#'); // Mark this a 'rept' block + } + + switch (kwno) + { + case 0: // .endr + if (--rptlevel == 0) + return(0); + goto addln; + case 1: // .rept + ++rptlevel; + default: + addln: + // Allocate length of line + 1('\0') + LONG + len = strlen(ln) + 1 + sizeof(LONG); +// p = (LONG *)amem(len); + p = (LONG *)malloc(len); + *p = 0; + + strcpy((char *)(p + 1), ln); + + if (nextrpt == NULL) + { + firstrpt = p; // First line of rept statement + } + else + { + *nextrpt = (LONG)p; + } + + nextrpt = p; + + return rptlevel; + } } + // -// --- Define a .rept block, this gets hairy because they can be nested ---------------------------- +// Define a .rept block, this gets hairy because they can be nested // - -int defrept(void) { - INOBJ *inobj; - IREPT *irept; - VALUE eval; - - // Evaluate repeat expression - if(abs_expr(&eval) != OK) - return(ERROR); - - // Suck in lines for .rept block - firstrpt = NULL; - nextrpt = NULL; - rptlevel = 1; - lncatch(defr1, "endr rept "); - - // Alloc and init input object - if(firstrpt) { - inobj = a_inobj(SRC_IREPT); // Create a new REPT input object - irept = inobj->inobj.irept; - irept->ir_firstln = firstrpt; - irept->ir_nextln = NULL; - irept->ir_count = eval; - } - - return(0); +int defrept(void) +{ + INOBJ * inobj; + IREPT * irept; + VALUE eval; + + // Evaluate repeat expression + if (abs_expr(&eval) != OK) + return ERROR; + + // Suck in lines for .rept block + firstrpt = NULL; + nextrpt = NULL; + rptlevel = 1; + lncatch(defr1, "endr rept "); + + // Alloc and init input object + if (firstrpt) + { + inobj = a_inobj(SRC_IREPT); // Create a new REPT input object + irept = inobj->inobj.irept; + irept->ir_firstln = firstrpt; + irept->ir_nextln = NULL; + irept->ir_count = eval; + } + + return 0; } + // -// ------------------------------------------------------------------------------------------------- -// Hand off lines of text to the function `lnfunc' until a line containing one of the directives in -// `dirlist' is encountered. Return the number of the keyword encountered (0..n) +// Hand off lines of text to the function `lnfunc' until a line containing one +// of the directives in `dirlist' is encountered. Return the number of the +// keyword encountered (0..n) // -// `dirlist' contains null-seperated terminated keywords. A final null terminates the list. -// Directives are compared to the keywords without regard to case. +// `dirlist' contains null-seperated terminated keywords. A final null +// terminates the list. Directives are compared to the keywords without regard +// to case. // // If `lnfunc' is NULL, then lines are simply skipped. // If `lnfunc' returns an error, processing is stopped. // -// `lnfunc' is called with an argument of -1 for every line but the last one, when it is called -// with an argument of the keyword number that caused the match. -// ------------------------------------------------------------------------------------------------- +// `lnfunc' is called with an argument of -1 for every line but the last one, +// when it is called with an argument of the keyword number that caused the +// match. // - -int lncatch(int (*lnfunc)(), char *dirlist) { - char *p; - int k; - - if(lnfunc != NULL) - ++lnsave; // Tell tokenizer to keep lines - - for(;;) { - if(tokln() == TKEOF) { - errors("encountered end-of-file looking for '%s'", dirlist); - fatal("cannot continue"); - } - - // Test for end condition. Two cases to handle: - // - // symbol: - p = NULL; - k = -1; - - if(*tok == SYMBOL) { - if((tok[2] == ':' || tok[2] == DCOLON)) { - if(tok[3] == SYMBOL) // label: symbol - p = (char *)tok[4]; - } else { - p = (char *)tok[1]; // symbol - } - } - - if(p != NULL) { - if(*p == '.') // ignore leading '.'s - ++p; - k = kwmatch(p, dirlist); - } - - // Hand-off line to function - // if it returns 0, and we found a keyword, stop looking. - // if it returns 1, hand off the line and keep looking. - if(lnfunc != NULL) - k = (*lnfunc)(lnbuf, k); - - if(!k) - break; - } - - if(lnfunc != NULL) - --lnsave; // Tell tokenizer to stop keeping lines - - return(0); +int lncatch(int (* lnfunc)(), char * dirlist) +{ + char * p; + int k; + + if (lnfunc != NULL) + ++lnsave; // Tell tokenizer to keep lines + + for(;;) + { + if (tokln() == TKEOF) + { + errors("encountered end-of-file looking for '%s'", dirlist); + fatal("cannot continue"); + } + + // Test for end condition. Two cases to handle: + // + // symbol: + p = NULL; + k = -1; + + if (*tok == SYMBOL) + { + if ((tok[2] == ':' || tok[2] == DCOLON)) + { + if (tok[3] == SYMBOL) // label: symbol + p = (char *)tok[4]; + } + else + { + p = (char *)tok[1]; // symbol + } + } + + if (p != NULL) + { + if (*p == '.') // ignore leading '.'s + ++p; + + k = kwmatch(p, dirlist); + } + + // Hand-off line to function + // if it returns 0, and we found a keyword, stop looking. + // if it returns 1, hand off the line and keep looking. + if (lnfunc != NULL) + k = (*lnfunc)(lnbuf, k); + + if (!k) + break; + } + + if (lnfunc != NULL) + --lnsave; // Tell tokenizer to stop keeping lines + + return 0; } + // -// ------------------------------------------------------------------------------------------------- -// See if the string `kw' matches one of the keywords in `kwlist'. If so, return the number of -// the keyword matched. Return -1 if there was no match. +// See if the string `kw' matches one of the keywords in `kwlist'. If so, +// return the number of the keyword matched. Return -1 if there was no match. // Strings are compared without regard for case. -// ------------------------------------------------------------------------------------------------- // +int kwmatch(char * kw, char * kwlist) +{ + char * p; + char c1; + char c2; + int k; -int kwmatch(char *kw, char *kwlist) { - char *p; - char c1; - char c2; - int k; + for(k=0; *kwlist; ++k) + { + for(p=kw;;) + { + c1 = *kwlist++; + c2 = *p++; - for(k = 0; *kwlist; ++k) { - for(p = kw;;) { - c1 = *kwlist++; - c2 = *p++; + if (c2 >= 'A' && c2 <= 'Z') + c2 += 32; - if(c2 >= 'A' && c2 <= 'Z') - c2 += 32; + if (c1 == ' ' && c2 == EOS) + return k; - if(c1 == ' ' && c2 == EOS) - return(k); + if (c1 != c2) + break; + } - if(c1 != c2) - break; - } + // Skip to beginning of next keyword in `kwlist' + while (*kwlist && *kwlist != ' ') + ++kwlist; - // Skip to beginning of next keyword in `kwlist' - while(*kwlist && *kwlist != ' ') - ++kwlist; - if(*kwlist== ' ') - ++kwlist; - } + if (*kwlist== ' ') + ++kwlist; + } - return(-1); + return -1; } + // -// ------------------------------------------------------------------------------------------------- // Invoke a macro // o parse, count and copy arguments // o push macro's string-stream -// ------------------------------------------------------------------------------------------------- // - -int invokemac(SYM *mac, WORD siz) { - TOKEN *p = NULL; - IMACRO *imacro; - INOBJ *inobj; - int dry_run; - WORD nargs; - WORD arg_siz = 0; - TOKEN **argptr = NULL; - TOKEN *beg_tok; - - if((!strcmp(mac->sname, "mjump") || !strcmp(mac->sname, "mpad")) && !in_main) { - error("macro cannot be used outside of .gpumain"); - return(ERROR); - } - - inobj = a_inobj(SRC_IMACRO); // Alloc and init IMACRO - imacro = inobj->inobj.imacro; - imacro->im_siz = siz; - nargs = 0; - beg_tok = tok; - - for(dry_run = 1;; --dry_run) { - for(tok = beg_tok; *tok != EOL;) { - if(dry_run) ++nargs; - else *argptr++ = p; - - while(*tok != ',' && *tok != EOL) { - if(*tok == '\\' && tok[1] != EOL) ++tok; - switch((int)*tok) { - case CONST: - case SYMBOL: - case ACONST: - if(dry_run) arg_siz += sizeof(TOKEN), ++tok; - else *p++ = *tok++; - // FALLTHROUGH - default: - if(dry_run) arg_siz += sizeof(TOKEN), ++tok; - else *p++ = *tok++; - break; - } - } - - if(dry_run) arg_siz += sizeof(TOKEN); - else *p++ = EOL; - - if(*tok == ',') ++tok; - } - - // Allocate space for argument ptrs and so on and then go back and construct the arg frame - if(dry_run) { - if(nargs != 0) p = (TOKEN *)malloc((LONG)(arg_siz + 1)); - argptr = (TOKEN **)malloc((LONG)((nargs + 1) * sizeof(LONG))); - *argptr++ = (TOKEN *)argp; - argp = argptr; - } else - break; - } - - - // Setup imacro: - // o #arguments; - // o -> macro symbol; - // o -> macro definition string list; - // o save 'curuniq', to be restored when the macro pops; - // o bump `macuniq' counter and set 'curuniq' to it; - imacro->im_nargs = nargs; - imacro->im_macro = mac; - imacro->im_nextln = (LONG *)mac->svalue; - imacro->im_olduniq = curuniq; - curuniq = ++macuniq; - - DEBUG { - printf("nargs=%d\n", nargs); - for(nargs = 0; nargs < imacro->im_nargs; ++nargs) { - printf("arg%d=", nargs); - dumptok(argp[imacro->im_nargs - nargs - 1]); - } - } - - return(OK); +int invokemac(SYM * mac, WORD siz) +{ + TOKEN * p = NULL; + IMACRO * imacro; + INOBJ * inobj; + int dry_run; + WORD nargs; + WORD arg_siz = 0; + TOKEN ** argptr = NULL; + TOKEN * beg_tok; + + if ((!strcmp(mac->sname, "mjump") || !strcmp(mac->sname, "mpad")) && !in_main) + { + error("macro cannot be used outside of .gpumain"); + return ERROR; + } + + inobj = a_inobj(SRC_IMACRO); // Alloc and init IMACRO + imacro = inobj->inobj.imacro; + imacro->im_siz = siz; + nargs = 0; + beg_tok = tok; // 'tok' comes from token.c + + for(dry_run=1;; --dry_run) + { + for(tok=beg_tok; *tok!=EOL;) + { + if (dry_run) + nargs++; + else + *argptr++ = p; + + // Keep going while tok isn't pointing at a comma or EOL + while (*tok != ',' && *tok != EOL) + { + // Skip over backslash character, unless it's followed by an EOL + if (*tok == '\\' && tok[1] != EOL) + tok++; + + switch (*tok) + { + case CONST: + case SYMBOL: + case ACONST: + if (dry_run) + { + arg_siz += sizeof(TOKEN); + tok++; + } + else + *p++ = *tok++; + // FALLTHROUGH (picks up the arg after a CONST, SYMBOL or ACONST) + default: + if (dry_run) + { + arg_siz += sizeof(TOKEN); + tok++; + } + else + *p++ = *tok++; + + break; + } + } + + // We hit the comma or EOL, so count/stuff it + if (dry_run) + arg_siz += sizeof(TOKEN); + else + *p++ = EOL; + + // If we hit the comma instead of an EOL, skip over it + if (*tok == ',') + tok++; + } + + // Allocate space for argument ptrs and so on and then go back and + // construct the arg frame + if (dry_run) + { + if (nargs != 0) +//Barfing here with memory corruption in glibc. TOKEN is defined as LONG, which is uint32_t +// p = (TOKEN *)malloc(arg_siz + 1); + p = (TOKEN *)malloc(arg_siz + sizeof(TOKEN)); + + argptr = (TOKEN **)malloc((nargs + 1) * sizeof(LONG)); + *argptr++ = (TOKEN *)argp; + argp = argptr; + } + else + break; + } + + // Setup imacro: + // o #arguments; + // o -> macro symbol; + // o -> macro definition string list; + // o save 'curuniq', to be restored when the macro pops; + // o bump `macuniq' counter and set 'curuniq' to it; + imacro->im_nargs = nargs; + imacro->im_macro = mac; + imacro->im_nextln = (TOKEN *)mac->svalue; + imacro->im_olduniq = curuniq; + curuniq = macuniq++; +/*IMACRO { + IMACRO * im_link; // Pointer to ancient IMACROs + LONG * im_nextln; // Next line to include + WORD im_nargs; // # of arguments supplied on invocation + WORD im_siz; // Size suffix supplied on invocation + LONG im_olduniq; // Old value of 'macuniq' + SYM * im_macro; // Pointer to macro we're in + char im_lnbuf[LNSIZ]; // Line buffer +};*/ + + DEBUG + { + printf("nargs=%d\n", nargs); + + for(nargs=0; nargsim_nargs; ++nargs) + { + printf("arg%d=", nargs); + dumptok(argp[imacro->im_nargs - nargs - 1]); + } + } + + return OK; } + // -// ------------------------------------------------------------------------------------------------- // Setup inbuilt macros -// ------------------------------------------------------------------------------------------------- // - void ib_macro(void) { - SYM * mac; - - curmac = mac = newsym("mjump", MACRO, 0); - mac->svalue = 0; - mac->sattr = (WORD)(macnum++); - argno = 0; - defmac2("cc"); - defmac2("addr"); - defmac2("jreg"); - curmln = NULL; - defmac1(" nop", -1); - defmac1(" movei #\\addr,\\jreg", -1); - defmac1(" jump \\cc,(\\jreg)", -1); - defmac1(" nop", -1); - defmac1(" nop", -1); - - curmac = mac = newsym("mjr", MACRO, 0); - mac->svalue = 0; - mac->sattr = (WORD)(macnum++); - argno = 0; - defmac2("cc"); - defmac2("addr"); - curmln = NULL; - defmac1(" jr \\cc,\\addr", -1); - defmac1(" nop", -1); - defmac1(" nop", -1); - - curmac = mac = newsym("mpad", MACRO, 0); - mac->svalue = 0; - mac->sattr = (WORD)(macnum++); - argno = 0; - defmac2("size"); - curmln = NULL; - defmac1(" .rept (\\size/2)", -1); - defmac1(" nop", -1); - defmac1(" .endr", -1); + SYM * mac; + + curmac = mac = newsym("mjump", MACRO, 0); + mac->svalue = 0; + mac->sattr = (WORD)(macnum++); + argno = 0; + defmac2("cc"); + defmac2("addr"); + defmac2("jreg"); + curmln = NULL; + defmac1(" nop", -1); + defmac1(" movei #\\addr,\\jreg", -1); + defmac1(" jump \\cc,(\\jreg)", -1); + defmac1(" nop", -1); + defmac1(" nop", -1); + + curmac = mac = newsym("mjr", MACRO, 0); + mac->svalue = 0; + mac->sattr = (WORD)(macnum++); + argno = 0; + defmac2("cc"); + defmac2("addr"); + curmln = NULL; + defmac1(" jr \\cc,\\addr", -1); + defmac1(" nop", -1); + defmac1(" nop", -1); + + curmac = mac = newsym("mpad", MACRO, 0); + mac->svalue = 0; + mac->sattr = (WORD)(macnum++); + argno = 0; + defmac2("size"); + curmln = NULL; + defmac1(" .rept (\\size/2)", -1); + defmac1(" nop", -1); + defmac1(" .endr", -1); } diff --git a/macro.h b/macro.h index 8eeff44..ea25b8b 100644 --- a/macro.h +++ b/macro.h @@ -13,7 +13,7 @@ // Globals, externals etc extern LONG curuniq; -extern TOKEN **argp; +extern TOKEN ** argp; extern int mjump_align; // Prototypes diff --git a/mark.c b/mark.c index 1cf6e45..d3b827a 100644 --- a/mark.c +++ b/mark.c @@ -92,7 +92,8 @@ int amark(void) MCHUNK * p; // Alloc mark block header (and data) and set it up. - p = (MCHUNK *)amem((long)(sizeof(MCHUNK)) + MARK_ALLOC_INCR); +// p = (MCHUNK *)amem((long)(sizeof(MCHUNK)) + MARK_ALLOC_INCR); + p = (MCHUNK *)malloc(sizeof(MCHUNK) + MARK_ALLOC_INCR); p->mcnext = NULL; p->mcalloc = MARK_ALLOC_INCR; p->mcptr.cp = (char *)(((char *)p) + sizeof(MCHUNK)); diff --git a/procln.c b/procln.c index d44517c..edd2173 100644 --- a/procln.c +++ b/procln.c @@ -18,26 +18,25 @@ #include "symbol.h" #include "risca.h" -#define DEF_KW // Declare keyword values -#include "kwtab.h" // Incl generated keyword tables & defs +#define DEF_KW // Declare keyword values +#include "kwtab.h" // Incl generated keyword tables & defs -#define DEF_MN // Incl 68k keyword definitions -#define DECL_MN // Incl 68k keyword state machine tables +#define DEF_MN // Incl 68k keyword definitions +#define DECL_MN // Incl 68k keyword state machine tables #include "mntab.h" #define DEF_MR #define DECL_MR #include "risckw.h" -IFENT * ifent; // Current ifent -static IFENT ifent0; // Root ifent -static IFENT * f_ifent; // Freelist of ifents -static int disabled; // Assembly conditionally disabled -int just_bss; // 1, ds.b in microprocessor mode -VALUE pcloc; // Value of "PC" at beginning of line -IFENT * ifent; // Current ifent -SYM * lab_sym; // Label on line (or NULL) - +IFENT * ifent; // Current ifent +static IFENT ifent0; // Root ifent +static IFENT * f_ifent; // Freelist of ifents +static int disabled; // Assembly conditionally disabled +int just_bss; // 1, ds.b in microprocessor mode +VALUE pcloc; // Value of "PC" at beginning of line +IFENT * ifent; // Current ifent +SYM * lab_sym; // Label on line (or NULL) char extra_stuff[] = "extra (unexpected) text found after addressing mode"; char * comma_error = "missing comma"; @@ -68,25 +67,25 @@ LONG amsktab[0112] = { M_AINDEXED, M_AINDEXED, M_AINDEXED, M_AINDEXED, M_AINDEXED, M_AINDEXED, M_AINDEXED, M_AINDEXED, - M_ABSW, // 070 - M_ABSL, // 071 - M_PCDISP, // 072 - M_PCINDEXED, // 073 - M_IMMED, // 074 - 0L, // 075 - 0L, // 076 - 0L, // 077 - M_ABASE, // 0100 - M_MEMPOST, // 0101 - M_MEMPRE, // 0102 - M_PCBASE, // 0103 - M_PCMPOST, // 0104 - M_PCMPRE, // 0105 - M_AM_USP, // 0106 - M_AM_SR, // 0107 - M_AM_CCR, // 0110 - M_AM_NONE // 0111 -}; // 0112 length + M_ABSW, // 070 + M_ABSL, // 071 + M_PCDISP, // 072 + M_PCINDEXED, // 073 + M_IMMED, // 074 + 0L, // 075 + 0L, // 076 + 0L, // 077 + M_ABASE, // 0100 + M_MEMPOST, // 0101 + M_MEMPRE, // 0102 + M_PCBASE, // 0103 + M_PCMPOST, // 0104 + M_PCMPRE, // 0105 + M_AM_USP, // 0106 + M_AM_SR, // 0107 + M_AM_CCR, // 0110 + M_AM_NONE // 0111 +}; // 0112 length // @@ -106,74 +105,78 @@ void init_procln(void) // void assemble(void) { - int state; // Keyword machine state (output) - int j; // Random int, must be fast - char * p; // Random char ptr, must be fast - TOKEN * tk; // First token in line - char * label; // Symbol (or NULL) - char * equate; // Symbol (or NULL) - int labtyp = 0; // Label type (':', DCOLON) - int equtyp = 0; // Equ type ('=', DEQUALS) - VALUE eval; // Expression value - WORD eattr; // Expression attributes - SYM * esym; // External symbol involved in expr. - WORD siz = 0; // Size suffix to mnem/diretve/macro - LONG amsk0, amsk1; // Address-type masks for ea0, ea1 - MNTAB * m; // Code generation table pointer - SYM * sy, * sy2; // Symbol (temp usage) - char * opname = NULL; // Name of dirctve/mnemonic/macro - int listflag; // 0: Don't call listeol() - int as68mode = 0; // 1: Handle multiple labels - WORD rmask; // Register list, for REG - int registerbank; // RISC register bank - int riscreg; // RISC register - - listflag = 0; // Initialise listing flag - -loop: // Line processing loop label - + int state; // Keyword machine state (output) + int j; // Random int, must be fast + char * p; // Random char ptr, must be fast + TOKEN * tk; // First token in line + char * label; // Symbol (or NULL) + char * equate; // Symbol (or NULL) + int labtyp = 0; // Label type (':', DCOLON) + int equtyp = 0; // Equ type ('=', DEQUALS) + VALUE eval; // Expression value + WORD eattr; // Expression attributes + SYM * esym; // External symbol involved in expr. + WORD siz = 0; // Size suffix to mnem/diretve/macro + LONG amsk0, amsk1; // Address-type masks for ea0, ea1 + MNTAB * m; // Code generation table pointer + SYM * sy, * sy2; // Symbol (temp usage) + char * opname = NULL; // Name of dirctve/mnemonic/macro + int listflag; // 0: Don't call listeol() + int as68mode = 0; // 1: Handle multiple labels + WORD rmask; // Register list, for REG + int registerbank; // RISC register bank + int riscreg; // RISC register + + listflag = 0; // Initialise listing flag + +loop: // Line processing loop label + + // Get another line of tokens if (tokln() == TKEOF) - { // Get another line of tokens - if (list_flag && listflag) // Flush last line of source + { + if (list_flag && listflag) // Flush last line of source listeol(); - if (ifent->if_prev != NULL) // Check conditional token + if (ifent->if_prev != NULL) // Check conditional token error("hit EOF without finding matching .endif"); return; } + DEBUG DumpTokenBuffer(); + if (list_flag) { if (listflag && listing > 0) - listeol(); // Tell listing generator about EOL + listeol(); // Tell listing generator about EOL - lstout((char)(disabled ? '-' : lntag)); // Prepare new line for listing - listflag = 1; // OK to call `listeol' now - just_bss = 0; // Reset just_bss mode + lstout((char)(disabled ? '-' : lntag)); // Prepare new line for listing + listflag = 1; // OK to call `listeol' now + just_bss = 0; // Reset just_bss mode } - state = -3; // No keyword (just EOL) - label = NULL; // No label - lab_sym = NULL; // No (exported) label - equate = NULL; // No equate - tk = tok; // Save first token in line - pcloc = (VALUE)sloc; // Set beginning-of-line PC + state = -3; // No keyword (just EOL) + label = NULL; // No label + lab_sym = NULL; // No (exported) label + equate = NULL; // No equate + tk = tok; // Save first token in line + pcloc = (VALUE)sloc; // Set beginning-of-line PC - loop1: // Internal line processing loop +loop1: // Internal line processing loop - if (*tok == EOL) // Restart loop if end-of-line + if (*tok == EOL) // Restart loop if end-of-line goto loop; + // First token MUST be a symbol if (*tok != SYMBOL) - { // First token MUST be a symbol + { error(syntax_error); goto loop; } - j = (int)tok[2]; // Skip equates (normal statements) + j = (int)tok[2]; // Skip equates (normal statements) - if (j == '=' || j == DEQUALS || j == SET || j == REG || j == EQUREG || j == CCDEF) + if (j == '=' || j == DEQUALS || j == SET || j == REG || j == EQUREG || j == CCDEF) { equate = (char *)tok[1]; equtyp = j; @@ -181,12 +184,13 @@ loop: // Line processing goto normal; } + // Skip past label (but record it) if (j == ':' || j == DCOLON) - { // Skip past label (but record it) + { as68label: - label = (char *)tok[1]; // Get label name - labtyp = tok[2]; // Get label type - tok += 3; // Go to next line token + label = (char *)tok[1]; // Get label name + labtyp = tok[2]; // Get label type + tok += 3; // Go to next line token // Handle multiple labels; if there's another label, go process it, // and come back at `as68label' above. @@ -202,16 +206,20 @@ as68label: } } - if (*tok == EOL) // EOL is legal here... + if (*tok == EOL) // EOL is legal here... goto normal; + // Next token MUST be a symbol if (*tok++ != SYMBOL) - { // Next token MUST be a symbol + { error(syntax_error); goto loop; } - opname = p = (char *)*tok++; // Store opcode name here +// This is the problem here: On 64-bit platforms, this cuts the native pointer +// in half. We need to figure out how to fix this. +#warning "!!! Bad pointer !!!" + opname = p = (char *)*tok++; // Store opcode name here // Check to see if the SYMBOL is a keyword (a mnemonic or directive). // On output, `state' will have one of the values: @@ -224,15 +232,17 @@ as68label: { j = mnbase[state] + (int)tolowertab[*p]; + // Reject, character doesn't match if (mncheck[j] != state) - { // Reject, character doesn't match - state = -1; // No match + { + state = -1; // No match break; } + // Must accept or reject at EOS if (!*++p) - { // Must accept or reject at EOS - state = mnaccept[j]; // (-1 on no terminal match) + { + state = mnaccept[j]; // (-1 on no terminal match) break; } @@ -263,7 +273,7 @@ as68label: case MN_ENDIF: d_endif (); goto loop; - case MN_IIF: // .iif --- immediate if + case MN_IIF: // .iif --- immediate if if (disabled || expr(exprbuf, &eval, &eattr, &esym) != OK) goto loop; @@ -283,7 +293,7 @@ as68label: goto loop; goto loop1; - case MN_MACRO: // .macro --- macro definition + case MN_MACRO: // .macro --- macro definition if (!disabled) { if (label != NULL) @@ -293,8 +303,8 @@ as68label: } goto loop; - case MN_EXITM: // .exitm --- exit macro - case MN_ENDM: // .endm --- same as .exitm + case MN_EXITM: // .exitm --- exit macro + case MN_ENDM: // .endm --- same as .exitm if (!disabled) { if (label != NULL) @@ -323,13 +333,13 @@ as68label: } normal: - if (disabled) // Conditionally disabled code + if (disabled) // Conditionally disabled code goto loop; // Do equates if (equate != NULL) { - j = 0; // Pick global or local sym enviroment + j = 0; // Pick global or local sym enviroment if (*equate == '.') j = curenv; @@ -343,8 +353,9 @@ normal: if (equtyp == DEQUALS) { + // Can't GLOBAL a local symbol if (j) - { // Can't GLOBAL a local symbol + { error(locgl_error); goto loop; } @@ -381,17 +392,19 @@ normal: // o everything else if (equtyp == EQUREG) { + // Check that we are in a RISC section if (!rgpu && !rdsp) - { // Check that we are in a RISC section + { error(".equr/.regequ must be defined in .gpu/.dsp section"); goto loop; } + // Check for register to equate to if ((*tok >= KW_R0) && (*tok <= KW_R31)) - { // Check for register to equate to - sy->sattre = EQUATEDREG | RISCSYM; // Mark as equated register + { + sy->sattre = EQUATEDREG | RISCSYM; // Mark as equated register riscreg = (*tok - KW_R0); - sy->sattre |= (riscreg << 8); // Store register number + sy->sattre |= (riscreg << 8); // Store register number if ((tok[1] == ',') && (tok[2] == CONST)) { @@ -409,23 +422,25 @@ normal: registerbank = BANK_N; } - sy->sattre |= regbank; // Store register bank + sy->sattre |= regbank; // Store register bank eattr = ABS | DEFINED | GLOBAL; eval = 0x80000080 + (riscreg) + (registerbank << 8); tok++; } + // Checking for a register symbol else if (tok[0] == SYMBOL) - { // Checking for a register symbol + { sy2 = lookup((char *)tok[1], LABEL, j); + // Make sure symbol is a valid equreg if (!sy2 || !(sy2->sattre & EQUATEDREG)) - { // Make sure symbol is a valid equreg + { error("invalid GPU/DSP .equr/.regequ definition"); goto loop; } else { - eattr = ABS | DEFINED | GLOBAL; // Copy symbols attributes + eattr = ABS | DEFINED | GLOBAL; // Copy symbols attributes sy->sattre = sy2->sattre; eval = (sy2->svalue & 0xFFFFF0FF); tok += 2; @@ -470,8 +485,9 @@ normal: else if (expr(exprbuf, &eval, &eattr, &esym) != OK) goto loop; } + //equ a equr else if (*tok == SYMBOL) - { //equ a equr + { sy2 = lookup((char *)tok[1], LABEL, j); if (sy2 && (sy2->sattre & EQUATEDREG)) @@ -494,13 +510,13 @@ normal: goto loop; } - - sy->sattr |= eattr | EQUATED; // Symbol inherits value and attributes + sy->sattr |= eattr | EQUATED; // Symbol inherits value and attributes sy->svalue = eval; - if (list_flag) // Put value in listing + + if (list_flag) // Put value in listing listvalue(eval); - at_eol(); // Must be at EOL now + at_eol(); // Must be at EOL now goto loop; } @@ -547,8 +563,9 @@ do_label: if (!j) ++curenv; + // Make label global if (labtyp == DCOLON) - { // Make label global + { if (j) { error(locgl_error); @@ -567,22 +584,25 @@ do_label: if (state == -3) goto loop; - // If we are in GPU or DSP mode and still in need of a mnemonic then search for one + // If we are in GPU or DSP mode and still in need of a mnemonic then search + // for one if ((rgpu || rdsp) && (state < 0 || state >= 1000)) { for(state=0, p=opname; state>=0;) { j = mrbase[state] + (int)tolowertab[*p]; + // Reject, character doesn't match if (mrcheck[j] != state) - { // Reject, character doesn't match - state = -1; // No match + { + state = -1; // No match break; } + // Must accept or reject at EOS if (!*++p) - { // Must accept or reject at EOS - state = mraccept[j]; // (-1 on no terminal match) + { + state = mraccept[j]; // (-1 on no terminal match) break; } @@ -626,21 +646,22 @@ do_label: goto loop; } - if (sloc & 1) // Automatic .even + if (sloc & 1) // Automatic .even auto_even(); - if (challoc - ch_size < 18) // Make sure have space in current chunk - chcheck(0L); + if (challoc - ch_size < 18) // Make sure have space in current chunk + chcheck(0); m = &machtab[state - 1000]; + // Call special-mode handler if (m->mnattr & CGSPECIAL) - { // Call special-mode handler + { (*m->mnfunc)(m->mninst, siz); goto loop; } - if (amode(1) < 0) // Parse 0, 1 or 2 addr modes + if (amode(1) < 0) // Parse 0, 1 or 2 addr modes goto loop; if (*tok != EOL) @@ -649,7 +670,8 @@ do_label: amsk0 = amsktab[am0]; amsk1 = amsktab[am1]; - // Catch attempts to use ".B" with an address register (yes, this check does work at this level) + // Catch attempts to use ".B" with an address register (yes, this check + // does work at this level) if (siz == SIZB && (am0 == AREG || am1 == AREG)) { error("cannot use '.b' with an address register"); @@ -672,7 +694,7 @@ do_label: // // .if, Start Conditional Assembly // -int d_if (void) +int d_if(void) { IFENT * rif; WORD eattr; @@ -681,7 +703,8 @@ int d_if (void) // Alloc an IFENTRY if ((rif = f_ifent) == NULL) - rif = (IFENT *)amem((LONG)sizeof(IFENT)); +// rif = (IFENT *)amem((LONG)sizeof(IFENT)); + rif = (IFENT *)malloc(sizeof(IFENT)); else f_ifent = rif->if_prev; diff --git a/rmac.c b/rmac.c index 3cc24f4..56ff27f 100644 --- a/rmac.c +++ b/rmac.c @@ -308,14 +308,16 @@ char * amem(LONG amount) { char * p; - if (amount & 1) // Keep word alignment - ++amount; +// if (amount & 1) // Keep word alignment +// amount++; + amount = (amount + 1) & ~(0x01); // Keep word alignment + // Honor *small* request (< 64 bytes) if (amount < A_THRESH) - { // Honor *small* request + { if (a_amount < amount) { - a_ptr = amem(A_AMOUNT); + a_ptr = amem(A_AMOUNT); // Allocate 4K bytes a_amount = A_AMOUNT; } @@ -325,11 +327,11 @@ char * amem(LONG amount) } else { - amemtot += amount; // Bump total alloc - p = (char *)malloc(amount); // Get memory from malloc + amemtot += amount; // Bump total alloc + p = (char *)malloc(amount); // Get memory from malloc - if ((LONG)p == (LONG)NULL) - fatal("memory exhausted"); + if (p == NULL) + fatal("Memory exhausted!"); memset(p, 0, amount); } diff --git a/rmac.h b/rmac.h index 9afb0e4..f660a0d 100644 --- a/rmac.h +++ b/rmac.h @@ -14,50 +14,50 @@ // #ifdef WIN32 -#define PLATFORM "Win32" // Release platform - windows -#define _OPEN_FLAGS _O_TRUNC|_O_CREAT|_O_BINARY|_O_RDWR -#define _OPEN_INC _O_RDONLY|_O_BINARY -#define _PERM_MODE _S_IREAD|_S_IWRITE -#ifdef _MSC_VER - #if _MSC_VER > 1000 - #pragma warning(disable:4996) - #endif -#endif -#include -#include -#include -#include -#include -#include -#include -#include + #define PLATFORM "Win32" // Release platform - windows + #define _OPEN_FLAGS _O_TRUNC|_O_CREAT|_O_BINARY|_O_RDWR + #define _OPEN_INC _O_RDONLY|_O_BINARY + #define _PERM_MODE _S_IREAD|_S_IWRITE + #ifdef _MSC_VER + #if _MSC_VER > 1000 + #pragma warning(disable:4996) + #endif + #endif + #include + #include + #include + #include + #include + #include + #include + #include #else -#ifdef __GCCUNIX__ -#define PLATFORM "OSX/Linux" // Release platform - mac OS-X or linux -#define _OPEN_FLAGS O_TRUNC|O_CREAT|O_RDWR -#define _OPEN_INC O_RDONLY -#define _PERM_MODE S_IREAD|S_IWRITE -#include -#include -#include -#include -#include -#include -#include -#include + #ifdef __GCCUNIX__ + #define PLATFORM "OSX/Linux" // Release platform - mac OS-X or linux + #define _OPEN_FLAGS O_TRUNC|O_CREAT|O_RDWR + #define _OPEN_INC O_RDONLY + #define _PERM_MODE S_IREAD|S_IWRITE + #include + #include + #include + #include + #include + #include + #include + #include #else -#define PLATFORM "Unknown" // Release platform - not specified -#define _OPEN_FLAGS O_TRUNC|O_CREAT|O_RDWR -#define _OPEN_INC O_RDONLY -#define _PERM_MODE S_IREAD|S_IWRITE -#include -#include -#include -#include -#include -#include -#include -#endif + #define PLATFORM "Unknown" // Release platform - not specified + #define _OPEN_FLAGS O_TRUNC|O_CREAT|O_RDWR + #define _OPEN_INC O_RDONLY + #define _PERM_MODE S_IREAD|S_IWRITE + #include + #include + #include + #include + #include + #include + #include + #endif #endif #include @@ -67,112 +67,112 @@ #define LONG uint32_t #define VOID void -#define ERROR (-1) // Generic error return -#define EOS '\0' // End of string -#define SPACE ' ' // Ascii space +#define ERROR (-1) // Generic error return +#define EOS '\0' // End of string +#define SPACE ' ' // Ascii space #define SLASHCHAR '/' #define SLASHSTRING "/" -#define VALUE LONG // Assembler value -#define TOKEN LONG // Assembler token -#define FNSIZ 128 // Maximum size of a filename -#define OK 0 // OK return -#define DEBUG if(debug) // Debug conditional -#define MAXARGV 100 // Maximum number of commandline args -#define STDOUT 1 // Standard output -#define ERROUT 2 // Error output +#define VALUE LONG // Assembler value +#define TOKEN LONG // Assembler token +#define FNSIZ 128 // Maximum size of a filename +#define OK 0 // OK return +#define DEBUG if (debug) // Debug conditional +#define MAXARGV 100 // Maximum number of commandline args +#define STDOUT 1 // Standard output +#define ERROUT 2 // Error output #define CREATMASK 0 // (Normally) non-printable tokens -#define COLON ':' // : (grumble: GNUmacs hates ':') -#define CONST 'a' // CONST -#define ACONST 'A' // ACONST -#define STRING 'b' // STRING
-#define SYMBOL 'c' // SYMBOL
-#define EOL 'e' // End of line -#define TKEOF 'f' // End of file (or macro) -#define DEQUALS 'g' // == -#define SET 149 // set -#define REG 'R' // reg -#define EQUREG 148 // equreg -#define CCDEF 183 // ccdef -#define DCOLON 'h' // :: -#define GE 'i' // >= -#define LE 'j' // <= -#define NE 'k' // <> or != -#define SHR 'l' // >> -#define SHL 'm' // << -#define UNMINUS 'n' // Unary '-' -#define DOTB 'B' // .b or .B or .s or .S -#define DOTW 'W' // .w or .W -#define DOTL 'L' // .l or .L -#define DOTI 'I' // .i or .I -#define ENDEXPR 'E' // End of expression +#define COLON ':' // : (grumble: GNUmacs hates ':') +#define CONST 'a' // CONST +#define ACONST 'A' // ACONST +#define STRING 'b' // STRING
+#define SYMBOL 'c' // SYMBOL
+#define EOL 'e' // End of line +#define TKEOF 'f' // End of file (or macro) +#define DEQUALS 'g' // == +#define SET 149 // set +#define REG 'R' // reg +#define EQUREG 148 // equreg +#define CCDEF 183 // ccdef +#define DCOLON 'h' // :: +#define GE 'i' // >= +#define LE 'j' // <= +#define NE 'k' // <> or != +#define SHR 'l' // >> +#define SHL 'm' // << +#define UNMINUS 'n' // Unary '-' +#define DOTB 'B' // .b or .B or .s or .S +#define DOTW 'W' // .w or .W +#define DOTL 'L' // .l or .L +#define DOTI 'I' // .i or .I +#define ENDEXPR 'E' // End of expression // Object code formats -#define ALCYON 0 // Alcyon/DRI C object format -#define MWC 1 // Mark Williams object format -#define BSD 2 // BSD object format +#define ALCYON 0 // Alcyon/DRI C object format +#define MWC 1 // Mark Williams object format +#define BSD 2 // BSD object format // Symbols #define SYM struct _sym SYM { - SYM * snext; // * -> Next symbol on hash-chain - SYM * sorder; // * -> Next sym in order of refrence - SYM * sdecl; // * -> Next sym in order of declaration - BYTE stype; // Symbol type - WORD sattr; // Attribute bits - LONG sattre; // Extended attribute bits - WORD senv; // Enviroment number - LONG svalue; // Symbol value - char * sname; // * -> Symbol's print-name + SYM * snext; // * -> Next symbol on hash-chain + SYM * sorder; // * -> Next sym in order of refrence + SYM * sdecl; // * -> Next sym in order of declaration + BYTE stype; // Symbol type + WORD sattr; // Attribute bits + LONG sattre; // Extended attribute bits + WORD senv; // Enviroment number + LONG svalue; // Symbol value + char * sname; // * -> Symbol's print-name }; // Pointer type that can point to (almost) anything #define PTR union _ptr PTR { - char * cp; // Char - WORD * wp; // WORD - LONG * lp; // LONG - LONG lw; // LONG - SYM ** sy; // SYM - TOKEN * tk; // TOKEN + char * cp; // Char + WORD * wp; // WORD + LONG * lp; // LONG + LONG lw; // LONG + SYM ** sy; // SYM + TOKEN * tk; // TOKEN }; // Symbol spaces -#define LABEL 0 // User-defined symbol -#define MACRO 1 // Macro definition -#define MACARG 2 // Macro argument -#define SY_UNDEF -1 // Undefined (lookup never matches it) +#define LABEL 0 // User-defined symbol +#define MACRO 1 // Macro definition +#define MACARG 2 // Macro argument +#define SY_UNDEF -1 // Undefined (lookup never matches it) // Symbol and expression attributes -#define DEFINED 0x8000 // Symbol has been defined -#define GLOBAL 0x4000 // Symbol has been .GLOBL'd -#define COMMON 0x2000 // Symbol has been .COMM'd -#define REFERENCED 0x1000 // Symbol has been referenced -#define EQUATED 0x0800 // Symbol was equated -#define SDECLLIST 0x0400 // Symbol is on 'sdecl'-order list +#define DEFINED 0x8000 // Symbol has been defined +#define GLOBAL 0x4000 // Symbol has been .GLOBL'd +#define COMMON 0x2000 // Symbol has been .COMM'd +#define REFERENCED 0x1000 // Symbol has been referenced +#define EQUATED 0x0800 // Symbol was equated +#define SDECLLIST 0x0400 // Symbol is on 'sdecl'-order list // Expression spaces, ORed with symbol and expression attributes above -#define ABS 0x0000 // In absolute space -#define TEXT 0x0001 // Relative to text -#define DATA 0x0002 // Relative to data -#define BSS 0x0004 // Relative to BSS -//#define M6502 0x0008 // 6502/microprocessor (absolute) -#define TDB (TEXT|DATA|BSS) // Mask for text+data+bss +#define ABS 0x0000 // In absolute space +#define TEXT 0x0001 // Relative to text +#define DATA 0x0002 // Relative to data +#define BSS 0x0004 // Relative to BSS +//#define M6502 0x0008 // 6502/microprocessor (absolute) +#define TDB (TEXT|DATA|BSS) // Mask for text+data+bss // Sizes -#define SIZB 0x0001 // .b -#define SIZW 0x0002 // .w -#define SIZL 0x0004 // .l -#define SIZN 0x0008 // no .(size) specifier +#define SIZB 0x0001 // .b +#define SIZW 0x0002 // .w +#define SIZL 0x0004 // .l +#define SIZN 0x0008 // no .(size) specifier // RISC register bank definitions (used in extended symbol attributes also) -#define BANK_N 0x0000 // No register bank specified -#define BANK_0 0x0001 // Register bank zero specified -#define BANK_1 0x0002 // Register bank one specified -#define EQUATEDREG 0x0008 // Equated register symbol +#define BANK_N 0x0000 // No register bank specified +#define BANK_0 0x0001 // Register bank zero specified +#define BANK_1 0x0002 // Register bank one specified +#define EQUATEDREG 0x0008 // Equated register symbol #define UNDEF_EQUR 0x0010 #define EQUATEDCC 0x0020 #define UNDEF_CC 0x0040 @@ -199,7 +199,6 @@ extern int in_main; // Prototypes void init_sym(void); -SYM * lookup(char *, int, int); SYM * newsym(char *, int, int); char * fext(char *, char *, int); void cantcreat(char *); @@ -209,6 +208,6 @@ int nthpath(char *, int, char *); void clear(char *, LONG); char * copy(char *, char *, LONG); int rmac_qsort(char *, int, int, int (*)()); -char * amem(LONG); +//char * amem(LONG); #endif // __RMAC_H__ diff --git a/sect.c b/sect.c index 7db71a3..89df4b4 100644 --- a/sect.c +++ b/sect.c @@ -17,51 +17,51 @@ #include "listing.h" // Section descriptors -SECT sect[NSECTS]; // All sections... -int cursect; // Current section number - -// These are copied from the section descriptor, the current code chunk descriptor and the current -// fixup chunk descriptor when a switch is made into a section. They are copied back to the -// descriptors when the section is left. -WORD scattr; // Section attributes -LONG sloc; // Current loc in section - -CHUNK * scode; // Current (last) code chunk -LONG challoc; // #bytes alloc'd to code chunk -LONG ch_size; // #bytes used in code chunk -char * chptr; // Deposit point in code chunk buffer - -CHUNK * sfix; // Current (last) fixup chunk -LONG fchalloc; // #bytes alloc'd to fixup chunk -LONG fchsize; // #bytes used in fixup chunk -PTR fchptr; // Deposit point in fixup chunk buffer - -unsigned fwdjump[MAXFWDJUMPS]; // forward jump check table -unsigned fwindex = 0; // forward jump index - -// Return a size (SIZB, SIZW, SIZL) or 0, depending on what kind of fixup is associated -// with a location. +SECT sect[NSECTS]; // All sections... +int cursect; // Current section number + +// These are copied from the section descriptor, the current code chunk +// descriptor and the current fixup chunk descriptor when a switch is made into +// a section. They are copied back to the descriptors when the section is left. +WORD scattr; // Section attributes +LONG sloc; // Current loc in section + +CHUNK * scode; // Current (last) code chunk +LONG challoc; // # bytes alloc'd to code chunk +LONG ch_size; // # bytes used in code chunk +char * chptr; // Deposit point in code chunk buffer + +CHUNK * sfix; // Current (last) fixup chunk +LONG fchalloc; // # bytes alloc'd to fixup chunk +LONG fchsize; // # bytes used in fixup chunk +PTR fchptr; // Deposit point in fixup chunk buffer + +unsigned fwdjump[MAXFWDJUMPS]; // forward jump check table +unsigned fwindex = 0; // forward jump index + +// Return a size (SIZB, SIZW, SIZL) or 0, depending on what kind of fixup is +// associated with a location. static char fusiztab[] = { - 0, // FU_QUICK - 1, // FU_BYTE - 2, // FU_WORD - 2, // FU_WBYTE - 4, // FU_LONG - 1, // FU_BBRA - 0, // (unused) - 1, // FU_6BRA + 0, // FU_QUICK + 1, // FU_BYTE + 2, // FU_WORD + 2, // FU_WBYTE + 4, // FU_LONG + 1, // FU_BBRA + 0, // (unused) + 1, // FU_6BRA }; // Offset to REAL fixup location static char fusizoffs[] = { - 0, // FU_QUICK - 0, // FU_BYTE - 0, // FU_WORD - 1, // FU_WBYTE - 0, // FU_LONG - 1, // FU_BBRA - 0, // (unused) - 0, // FU_6BRA + 0, // FU_QUICK + 0, // FU_BYTE + 0, // FU_WORD + 1, // FU_WBYTE + 0, // FU_LONG + 1, // FU_BBRA + 0, // (unused) + 0, // FU_6BRA }; @@ -214,7 +214,7 @@ int chcheck(LONG amt) SECT * p; if (scattr & SBSS) - return 0; // If in BSS section, forget it + return 0; // If in BSS section, forget it if (!amt) amt = CH_THRESHOLD; @@ -226,18 +226,20 @@ int chcheck(LONG amt) amt = CH_CODE_SIZE; p = §[cursect]; - cp = (CHUNK *)amem((long)(sizeof(CHUNK) + amt)); + cp = (CHUNK *)malloc(sizeof(CHUNK) + amt); + // First chunk in section if (scode == NULL) - { // First chunk in section + { cp->chprev = NULL; p->sfcode = cp; } + // Add chunk to other chunks else - { // Add chunk to other chunks + { cp->chprev = scode; scode->chnext = cp; - scode->ch_size = ch_size; // Save old chunk's globals + scode->ch_size = ch_size; // Save old chunk's globals } // Setup chunk and global vars @@ -262,13 +264,14 @@ int fixup(WORD attr, LONG loc, TOKEN * fexpr) CHUNK * cp; SECT * p; - // Compute length of expression (could be faster); determine if it's the single-symbol case; - // no expression if it's just a mark. This code assumes 16 bit WORDs and 32 bit LONGs + // Compute length of expression (could be faster); determine if it's the + // single-symbol case; no expression if it's just a mark. This code assumes + // 16 bit WORDs and 32 bit LONGs if (*fexpr == SYMBOL && fexpr[2] == ENDEXPR) { if ((attr & 0x0F00) == FU_JR) // SCPCD : correct bit mask for attr (else other FU_xxx will match) NYAN ! { - i = 18; // Just a single symbol + i = 18; // Just a single symbol } else { @@ -279,13 +282,13 @@ int fixup(WORD attr, LONG loc, TOKEN * fexpr) { attr |= FU_EXPR; - for(len=0; fexpr[len]!=ENDEXPR; ++len) + for(len=0; fexpr[len]!=ENDEXPR; len++) { if (fexpr[len] == CONST || fexpr[len] == SYMBOL) - ++len; + len++; } - ++len; // Add 1 for ENDEXPR + len++; // Add 1 for ENDEXPR i = (len << 2) + 12; } @@ -293,7 +296,8 @@ int fixup(WORD attr, LONG loc, TOKEN * fexpr) if ((fchalloc - fchsize) < i) { p = §[cursect]; - cp = (CHUNK *)amem((long)(sizeof(CHUNK) + CH_FIXUP_SIZE)); +// cp = (CHUNK *)amem((long)(sizeof(CHUNK) + CH_FIXUP_SIZE)); + cp = (CHUNK *)malloc(sizeof(CHUNK) + CH_FIXUP_SIZE); if (sfix == NULL) { // First fixup chunk in section @@ -344,7 +348,6 @@ int fixup(WORD attr, LONG loc, TOKEN * fexpr) } fchsize += i; - return 0; } diff --git a/sect.h b/sect.h index 764d244..735c794 100644 --- a/sect.h +++ b/sect.h @@ -26,18 +26,18 @@ *chptr++=(char)lw;*chptr++=(char)(lw>>8); \ sloc+=4; ch_size += 4;if(orgactive) orgaddr += 4;} -#define NSECTS 16 // Max. number of sections +#define NSECTS 16 // Max. number of sections // Tunable (storage) definitions -#define CH_THRESHOLD 64 // Minimum amount of space in code chunk -#define CH_CODE_SIZE 2048 // Code chunk normal allocation -#define CH_FIXUP_SIZE 1024 // Fixup chunk normal allocation +#define CH_THRESHOLD 64 // Minimum amount of space in code chunk +#define CH_CODE_SIZE 2048 // Code chunk normal allocation +#define CH_FIXUP_SIZE 1024 // Fixup chunk normal allocation // Section attributes (.scattr) -#define SUSED 0x8000 // Section is used (really, valid) -#define SBSS 0x4000 // Section can contain no data -#define SABS 0x2000 // Section is absolute -#define SPIC 0x1000 // Section is position-independent code +#define SUSED 0x8000 // Section is used (really, valid) +#define SBSS 0x4000 // Section can contain no data +#define SABS 0x2000 // Section is absolute +#define SPIC 0x1000 // Section is position-independent code // Fixup record a WORD of these bits, followed by a loc and then a pointer // to a symbol or an ENDEXPR-terminated postfix expression. @@ -52,17 +52,17 @@ // token.L expression list // (etc) // ENDEXPR.L (end of expression) -#define FUMASK 007 // Mask for fixup cases: -#define FU_QUICK 000 // Fixup 3-bit quick instr field -#define FU_BYTE 001 // Fixup byte -#define FU_WORD 002 // Fixup word -#define FU_WBYTE 003 // Fixup byte (at loc+1) -#define FU_LONG 004 // Fixup long -#define FU_BBRA 005 // Fixup byte branch -#define FU_6BRA 007 // Fixup 6502-format branch offset -#define FU_SEXT 010 // Ok to sign extend -#define FU_PCREL 020 // Subtract PC first -#define FU_EXPR 040 // Expression (not symbol) follows +#define FUMASK 007 // Mask for fixup cases: +#define FU_QUICK 000 // Fixup 3-bit quick instr field +#define FU_BYTE 001 // Fixup byte +#define FU_WORD 002 // Fixup word +#define FU_WBYTE 003 // Fixup byte (at loc+1) +#define FU_LONG 004 // Fixup long +#define FU_BBRA 005 // Fixup byte branch +#define FU_6BRA 007 // Fixup 6502-format branch offset +#define FU_SEXT 010 // Ok to sign extend +#define FU_PCREL 020 // Subtract PC first +#define FU_EXPR 040 // Expression (not symbol) follows #define FU_MOVEI 0x0100 #define FU_JR 0x0200 @@ -73,30 +73,30 @@ #define FU_NUM32 0x0700 #define FU_REGTWO 0x0800 #define FU_SUB32 0x1000 -#define FU_ISBRA 0x2000 // Word forward fixup is a BRA or DBRA -#define FU_LBRA 0x4000 // Long branch, for short branch detect -#define FU_DONE 0x8000 // Fixup has been done +#define FU_ISBRA 0x2000 // Word forward fixup is a BRA or DBRA +#define FU_LBRA 0x4000 // Long branch, for short branch detect +#define FU_DONE 0x8000 // Fixup has been done // Chunks are used to hold generated code and fixup records #define CHUNK struct _chunk CHUNK { - CHUNK * chnext; // Next, previous chunks in section + CHUNK * chnext; // Next, previous chunks in section CHUNK * chprev; - LONG chloc; // Base addr of this chunk - LONG challoc; // #bytes allocated for chunk - LONG ch_size; // #bytes chunk actually uses - char * chptr; // Data for this chunk + LONG chloc; // Base addr of this chunk + LONG challoc; // #bytes allocated for chunk + LONG ch_size; // #bytes chunk actually uses + char * chptr; // Data for this chunk }; // Section descriptor #define SECT struct _sect SECT { - WORD scattr; // Section attributes - LONG sloc; // Current loc-in / size-of section - CHUNK * sfcode; // First chunk in section - CHUNK * scode; // Last chunk in section - CHUNK * sffix; // First fixup chunk - CHUNK * sfix; // Last fixup chunk + WORD scattr; // Section attributes + LONG sloc; // Current loc-in / size-of section + CHUNK * sfcode; // First chunk in section + CHUNK * scode; // Last chunk in section + CHUNK * sffix; // First fixup chunk + CHUNK * sfix; // Last fixup chunk }; // A mark is of the form: @@ -106,21 +106,21 @@ SECT { // .L [symbol] symbol involved in external reference #define MCHUNK struct _mchunk MCHUNK { - MCHUNK * mcnext; // Next mark chunk - PTR mcptr; // Vector of marks - LONG mcalloc; // #marks allocted to mark block - LONG mcused; // #marks used in block + MCHUNK * mcnext; // Next mark chunk + PTR mcptr; // Vector of marks + LONG mcalloc; // #marks allocted to mark block + LONG mcused; // #marks used in block }; -#define MWORD 0x0000 // Marked word -#define MLONG 0x0100 // Marked long +#define MWORD 0x0000 // Marked word +#define MLONG 0x0100 // Marked long #define MMOVEI 0x0200 -#define MCHFROM 0x8000 // Mark includes change-to-from -#define MSYMBOL 0x4000 // Mark includes symbol number -#define MCHEND 0x2000 // Indicates end of mark chunk -#define MPCREL 0x1000 // Mark is PC-relative +#define MCHFROM 0x8000 // Mark includes change-to-from +#define MSYMBOL 0x4000 // Mark includes symbol number +#define MCHEND 0x2000 // Indicates end of mark chunk +#define MPCREL 0x1000 // Mark is PC-relative -#define MAXFWDJUMPS 1024 // Maximum forward jumps to check +#define MAXFWDJUMPS 1024 // Maximum forward jumps to check extern unsigned fwdjump[MAXFWDJUMPS]; extern unsigned fwindex; diff --git a/symbol.c b/symbol.c index 25829f4..fbe84a5 100644 --- a/symbol.c +++ b/symbol.c @@ -11,12 +11,12 @@ #include "procln.h" #include "error.h" -static SYM * sytab[NBUCKETS]; // User symbol-table header -int curenv; // Current enviroment number -SYM * sorder; // * -> Symbols, in order of reference -SYM * sordtail; // * -> Last symbol in sorder list -SYM * sdecl; // * -> Symbols, in order of declaration -SYM * sdecltail; // * -> Last symbol in sdecl list +static SYM * sytab[NBUCKETS]; // User symbol-table header +int curenv; // Current enviroment number +SYM * sorder; // * -> Symbols, in order of reference +SYM * sordtail; // * -> Last symbol in sorder list +SYM * sdecl; // * -> Symbols, in order of declaration +SYM * sdecltail; // * -> Last symbol in sdecl list // Tags for marking symbol spaces // a = absolute @@ -34,50 +34,27 @@ static char tdb_text[8] = { // void init_sym(void) { - int i; // Iterator + int i; // Iterator - for(i=0; isname = nstring(name); +// sy->sname = nstring(name); + sy->sname = strdup(name); // Fill-in the symbol sy->stype = (BYTE)type; sy->senv = (WORD)envno; sy->sattr = 0; - +#if 0 if (rgpu || rdsp) sy->sattre = RISCSYM; else sy->sattre = 0; - +#else + sy->sattre = (rgpu || rdsp ? RISCSYM : 0); +#endif sy->svalue = 0; // Install symbol in symbol table @@ -127,14 +108,14 @@ SYM * newsym(char * name, int type, int envno) // Append symbol to symbol-order list if (sorder == NULL) - sorder = sy; // Add first symbol + sorder = sy; // Add first symbol else - sordtail->sorder = sy; // Or append to tail of list + sordtail->sorder = sy; // Or append to tail of list sy->sorder = NULL; sordtail = sy; - return sy; // Return pointer to symbol + return sy; // Return pointer to symbol } @@ -144,9 +125,10 @@ SYM * newsym(char * name, int type, int envno) // SYM * lookup(char * name, int type, int envno) { - SYM * sy; // Symbol record pointer - int k, sum; // Hash bucket calculation - char * s; // String pointer +#if 0 + SYM * sy; // Symbol record pointer + int k, sum; // Hash bucket calculation + char * s; // String pointer // Pick a hash-bucket (SAME algorithm as syhash()) k = 0; @@ -161,20 +143,23 @@ SYM * lookup(char * name, int type, int envno) } sy = sytab[sum & (NBUCKETS-1)]; +#else + SYM * sy = sytab[syhash(name, envno)]; +#endif // Do linear-search for symbol in bucket while (sy != NULL) { - if (sy->stype == type && // Type, envno and name must match - sy->senv == envno && - *name == *sy->sname && // Fast check for first character - !strcmp(name, sy->sname)) + if (sy->stype == type // Type, envno and name must match + && sy->senv == envno + && *name == *sy->sname // Fast check for first character + && !strcmp(name, sy->sname)) break; else sy = sy->snext; } - return sy; // Return NULL or matching symbol + return sy; // Return NULL or matching symbol } @@ -209,7 +194,7 @@ int syg_fix(void) // Scan through all symbols; // If a symbol is REFERENCED but not DEFINED, then make it global. - for(sy = sorder; sy != NULL; sy = sy->sorder) + for(sy=sorder; sy!=NULL; sy=sy->sorder) { if (sy->stype == LABEL && sy->senv == 0 && ((sy->sattr & (REFERENCED|DEFINED)) == REFERENCED)) @@ -225,7 +210,7 @@ int syg_fix(void) // int uc_string(char * s) { - for(; *s; ++s) + for(; *s; s++) { if (*s >= 'a' && *s <= 'z') *s -= 32; @@ -240,7 +225,7 @@ int uc_string(char * s) // number is put in `.senv'. Return the number of symbols that will be in the // symbol table. // -int sy_assign(char * buf, char *(*constr)()) +int sy_assign(char * buf, char *(* constr)()) { SYM * sy; int scount; @@ -332,7 +317,8 @@ int symtable(void) // Allocate storage for list headers and partition all labels. // Throw away macros and macro arguments. - sy = (SYM **)amem((LONG)(128 * sizeof(LONG))); +// sy = (SYM **)amem((LONG)(128 * sizeof(LONG))); + sy = (SYM **)malloc(128 * sizeof(LONG)); for(i=0; i<128; ++i) sy[i] = NULL; @@ -346,7 +332,7 @@ int symtable(void) r = NULL; if (p->stype != LABEL) - continue; // Ignore non-labels + continue; // Ignore non-labels if (p->sattre & UNDEF_EQUR) continue; @@ -360,12 +346,12 @@ int symtable(void) } if (r == NULL) - { // Insert at front of list + { // Insert at front of list p->snext = sy[j]; sy[j] = p; } else - { // Insert in middle or append to list + { // Insert in middle or append to list p->snext = r->snext; r->snext = p; } diff --git a/symbol.h b/symbol.h index 9da0843..9f46ee3 100644 --- a/symbol.h +++ b/symbol.h @@ -22,7 +22,6 @@ extern char subttl[]; SYM * lookup(char *, int, int); void init_sym(void); SYM * newsym(char *, int, int); -char * nstring(char *); void sym_decl(SYM *); int syg_fix(void); int symtable(void); diff --git a/token.c b/token.c index 4f812c2..cd515a8 100644 --- a/token.c +++ b/token.c @@ -12,26 +12,27 @@ #include "macro.h" #include "error.h" -#define DECL_KW // Declare keyword arrays -#define DEF_KW // Declare keyword values -#include "kwtab.h" // Incl generated keyword tables & defs - -int lnsave; // 1; strcpy() text of current line -int curlineno; // Current line number -int totlines; // Total # of lines -int mjump_align = 0; // mjump alignment flag -char lntag; // Line tag -char * curfname; // Current filename -char tolowertab[128]; // Uppercase ==> lowercase -char hextab[128]; // Table of hex values -char dotxtab[128]; // Table for ".b", ".s", etc. -char irbuf[LNSIZ]; // Text for .rept block line -char lnbuf[LNSIZ]; // Text of current line -WORD filecount; // Unique file number counter -WORD cfileno; // Current file number -TOKEN * tok; // Ptr to current token -TOKEN * etok; // Ptr past last token in tokbuf[] -TOKEN tokeol[1] = {EOL}; // Bailout end-of-line token +#define DECL_KW // Declare keyword arrays +#define DEF_KW // Declare keyword values +#include "kwtab.h" // Incl generated keyword tables & defs + +int lnsave; // 1; strcpy() text of current line +int curlineno; // Current line number +int totlines; // Total # of lines +int mjump_align = 0; // mjump alignment flag +char lntag; // Line tag +char * curfname; // Current filename +char tolowertab[128]; // Uppercase ==> lowercase +char hextab[128]; // Table of hex values +char dotxtab[128]; // Table for ".b", ".s", etc. +char irbuf[LNSIZ]; // Text for .rept block line +char lnbuf[LNSIZ]; // Text of current line +WORD filecount; // Unique file number counter +WORD cfileno; // Current file number +TOKEN * tok; // Ptr to current token +TOKEN * etok; // Ptr past last token in tokbuf[] +TOKEN tokeol[1] = {EOL}; // Bailout end-of-line token +char * string[TOKBUFSIZE]; // Token buffer string pointer storage // File record, used to maintain a list of every include file ever visited #define FILEREC struct _filerec @@ -44,74 +45,74 @@ FILEREC FILEREC * filerec; FILEREC * last_fr; -INOBJ * cur_inobj; // Ptr current input obj (IFILE/IMACRO) -static INOBJ * f_inobj; // Ptr list of free INOBJs -static IFILE * f_ifile; // Ptr list of free IFILEs -static IMACRO * f_imacro; // Ptr list of free IMACROs +INOBJ * cur_inobj; // Ptr current input obj (IFILE/IMACRO) +static INOBJ * f_inobj; // Ptr list of free INOBJs +static IFILE * f_ifile; // Ptr list of free IFILEs +static IMACRO * f_imacro; // Ptr list of free IMACROs -static TOKEN tokbuf[TOKBUFSIZE]; // Token buffer (stack-like, all files) +static TOKEN tokbuf[TOKBUFSIZE]; // Token buffer (stack-like, all files) char chrtab[] = { - ILLEG, ILLEG, ILLEG, ILLEG, // NUL SOH STX ETX - ILLEG, ILLEG, ILLEG, ILLEG, // EOT ENQ ACK BEL - ILLEG, WHITE, ILLEG, ILLEG, // BS HT LF VT - WHITE, ILLEG, ILLEG, ILLEG, // FF CR SO SI - - ILLEG, ILLEG, ILLEG, ILLEG, // DLE DC1 DC2 DC3 - ILLEG, ILLEG, ILLEG, ILLEG, // DC4 NAK SYN ETB - ILLEG, ILLEG, ILLEG, ILLEG, // CAN EM SUB ESC - ILLEG, ILLEG, ILLEG, ILLEG, // FS GS RS US - - WHITE, MULTX, MULTX, SELF, // SP ! " # - MULTX+CTSYM, MULTX, SELF, MULTX, // $ % & ' - SELF, SELF, SELF, SELF, // ( ) * + - SELF, SELF, STSYM, SELF, // , - . / - - DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 0 1 - DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 2 3 - DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 4 5 - DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 6 7 - DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 8 9 - MULTX, MULTX, // : ; - MULTX, MULTX, MULTX, STSYM+CTSYM, // < = > ? - - MULTX, STSYM+CTSYM+HDIGIT, // @ A - (char)((BYTE)DOT)+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // B C - STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // D E - STSYM+CTSYM+HDIGIT, STSYM+CTSYM, // F G - STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // H I J K - (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // L M N O - - STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // P Q R S - STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // T U V W - STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF, // X Y Z [ - SELF, SELF, MULTX, STSYM+CTSYM, // \ ] ^ _ - - ILLEG, STSYM+CTSYM+HDIGIT, // ` a - (char)((BYTE)DOT)+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // b c - STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // d e - STSYM+CTSYM+HDIGIT, STSYM+CTSYM, // f g - STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // h i j k - (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // l m n o - - STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // p q r s - STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // t u v w - STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF, // x y z { - SELF, SELF, SELF, ILLEG // | } ~ DEL + ILLEG, ILLEG, ILLEG, ILLEG, // NUL SOH STX ETX + ILLEG, ILLEG, ILLEG, ILLEG, // EOT ENQ ACK BEL + ILLEG, WHITE, ILLEG, ILLEG, // BS HT LF VT + WHITE, ILLEG, ILLEG, ILLEG, // FF CR SO SI + + ILLEG, ILLEG, ILLEG, ILLEG, // DLE DC1 DC2 DC3 + ILLEG, ILLEG, ILLEG, ILLEG, // DC4 NAK SYN ETB + ILLEG, ILLEG, ILLEG, ILLEG, // CAN EM SUB ESC + ILLEG, ILLEG, ILLEG, ILLEG, // FS GS RS US + + WHITE, MULTX, MULTX, SELF, // SP ! " # + MULTX+CTSYM, MULTX, SELF, MULTX, // $ % & ' + SELF, SELF, SELF, SELF, // ( ) * + + SELF, SELF, STSYM, SELF, // , - . / + + DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 0 1 + DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 2 3 + DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 4 5 + DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 6 7 + DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM, // 8 9 + MULTX, MULTX, // : ; + MULTX, MULTX, MULTX, STSYM+CTSYM, // < = > ? + + MULTX, STSYM+CTSYM+HDIGIT, // @ A + (char)((BYTE)DOT)+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // B C + STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // D E + STSYM+CTSYM+HDIGIT, STSYM+CTSYM, // F G + STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // H I J K + (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // L M N O + + STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // P Q R S + STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // T U V W + STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF, // X Y Z [ + SELF, SELF, MULTX, STSYM+CTSYM, // \ ] ^ _ + + ILLEG, STSYM+CTSYM+HDIGIT, // ` a + (char)((BYTE)DOT)+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // b c + STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT, // d e + STSYM+CTSYM+HDIGIT, STSYM+CTSYM, // f g + STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // h i j k + (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, // l m n o + + STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // p q r s + STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM, // t u v w + STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF, // x y z { + SELF, SELF, SELF, ILLEG // | } ~ DEL }; // Names of registers static char * regname[] = { - "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", - "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", - "pc", "ssp", "usp", "sr", "ccr" + "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", + "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", + "pc", "ssp", "usp", "sr", "ccr" }; static char * riscregname[] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", - "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" }; @@ -142,7 +143,8 @@ INOBJ * a_inobj(int typ) // Allocate and initialize INOBJ first if (f_inobj == NULL) - inobj = (INOBJ *)amem((LONG)sizeof(INOBJ)); +// inobj = (INOBJ *)amem((LONG)sizeof(INOBJ)); + inobj = (INOBJ *)malloc(sizeof(INOBJ)); else { inobj = f_inobj; @@ -151,9 +153,10 @@ INOBJ * a_inobj(int typ) switch (typ) { - case SRC_IFILE: // Alloc and init an IFILE + case SRC_IFILE: // Alloc and init an IFILE if (f_ifile == NULL) - ifile = (IFILE *)amem((LONG)sizeof(IFILE)); +// ifile = (IFILE *)amem((LONG)sizeof(IFILE)); + ifile = (IFILE *)malloc(sizeof(IFILE)); else { ifile = f_ifile; @@ -162,9 +165,10 @@ INOBJ * a_inobj(int typ) inobj->inobj.ifile = ifile; break; - case SRC_IMACRO: // Alloc and init an IMACRO + case SRC_IMACRO: // Alloc and init an IMACRO if (f_imacro == NULL) - imacro = (IMACRO *)amem((LONG)sizeof(IMACRO)); +// imacro = (IMACRO *)amem((LONG)sizeof(IMACRO)); + imacro = (IMACRO *)malloc(sizeof(IMACRO)); else { imacro = f_imacro; @@ -173,14 +177,15 @@ INOBJ * a_inobj(int typ) inobj->inobj.imacro = imacro; break; - case SRC_IREPT: // Alloc and init an IREPT - inobj->inobj.irept = (IREPT *)amem((LONG)sizeof(IREPT)); + case SRC_IREPT: // Alloc and init an IREPT +// inobj->inobj.irept = (IREPT *)amem((LONG)sizeof(IREPT)); + inobj->inobj.irept = (IREPT *)malloc(sizeof(IREPT)); DEBUG printf("alloc IREPT\n"); break; } // Install INOBJ on top of input stack - inobj->in_ifent = ifent; // Record .if context on entry + inobj->in_ifent = ifent; // Record .if context on entry inobj->in_type = (WORD)typ; inobj->in_otok = tok; inobj->in_etok = etok; @@ -209,66 +214,69 @@ int mexpand(char * src, char * dest, int destsiz) { char * s; char * d = NULL; - char * dst; // Next dest slot - char * edst; // End+1 of dest buffer + char * dst; // Next dest slot + char * edst; // End+1 of dest buffer int i; - int questmark; // \? for testing argument existence + int questmark; // \? for testing argument existence TOKEN * tk; - char mname[128]; // Assume max size of a formal arg name + char mname[128]; // Assume max size of a formal arg name int macnum; SYM * arg; IMACRO * imacro; - char numbuf[20]; // Buffer for text of CONSTs + char numbuf[20]; // Buffer for text of CONSTs imacro = cur_inobj->inobj.imacro; macnum = (int)(imacro->im_macro->sattr); - --destsiz; + destsiz--; dst = dest; edst = dest + destsiz; // Check for (and skip over) any "label" on the line s = src; + if (*s == ':') { while (*s != EOS && !(chrtab[*s] & WHITE)) - ++s; + s++; if (*s != EOS) - ++s; // Skip first whitespace + s++; // Skip first whitespace } // Expand the rest of the line while (*s != EOS) { + // Copy single character if (*s != '\\') - { // Copy single character + { if (dst >= edst) goto overflow; *dst++ = *s++; } + // Do macro expansion else - { // Do macro expansion + { questmark = 0; // Do special cases switch (*++s) { - case '\\': // \\, \ (collapse to single backslash) + case '\\': // \\, \ (collapse to single backslash) if (dst >= edst) goto overflow; *dst++ = *s++; continue; - case '?': // \? set `questmark' flag + case '?': // \? set `questmark' flag ++s; questmark = 1; break; - case '#': // \#, number of arguments + case '#': // \#, number of arguments sprintf(numbuf, "%d", (int)imacro->im_nargs); goto copystr; - case '!': // \! size suffix supplied on invocation + case '!': // \! size suffix supplied on invocation switch ((int)imacro->im_siz) { case SIZN: d = ""; break; @@ -278,7 +286,7 @@ int mexpand(char * src, char * dest, int destsiz) } goto copy_d; - case '~': // ==> unique label string Mnnnn... + case '~': // ==> unique label string Mnnnn... sprintf(numbuf, "M%ud", curuniq); copystr: d = numbuf; @@ -311,16 +319,19 @@ copy_d: // Get argument name: \name, \{name} d = mname; + + // \foo if (*s != '{') - { // \foo + { do { *d++ = *s++; } while (chrtab[*s] & CTSYM); } + // \\{foo} else - { // \\{foo} + { for(++s; *s != EOS && *s != '}';) *d++ = *s++; @@ -332,15 +343,17 @@ copy_d: *d = EOS; - // Lookup the argument and copy its (string) value into the destination string + // Lookup the argument and copy its (string) value into the + // destination string DEBUG printf("mname='%s'\n", mname); if ((arg = lookup(mname, MACARG, macnum)) == NULL) return errors("undefined argument: '%s'", mname); else { - // Convert a string of tokens (terminated with EOL) back into text. If an argument - // is out of range (not specified in the macro invocation) then it is ignored. + // Convert a string of tokens (terminated with EOL) back into + // text. If an argument is out of range (not specified in the + // macro invocation) then it is ignored. i = (int)arg->svalue; arg_num: DEBUG printf("~argnumber=%d\n", i); @@ -365,12 +378,12 @@ arg_num: continue; } - if (tk != NULL) // arg# is in range, so expand it + if (tk != NULL) // arg# is in range, so expand it { while (*tk != EOL) { - // Reverse-translation from a token number to a string. This is a hack. - // It might be better table-driven. + // Reverse-translation from a token number to a string. + // This is a hack. It might be better table-driven. d = NULL; if ((*tk >= KW_D0) && !rdsp && !rgpu) @@ -477,7 +490,7 @@ arg_num: if (dst >= edst) goto overflow; - *dst++ = (char)*(tk-1); + *dst++ = (char)*(tk - 1); break; } } @@ -516,14 +529,12 @@ overflow: // char * getmln(void) { - IMACRO * imacro; - LONG * strp; unsigned source_addr; - imacro = cur_inobj->inobj.imacro; - strp = imacro->im_nextln; + IMACRO * imacro = cur_inobj->inobj.imacro; + LONG * strp = imacro->im_nextln; - if (strp == NULL) // End-of-macro + if (strp == NULL) // End-of-macro return NULL; imacro->im_nextln = (LONG *)*strp; @@ -531,9 +542,9 @@ char * getmln(void) if (!strcmp(imacro->im_macro->sname, "mjump") && !mjump_align) { - // if we need to adjust the alignment of the jump source address to meet the rules of - // gpu main execution we need to skip the first nop of the macro. This is simpler than - // trying to insert nop's mid macro. + // if we need to adjust the alignment of the jump source address to + // meet the rules of gpu main execution we need to skip the first nop + // of the macro. This is simpler than trying to insert nop's mid macro. source_addr = (orgactive) ? orgaddr : sloc; source_addr += 8; @@ -560,17 +571,15 @@ char * getmln(void) // char * getrln(void) { - IREPT * irept; - LONG * strp; - irept = cur_inobj->inobj.irept; - strp = irept->ir_nextln; // initial null + IREPT * irept = cur_inobj->inobj.irept; + LONG * strp = irept->ir_nextln; // initial null // Do repeat at end of .rept block's string list if (strp == NULL) { DEBUG printf("back-to-top-of-repeat-block count=%d\n", (int)irept->ir_count); - irept->ir_nextln = irept->ir_firstln; // copy first line + irept->ir_nextln = irept->ir_firstln; // copy first line if (irept->ir_count-- == 0) { @@ -578,11 +587,10 @@ char * getrln(void) return NULL; } - strp = irept->ir_nextln; //strp + strp = irept->ir_nextln; //strp } - strcpy(irbuf, (char*)(irept->ir_nextln + 1)); - + strcpy(irbuf, (char *)(irept->ir_nextln + 1)); DEBUG printf("repeat line='%s'\n", irbuf); irept->ir_nextln = (LONG *)*strp; @@ -599,31 +607,33 @@ int include(int handle, char * fname) INOBJ * inobj; FILEREC * fr; + // Verbose mode if (verb_flag) - printf("[Including: %s]\n", fname); // Verbose mode + printf("[Including: %s]\n", fname); // Alloc and initialize include-descriptors inobj = a_inobj(SRC_IFILE); ifile = inobj->inobj.ifile; - ifile->ifhandle = handle; // Setup file handle - ifile->ifind = ifile->ifcnt = 0; // Setup buffer indices - ifile->ifoldlineno = curlineno; // Save old line number - ifile->ifoldfname = curfname; // Save old filename - ifile->ifno = cfileno; // Save old file number - cfileno = ++filecount; // Compute new file number - curfname = nstring(fname); // Set current filename (alloc storage) - curlineno = 0; // Start on line zero + ifile->ifhandle = handle; // Setup file handle + ifile->ifind = ifile->ifcnt = 0; // Setup buffer indices + ifile->ifoldlineno = curlineno; // Save old line number + ifile->ifoldfname = curfname; // Save old filename + ifile->ifno = cfileno; // Save old file number + cfileno = filecount++; // Compute new file number + curfname = strdup(fname); // Set current filename (alloc storage) + curlineno = 0; // Start on line zero // Add another file to the file-record - fr = (FILEREC *)amem((LONG)sizeof(FILEREC)); +// fr = (FILEREC *)amem((LONG)sizeof(FILEREC)); + fr = (FILEREC *)malloc(sizeof(FILEREC)); fr->frec_next = NULL; fr->frec_name = curfname; if (last_fr == NULL) - filerec = fr; // Add first filerec + filerec = fr; // Add first filerec else - last_fr->frec_next = fr; // Append to list of filerecs + last_fr->frec_next = fr; // Append to list of filerecs last_fr = fr; @@ -636,13 +646,13 @@ int include(int handle, char * fname) // void init_token(void) { - int i; // Iterator - char * htab = "0123456789abcdefABCDEF"; // Hex character table + int i; // Iterator + char * htab = "0123456789abcdefABCDEF"; // Hex character table - lnsave = 0; // Don't save lines - curfname = ""; // No file, empty filename + lnsave = 0; // Don't save lines + curfname = ""; // No file, empty filename filecount = (WORD)-1; - cfileno = (WORD)-1; // cfileno gets bumped to 0 + cfileno = (WORD)-1; // cfileno gets bumped to 0 curlineno = 0; totlines = 0; etok = tokbuf; @@ -655,29 +665,29 @@ void init_token(void) lntag = SPACE; // Initialize hex, "dot" and tolower tables - for(i=0; i<128; ++i) + for(i=0; i<128; i++) { hextab[i] = -1; dotxtab[i] = 0; tolowertab[i] = (char)i; } - for(i=0; htab[i]!=EOS; ++i) + for(i=0; htab[i]!=EOS; i++) hextab[htab[i]] = (char)((i < 16) ? i : i - 6); - for(i='A'; i<='Z'; ++i) + for(i='A'; i<='Z'; i++) tolowertab[i] |= 0x20; // These characters are legal immediately after a period - dotxtab['b'] = DOTB; // .b .B .s .S + dotxtab['b'] = DOTB; // .b .B .s .S dotxtab['B'] = DOTB; dotxtab['s'] = DOTB; dotxtab['S'] = DOTB; - dotxtab['w'] = DOTW; // .w .W + dotxtab['w'] = DOTW; // .w .W dotxtab['W'] = DOTW; - dotxtab['l'] = DOTL; // .l .L + dotxtab['l'] = DOTL; // .l .L dotxtab['L'] = DOTL; - dotxtab['I'] = DOTI; // .l .L + dotxtab['I'] = DOTI; // .l .L dotxtab['I'] = DOTI; } @@ -696,35 +706,35 @@ int fpop(void) if (inobj != NULL) { - // Pop IFENT levels until we reach the conditional assembly context we were at when the - // input object was entered. + // Pop IFENT levels until we reach the conditional assembly context we + // were at when the input object was entered. while (ifent != inobj->in_ifent) - d_endif (); + d_endif(); - tok = inobj->in_otok; // Restore tok and otok + tok = inobj->in_otok; // Restore tok and otok etok = inobj->in_etok; switch (inobj->in_type) { - case SRC_IFILE: // Pop and release an IFILE + case SRC_IFILE: // Pop and release an IFILE if (verb_flag) printf("[Leaving: %s]\n", curfname); ifile = inobj->inobj.ifile; ifile->if_link = f_ifile; f_ifile = ifile; - close(ifile->ifhandle); // Close source file - curfname = ifile->ifoldfname; // Set current filename - curlineno = ifile->ifoldlineno; // Set current line# + close(ifile->ifhandle); // Close source file + curfname = ifile->ifoldfname; // Set current filename + curlineno = ifile->ifoldlineno; // Set current line# DEBUG printf("cfileno=%d ifile->ifno=%d\n", (int)cfileno, (int)ifile->ifno); - cfileno = ifile->ifno; // Restore current file number + cfileno = ifile->ifno; // Restore current file number break; - case SRC_IMACRO: // Pop and release an IMACRO + case SRC_IMACRO: // Pop and release an IMACRO imacro = inobj->inobj.imacro; imacro->im_link = f_imacro; f_imacro = imacro; break; - case SRC_IREPT: // Pop and release an IREPT + case SRC_IREPT: // Pop and release an IREPT DEBUG printf("dealloc IREPT\n"); p = inobj->inobj.irept->ir_firstln; @@ -752,37 +762,35 @@ int fpop(void) // char * getln(void) { - IFILE * fl; int i, j; char * p, * d; - int readamt; - - readamt = -1; // 0 if last read() yeilded 0 bytes - fl = cur_inobj->inobj.ifile; + int readamt = -1; // 0 if last read() yeilded 0 bytes + IFILE * fl = cur_inobj->inobj.ifile; for(;;) { - // Scan for next end-of-line; handle stupid text formats by treating \r\n the same as \n. - // (lone '\r' at end of buffer means we have to check for '\n'). + // Scan for next end-of-line; handle stupid text formats by treating + // \r\n the same as \n. (lone '\r' at end of buffer means we have to + // check for '\n'). i = 0; j = fl->ifcnt; d = &fl->ifbuf[fl->ifind]; - for(p=d; i= j) { - break; // Look for '\n' to eat + break; // Look for '\n' to eat } else if (p[1] == '\n') { - ++i; + i++; } } @@ -794,7 +802,8 @@ char * getln(void) } } - // Handle hanging lines by ignoring them (Input file is exhausted, no \r or \n on last line) + // Handle hanging lines by ignoring them (Input file is exhausted, no + // \r or \n on last line) if (!readamt && fl->ifcnt) { fl->ifcnt = 0; @@ -810,14 +819,15 @@ char * getln(void) return &fl->ifbuf[fl->ifind]; } - // Relocate what's left of a line to the beginning of the buffer, and read some more of the - // file in; return NULL if the buffer's empty and on EOF. + // Relocate what's left of a line to the beginning of the buffer, and + // read some more of the file in; return NULL if the buffer's empty and + // on EOF. if (fl->ifind != 0) { p = &fl->ifbuf[fl->ifind]; d = &fl->ifbuf[fl->ifcnt & 1]; - for(i = 0; i < fl->ifcnt; ++i) + for(i=0; iifcnt; i++) *d++ = *p++; fl->ifind = fl->ifcnt & 1; @@ -837,23 +847,25 @@ char * getln(void) // int tokln(void) { - char * ln = NULL; // Ptr to current position in line - char * p; // Random character ptr - TOKEN *tk; // Token-deposit ptr - int state = 0; // State for keyword detector - int j = 0; // Var for keyword detector - char c; // Random char - VALUE v; // Random value - char * nullspot = NULL; // Spot to clobber for SYMBOL terminatn - int stuffnull; // 1:terminate SYMBOL '\0' at *nullspot + char * ln = NULL; // Ptr to current position in line + char * p; // Random character ptr + TOKEN * tk; // Token-deposit ptr + int state = 0; // State for keyword detector + int j = 0; // Var for keyword detector + char c; // Random char + VALUE v; // Random value + char * nullspot = NULL; // Spot to clobber for SYMBOL terminatn + int stuffnull; // 1:terminate SYMBOL '\0' at *nullspot char c1; + int stringNum = 0; // Pointer to string locations in tokenized line retry: - if (cur_inobj == NULL) // Return EOF if input stack is empty + if (cur_inobj == NULL) // Return EOF if input stack is empty return TKEOF; - // Get another line of input from the current input source: a file, a macro, or a repeat-block + // Get another line of input from the current input source: a file, + // a macro, or a repeat-block switch (cur_inobj->in_type) { // Include-file: @@ -864,16 +876,17 @@ int tokln(void) case SRC_IFILE: if ((ln = getln()) == NULL) { - fpop(); // Pop input level - goto retry; // Try for more lines + fpop(); // Pop input level + goto retry; // Try for more lines } - ++curlineno; // Bump line number + curlineno++; // Bump line number lntag = SPACE; if (as68_flag) { - // AS68 compatibility, throw away all lines starting with back-quotes, tildes, or '*' + // AS68 compatibility, throw away all lines starting with + // back-quotes, tildes, or '*' // On other lines, turn the first '*' into a semi-colon. if (*ln == '`' || *ln == '~' || *ln == '*') *ln = ';'; @@ -897,8 +910,8 @@ int tokln(void) case SRC_IMACRO: if ((ln = getmln()) == NULL) { - exitmac(); // Exit macro (pop args, do fpop(), etc) - goto retry; // Try for more lines... + exitmac(); // Exit macro (pop args, do fpop(), etc) + goto retry; // Try for more lines... } lntag = '@'; @@ -917,19 +930,21 @@ int tokln(void) break; } - // Save text of the line. We only do this during listings and within macro-type blocks, - // since it is expensive to unconditionally copy every line. + // Save text of the line. We only do this during listings and within + // macro-type blocks, since it is expensive to unconditionally copy every + // line. if (lnsave) strcpy(lnbuf, ln); // General house-keeping - tok = tokeol; // Set "tok" to EOL in case of error - tk = etok; // Reset token ptr - stuffnull = 0; // Don't stuff nulls - ++totlines; // Bump total #lines assembled - - // See if the entire line is a comment. This is a win if the programmer puts in lots of comments - if (*ln == '*' || *ln == ';' || ((*ln == '/') && (*(ln+1) == '/'))) + tok = tokeol; // Set "tok" to EOL in case of error + tk = etok; // Reset token ptr + stuffnull = 0; // Don't stuff nulls + totlines++; // Bump total #lines assembled + + // See if the entire line is a comment. This is a win if the programmer + // puts in lots of comments + if (*ln == '*' || *ln == ';' || ((*ln == '/') && (*(ln + 1) == '/'))) goto goteol; // Main tokenization loop; @@ -942,39 +957,41 @@ int tokln(void) { // Skip whitespace, handle EOL while ((int)chrtab[*ln] & WHITE) - ++ln; + ln++; // Handle EOL, comment with ';' - if (*ln == EOS || *ln == ';'|| ((*ln == '/') && (*(ln+1) == '/'))) + if (*ln == EOS || *ln == ';'|| ((*ln == '/') && (*(ln + 1) == '/'))) break; - // Handle start of symbol. Symbols are null-terminated in place. The termination is - // always one symbol behind, since there may be no place for a null in the case that - // an operator immediately follows the name. + // Handle start of symbol. Symbols are null-terminated in place. The + // termination is always one symbol behind, since there may be no place + // for a null in the case that an operator immediately follows the name. c = chrtab[*ln]; if (c & STSYM) { - if (stuffnull) // Terminate old symbol + if (stuffnull) // Terminate old symbol *nullspot = EOS; - v = 0; // Assume no DOT attrib follows symbol + v = 0; // Assume no DOT attrib follows symbol stuffnull = 1; - p = nullspot = ln++; // Nullspot -> start of this symbol + p = nullspot = ln++; // Nullspot -> start of this symbol // Find end of symbol (and compute its length) - for(j=1; (int)chrtab[*ln]&CTSYM; ++j) - ++ln; + for(j=1; (int)chrtab[*ln]&CTSYM; j++) + ln++; - // Handle "DOT" special forms (like ".b") that follow a normal symbol or keyword: + // Handle "DOT" special forms (like ".b") that follow a normal + // symbol or keyword: if (*ln == '.') { - *ln++ = EOS; // Terminate symbol - stuffnull = 0; // And never try it again + *ln++ = EOS; // Terminate symbol + stuffnull = 0; // And never try it again - // Character following the `.' must have a DOT attribute, and the chararacter after - // THAT one must not have a start-symbol attribute (to prevent symbols that look - // like, for example, "zingo.barf", which might be a good idea anyway....) + // Character following the `.' must have a DOT attribute, and + // the chararacter after THAT one must not have a start-symbol + // attribute (to prevent symbols that look like, for example, + // "zingo.barf", which might be a good idea anyway....) if ((((int)chrtab[*ln] & DOT) == 0) || ((int)dotxtab[*ln] <= 0)) return error("[bwsl] must follow `.' in symbol"); @@ -984,7 +1001,8 @@ int tokln(void) return error("misuse of `.', not allowed in symbols"); } - // If the symbol is small, check to see if it's really the name of a register. + // If the symbol is small, check to see if it's really the name of + // a register. if (j <= KWSIZE) { for(state=0; state>=0;) @@ -1029,6 +1047,9 @@ int tokln(void) if (j < 0 || state < 0) { *tk++ = SYMBOL; +#warning +//problem here: nullspot is a char * but TOKEN is a uint32_t. On a 64-bit system, +//this will cause all kinds of mischief. *tk++ = (TOKEN)nullspot; } else @@ -1037,10 +1058,10 @@ int tokln(void) stuffnull = 0; } - if (v) // Record attribute token (if any) + if (v) // Record attribute token (if any) *tk++ = (TOKEN)v; - if (stuffnull) // Arrange for string termination + if (stuffnull) // Arrange for string termination nullspot = ln; continue; @@ -1072,6 +1093,9 @@ int tokln(void) case '\"': // "string" c1 = ln[-1]; *tk++ = STRING; +#warning +// More char * stuffing (8 bytes) into the space of 4 (TOKEN). +// Need to figure out how to fix this crap. *tk++ = (TOKEN)ln; for(p=ln; *ln!=EOS && *ln!=c1;) @@ -1229,19 +1253,19 @@ int tokln(void) if (*ln == '.') { - if ((*(ln+1) == 'b') || (*(ln+1) == 'B')) + if ((*(ln + 1) == 'b') || (*(ln + 1) == 'B')) { v &= 0x000000FF; ln += 2; } - if ((*(ln+1) == 'w') || (*(ln+1) == 'W')) + if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W')) { v &= 0x0000FFFF; ln += 2; } - if ((*(ln+1) == 'l') || (*(ln+1) == 'L')) + if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L')) { ln += 2; } @@ -1350,6 +1374,7 @@ int tokln(void) while ((int)chrtab[*ln] & DIGIT) v = (v * 10) + *ln++ - '0'; + // See if there's a .[bwl] after the constant, & deal with it if (*ln == '.') { if ((*(ln+1) == 'b') || (*(ln+1) == 'B')) @@ -1382,9 +1407,9 @@ int tokln(void) // Terminate line of tokens and return "success." goteol: - tok = etok; // Set tok to beginning of line + tok = etok; // Set tok to beginning of line - if (stuffnull) // Terminate last SYMBOL + if (stuffnull) // Terminate last SYMBOL *nullspot = EOS; *tk++ = EOL; @@ -1461,3 +1486,86 @@ int d_goto(void) return error("goto label not found"); } + +void DumpTokenBuffer(void) +{ + TOKEN * t; + printf("Tokens: "); + + for(t=tokbuf; *t!=EOL; t++) + { + if (*t == COLON) + printf("[COLON]"); + else if (*t == CONST) + { + t++; + printf("[CONST: $%X]", (uint32_t)*t); + } + else if (*t == ACONST) + printf("[ACONST]"); + else if (*t == STRING) + printf("[STRING]"); + else if (*t == SYMBOL) + { + t++; + printf("[SYMBOL:\"%s\"]", (char *)*t); + } + else if (*t == EOS) + printf("[EOS]"); + else if (*t == TKEOF) + printf("[TKEOF]"); + else if (*t == DEQUALS) + printf("[DEQUALS]"); + else if (*t == SET) + printf("[SET]"); + else if (*t == REG) + printf("[REG]"); + else if (*t == DCOLON) + printf("[DCOLON]"); + else if (*t == GE) + printf("[GE]"); + else if (*t == LE) + printf("[LE]"); + else if (*t == NE) + printf("[NE]"); + else if (*t == SHR) + printf("[SHR]"); + else if (*t == SHL) + printf("[SHL]"); + else if (*t == UNMINUS) + printf("[UNMINUS]"); + else if (*t == DOTB) + printf("[DOTB]"); + else if (*t == DOTW) + printf("[DOTW]"); + else if (*t == DOTL) + printf("[DOTL]"); + else if (*t == DOTI) + printf("[DOTI]"); + else if (*t == ENDEXPR) + printf("[ENDEXPR]"); + else if (*t == CR_DEFINED) + printf("[CR_DEFINED]"); + else if (*t == CR_REFERENCED) + printf("[CR_REFERENCED]"); + else if (*t == CR_STREQ) + printf("[CR_STREQ]"); + else if (*t == CR_MACDEF) + printf("[CR_MACDEF]"); + else if (*t == CR_TIME) + printf("[CR_TIME]"); + else if (*t == CR_DATE) + printf("[CR_DATE]"); + else if (*t >= 0x20 && *t <= 0x2F) + printf("[%c]", (char)*t); + else if (*t >= 0x80 && *t <= 0x87) + printf("[D%u]", ((uint32_t)*t) - 0x80); + else if (*t >= 0x88 && *t <= 0x8F) + printf("[A%u]", ((uint32_t)*t) - 0x88); + else +// printf("[%X:%c]", (uint32_t)*t, (char)*t); + printf("[%X]", (uint32_t)*t); + } + + printf("[EOL]\n"); +} diff --git a/token.h b/token.h index be3c1e3..5ca5176 100644 --- a/token.h +++ b/token.h @@ -28,7 +28,7 @@ // Tunable definitions #define LNSIZ 256 // Maximum size of a line of text #define TOKBUFSIZE 400 // Size of token-line buffer -#define QUANTUM 4096L // #bytes to eat at a time from a file +#define QUANTUM 4096L // # bytes to eat at a time from a file #define LNBUFSIZ (QUANTUM*2) // Size of file's buffer #define KWSIZE 7 // Maximum size of keyword in kwtab.h @@ -142,6 +142,7 @@ extern unsigned orgactive; extern unsigned orgaddr; extern LONG sloc; extern int mjump_align; +extern char * string[]; // Prototypes int include(int, char *); @@ -152,5 +153,6 @@ int fpop(void); //int d_goto(WORD); int d_goto(void); INOBJ * a_inobj(int); +void DumpTokenBuffer(void); #endif // __TOKEN_H__ diff --git a/version.h b/version.h index 045c3df..493eff8 100644 --- a/version.h +++ b/version.h @@ -13,6 +13,6 @@ #define MAJOR 1 // Major version number #define MINOR 1 // Minor version number -#define PATCH 0 // Patch release number +#define PATCH 1 // Patch release number #endif // __VERSION_H__ -- 2.37.2