--- /dev/null
+68kgen
+68kgen.o
+68ktab.h
+*.o
+*~
+kwtab.h
+mntab.h
+risckw.h
+rmac
+kwgen
#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)
{
defined = (WORD)(eattr & DEFINED);
if ((challoc - ch_size) < 4)
- chcheck(4L);
+ chcheck(4);
switch (siz)
{
// Globals, Externals etc
extern TOKEN exprbuf[];
-extern int (*dirtab[])();
+extern int (* dirtab[])();
// Prototypes
int d_even(void);
#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();
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;
}
#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);
int expr(TOKEN *, VALUE *, WORD *, SYM **);
int evexpr(TOKEN *, VALUE *, WORD *, SYM **);
-#endif // __EXPR_H__
\ No newline at end of file
+#endif // __EXPR_H__
#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,...
// -----------------
// `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:
- // <directive>
- // symbol: <directive>
- 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:
+ // <directive>
+ // symbol: <directive>
+ 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; nargs<imacro->im_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);
}
// Globals, externals etc
extern LONG curuniq;
-extern TOKEN **argp;
+extern TOKEN ** argp;
extern int mjump_align;
// Prototypes
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));
#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";
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
//
//
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;
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.
}
}
- 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:
{
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;
}
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;
goto loop;
goto loop1;
- case MN_MACRO: // .macro --- macro definition
+ case MN_MACRO: // .macro --- macro definition
if (!disabled)
{
if (label != NULL)
}
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)
}
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;
if (equtyp == DEQUALS)
{
+ // Can't GLOBAL a local symbol
if (j)
- { // Can't GLOBAL a local symbol
+ {
error(locgl_error);
goto loop;
}
// 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))
{
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;
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))
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;
}
if (!j)
++curenv;
+ // Make label global
if (labtyp == DCOLON)
- { // Make label global
+ {
if (j)
{
error(locgl_error);
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;
}
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)
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");
//
// .if, Start Conditional Assembly
//
-int d_if (void)
+int d_if(void)
{
IFENT * rif;
WORD eattr;
// 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;
{
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;
}
}
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);
}
//
#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 <io.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+ #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 <io.h>
+ #include <fcntl.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <ctype.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
#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 <sys/fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
+ #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 <sys/fcntl.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <ctype.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
#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 <sys/fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#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 <sys/fcntl.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <ctype.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #endif
#endif
#include <inttypes.h>
#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 <value>
-#define ACONST 'A' // ACONST <value> <attrib>
-#define STRING 'b' // STRING <address>
-#define SYMBOL 'c' // SYMBOL <address>
-#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 <value>
+#define ACONST 'A' // ACONST <value> <attrib>
+#define STRING 'b' // STRING <address>
+#define SYMBOL 'c' // SYMBOL <address>
+#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
// Prototypes
void init_sym(void);
-SYM * lookup(char *, int, int);
SYM * newsym(char *, int, int);
char * fext(char *, char *, int);
void cantcreat(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__
#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
};
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;
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
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
{
{
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;
}
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
}
fchsize += i;
-
return 0;
}
*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.
// 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
#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:
// .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;
#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
//
void init_sym(void)
{
- int i; // Iterator
+ int i; // Iterator
- for(i=0; i<NBUCKETS; ++i) // Initialise symbol hash table
+ for(i=0; i<NBUCKETS; ++i) // Initialise symbol hash table
sytab[i] = NULL;
- curenv = 1; // Init local symbol enviroment
- sorder = NULL; // Init symbol-reference list
+ curenv = 1; // Init local symbol enviroment
+ sorder = NULL; // Init symbol-reference list
sordtail = NULL;
- sdecl = NULL; // Init symbol-decl list
+ sdecl = NULL; // Init symbol-decl list
sdecltail = NULL;
}
-//
-// Allocate and Return Pointer to a Copy of a String
-//
-char * nstring(char * str)
-{
- long i;
- char * s, * d;
-
- for(i=0; str[i]; ++i)
- ;
-
- s = d = amem(i + 1);
-
- while (*str)
- *d++ = *str++;
-
- *d++ = '\0';
-
- return s;
-}
-
-
//
// Hash the Print Name and Enviroment Number
//
int syhash(char * name, int envno)
{
- int sum, k; // Hash calculation
- k = 0;
+ int sum, k = 0; // Hash calculation
- for(sum=envno; *name; ++name)
+ for(sum=envno; *name; name++)
{
if (k++ == 1)
sum += *name << 2;
//
SYM * newsym(char * name, int type, int envno)
{
- int hash; // Symbol hash value
- SYM * sy; // Pointer to symbol
+ int hash; // Symbol hash value
+ SYM * sy; // Pointer to symbol
// Allocate the symbol
- sy = (SYM *)amem((long)(sizeof(SYM)));
+// sy = (SYM *)amem((long)(sizeof(SYM)));
+ sy = (SYM *)malloc(sizeof(SYM));
if (sy == NULL)
{
return NULL;
}
- sy->sname = 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
// 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
}
//
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;
}
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
}
// 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))
//
int uc_string(char * s)
{
- for(; *s; ++s)
+ for(; *s; s++)
{
if (*s >= 'a' && *s <= 'z')
*s -= 32;
// 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;
// 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;
r = NULL;
if (p->stype != LABEL)
- continue; // Ignore non-labels
+ continue; // Ignore non-labels
if (p->sattre & UNDEF_EQUR)
continue;
}
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;
}
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);
#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
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"
};
// 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;
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;
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;
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;
{
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 '?': // \? <macro> set `questmark' flag
+ case '?': // \? <macro> 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;
}
goto copy_d;
- case '~': // ==> unique label string Mnnnn...
+ case '~': // ==> unique label string Mnnnn...
sprintf(numbuf, "M%ud", curuniq);
copystr:
d = numbuf;
// 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++;
*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);
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)
if (dst >= edst)
goto overflow;
- *dst++ = (char)*(tk-1);
+ *dst++ = (char)*(tk - 1);
break;
}
}
//
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;
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;
//
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)
{
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;
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;
//
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;
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;
}
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;
//
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; ++i, ++p)
+ for(p=d; i<j; i++, p++)
{
if (*p == '\r' || *p == '\n')
{
- ++i;
+ i++;
if (*p == '\r')
{
if (i >= j)
{
- break; // Look for '\n' to eat
+ break; // Look for '\n' to eat
}
else if (p[1] == '\n')
{
- ++i;
+ i++;
}
}
}
}
- // 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;
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; i<fl->ifcnt; i++)
*d++ = *p++;
fl->ifind = fl->ifcnt & 1;
//
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:
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 = ';';
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 = '@';
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;
{
// 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");
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;)
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
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;
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;)
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;
}
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'))
// 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;
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");
+}
// 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
extern unsigned orgaddr;
extern LONG sloc;
extern int mjump_align;
+extern char * string[];
// Prototypes
int include(int, char *);
//int d_goto(WORD);
int d_goto(void);
INOBJ * a_inobj(int);
+void DumpTokenBuffer(void);
#endif // __TOKEN_H__
#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__