diff --git a/asm.cpp b/asm.cpp index 2bbe76f..85cc331 100644 --- a/asm.cpp +++ b/asm.cpp @@ -1191,7 +1191,7 @@ out: return (res); } -TSymbol * CLASS::addVariable(std::string symname, std::string val, variable_t &vars, bool replace) +TSymbol * CLASS::addVariable(std::string symname, std::string val, TVariable &vars, bool replace) { TSymbol *res = NULL; TSymbol *fnd = NULL; @@ -1230,18 +1230,27 @@ TSymbol * CLASS::addVariable(std::string symname, std::string val, variable_t &v //printf("addvariable: %s %s\n", s.name.c_str(), s.text.c_str()); std::pair p(sym, s); - vars.insert(p); + vars.vars.insert(p); res = findVariable(sym, vars); return (res); } -TSymbol * CLASS::findVariable(std::string symname, variable_t &vars) +TSymbol * CLASS::findVariable(std::string symname, TVariable &vars) { TSymbol *res = NULL; + if ((expand_macrostack.size() > 0) && (vars.id != expand_macro.variables.id)) + { + res = findVariable(symname, expand_macro.variables); + if (res != NULL) + { + return (res); + } + } + //printf("finding: %s\n",symname.c_str()); - auto itr = vars.find(symname); - if (itr != vars.end()) + auto itr = vars.vars.find(symname); + if (itr != vars.vars.end()) { //printf("Found: %s 0x%08X\n",itr->second.name.c_str(),itr->second.value); res = &itr->second; @@ -1251,13 +1260,13 @@ TSymbol * CLASS::findVariable(std::string symname, variable_t &vars) return (res); } -void CLASS::showVariables(variable_t &vars) +void CLASS::showVariables(TVariable &vars) { - if (variables.size() > 0) + if (vars.vars.size() > 0) { printf("\nVariables:\n"); - for (auto itr = vars.begin(); itr != vars.end(); ++itr) + for (auto itr = vars.vars.begin(); itr != vars.vars.end(); ++itr) { printf("%-16s %s\n", itr->first.c_str(), itr->second.var_text.c_str()); } @@ -1362,6 +1371,17 @@ int CLASS::callOpCode(std::string op, MerlinLine &line) char c; std::string s; +// during MACRO definition no opcodes are called (except for MAC, EOM, <<) + if (macrostack.size() > 0) + { + // if something on the macro stack, then a macro is being defined + std::string upop = Poco::toUpper(op); + if (!((upop == "MAC") || (upop == "EOM") || (upop == "<<<"))) + { + return 0; + } + } + if (op.length() == 4) // check for 4 digit 'L' opcodes { c = op[3] & 0x7F; @@ -1626,7 +1646,7 @@ void CLASS::initpass(void) dumstartaddr = 0; dumstart = 0; truncdata = 0; - variables.clear(); // clear the variables for each pass + variables.vars.clear(); // clear the variables for each pass while (!macrostack.empty()) { @@ -1957,7 +1977,16 @@ restart: off = mVec[0].offset; len = mVec[0].length; s = oper.substr(off, len); - sym = findVariable(s, variables); + + sym = NULL; + if (expand_macrostack.size() > 0) + { + sym = findVariable(s, expand_macro.variables); + } + if (sym == NULL) + { + sym = findVariable(s, variables); + } if (sym != NULL) { //printf("match |%s|\n",sym->var_text.c_str()); @@ -1992,7 +2021,7 @@ restart: done = true; } } - //printf("inoper=|%s| outoper=|%s|\n",operin.c_str(),oper.c_str()); +//printf("inoper=|%s| outoper=|%s|\n",operin.c_str(),oper.c_str()); if (ct > 0) { outop = oper; @@ -2139,6 +2168,7 @@ void CLASS::process(void) x = substituteVariables(line, outop); if (x > 0) { + line.printoperand = outop; line.operand = outop; } x = parseOperand(line); @@ -2164,12 +2194,29 @@ void CLASS::process(void) x = 0; if (op.length() > 0) { - TMacro *mac = findMacro(op); + TMacro *mac = NULL; + bool inoperand = false; + mac = findMacro(op); + if (mac == NULL) + { + if (op == ">>>") // specal merlin way of calling a macro + { + Poco::StringTokenizer tok(operand, ", ", Poco::StringTokenizer::TOK_TRIM | + Poco::StringTokenizer::TOK_IGNORE_EMPTY); + std::string s=""; + if (tok.count()>0) + { + s=tok[0]; + } + mac = findMacro(s); + inoperand = true; + } + } if (mac == NULL) { x = callOpCode(op, line); } - else + if (mac != NULL) { expand_macrostack.push(expand_macro); expand_macro = *mac; @@ -2184,11 +2231,37 @@ void CLASS::process(void) } expand_macro.running = true; expand_macro.sourceline = lineno; - expand_macro.variables.clear(); + expand_macro.variables.vars.clear(); // set the variables for the macro here SGQ - expand_macro.currentline = 0; + + std::string parms = line.operand; + if (inoperand) + { + Poco::StringTokenizer tok(parms, ", ", Poco::StringTokenizer::TOK_TRIM | + Poco::StringTokenizer::TOK_IGNORE_EMPTY); + parms = ""; + if (tok.count() > 1) + { + parms = tok[1]; + } + } + Poco::StringTokenizer tok(parms, ",;", Poco::StringTokenizer::TOK_TRIM | + Poco::StringTokenizer::TOK_IGNORE_EMPTY); + + uint32_t ct = 0; + for (auto itr = tok.begin(); itr != tok.end(); ++itr) + { + //evaluate each of these strings, check for errors on pass 2 + std::string expr = *itr; + std::string v = "]" + Poco::NumberFormatter::format(ct + 1); + //printf("var: %s %s\n", v.c_str(), expr.c_str()); + addVariable(v, expr, expand_macro.variables, true); + ct++; + } x = 0; + expand_macro.currentline = 0; } + //} } if ((x > 0) && (codeSkipped())) // has a psuedo-op turned off code generation? (LUP, IF, etc) diff --git a/asm.h b/asm.h index 6565c8e..338d5c2 100644 --- a/asm.h +++ b/asm.h @@ -347,16 +347,28 @@ public: } }; -typedef Poco::HashMap variable_t; +//typedef Poco::HashMap variable_t; + +class TVariable +{ +public: + uint32_t id; + Poco::HashMap vars; + TVariable() + { + // SGQ - must fix this so it is guaranteed unique for each one + id=rand(); + } +}; class TMacro { public: std::string name; std::string lcname; - variable_t variables; + TVariable variables; std::vector lines; - uint32_t start,end,currentline,len; + uint32_t start, end, currentline, len; uint32_t sourceline; bool running; @@ -366,15 +378,15 @@ public: } void clear(void) { - name=""; - lcname=""; - variables.clear(); + name = ""; + lcname = ""; + variables.vars.clear(); lines.clear(); - sourceline=0; - currentline=0; - len=0; + sourceline = 0; + currentline = 0; + len = 0; start = 0; - end=0; + end = 0; running = false; } }; @@ -410,7 +422,7 @@ public: Poco::HashMap macros; Poco::HashMap opcodes; Poco::HashMap symbols; - variable_t variables; + TVariable variables; TOriginSection PC; TLUPstruct curLUP; @@ -447,15 +459,15 @@ public: TSymbol *findSymbol(std::string sym); TSymbol *addSymbol(std::string sym, uint32_t val, bool replace); - TSymbol *findVariable(std::string sym, variable_t &vars); - TSymbol *addVariable(std::string sym, std::string val, variable_t &vars,bool replace); + TSymbol *findVariable(std::string sym, TVariable &vars); + TSymbol *addVariable(std::string sym, std::string val, TVariable &vars, bool replace); void initpass(void); void showSymbolTable(bool alpha); void showMacros(bool alpha); - void showVariables(variable_t &vars); + void showVariables(TVariable &vars); int evaluate(MerlinLine &line, std::string expr, int64_t &value); int substituteVariables(MerlinLine & line, std::string &outop); diff --git a/opcodes.cpp b/opcodes.cpp index 6909fb2..e77cea7 100644 --- a/opcodes.cpp +++ b/opcodes.cpp @@ -888,6 +888,7 @@ void CLASS::insertOpcodes(void) pushopcode("MAC", P_MAC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("EOM", P_MAC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("<<<", P_MAC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); + pushopcode(">>>", P_MAC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("ADC", 0x03, OP_STD | OP_A, OPHANDLER(&CLASS::doBase6502)); diff --git a/psuedo.cpp b/psuedo.cpp index e8d4a45..9f17d6d 100644 --- a/psuedo.cpp +++ b/psuedo.cpp @@ -165,6 +165,10 @@ int CLASS::doMAC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) // don't need to do anything on pass > 0 } } + else if (op == ">>>") + { + // don't do anything here, let the macro call handler stuff do ths (asm.cpp) + } else // it is EOM or <<< { if (a.macrostack.size() > 0) @@ -224,7 +228,14 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) a.LUPstack.push(a.curLUP); - a.curLUP.lupoffset = len; + if (a.expand_macrostack.size() > 0) + { + a.curLUP.lupoffset = a.expand_macro.currentline; + } + else + { + a.curLUP.lupoffset = len; + } a.curLUP.lupct = eval_value & 0xFFFF; // evaluate here a.curLUP.luprunning++; @@ -247,6 +258,8 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) if (a.curLUP.luprunning > 0) { + + lidx = line.lineno - 1; len = lidx - a.curLUP.lupoffset - 1; @@ -255,7 +268,14 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) a.curLUP.lupct--; if (a.curLUP.lupct != 0) { - a.lineno = a.curLUP.lupoffset; + if (a.expand_macrostack.size() > 0) + { + a.expand_macro.currentline = a.curLUP.lupoffset; + } + else + { + a.lineno = a.curLUP.lupoffset; + } goto out; } } @@ -282,7 +302,6 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) //err = errUnexpectedOp; } } - out: if (err > 0) {