diff --git a/asm.cpp b/asm.cpp index 2bbe76f..cfce539 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()); } @@ -1626,7 +1635,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()) { @@ -2164,30 +2173,41 @@ void CLASS::process(void) x = 0; if (op.length() > 0) { - TMacro *mac = findMacro(op); - if (mac == NULL) + TMacro *mac = NULL; + if (macrostack.size() == 0) { - x = callOpCode(op, line); - } - else - { - expand_macrostack.push(expand_macro); - expand_macro = *mac; - - expand_macro.lines.clear(); - //printf("mac start=%u end=%u\n", expand_macro.start, expand_macro.end); - for (uint32_t lc = expand_macro.start; lc < expand_macro.end; lc++) + mac = findMacro(op); + if (mac == NULL) { - //printf("pushing %s\n", lines[lc].wholetext.c_str()); - MerlinLine nl(lines[lc].wholetext); // create a new clean line (without errors,data) - expand_macro.lines.push_back(nl); + + if (op == ">>>") // specal merlin way of calling a macro + { + mac = findMacro(operand); + } + else + { + x = callOpCode(op, line); + } + } + if (mac != NULL) + { + expand_macrostack.push(expand_macro); + expand_macro = *mac; + + expand_macro.lines.clear(); + //printf("mac start=%u end=%u\n", expand_macro.start, expand_macro.end); + for (uint32_t lc = expand_macro.start; lc < expand_macro.end; lc++) + { + //printf("pushing %s\n", lines[lc].wholetext.c_str()); + MerlinLine nl(lines[lc].wholetext); // create a new clean line (without errors,data) + expand_macro.lines.push_back(nl); + } + expand_macro.running = true; + expand_macro.sourceline = lineno; + expand_macro.variables.vars.clear(); + // set the variables for the macro here SGQ + expand_macro.currentline = 0; } - expand_macro.running = true; - expand_macro.sourceline = lineno; - expand_macro.variables.clear(); - // set the variables for the macro here SGQ - expand_macro.currentline = 0; - x = 0; } } 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..d8eb9e5 100644 --- a/psuedo.cpp +++ b/psuedo.cpp @@ -35,6 +35,14 @@ int CLASS::doDO(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) { UNUSED(opinfo); + + if (a.macrostack.size()>0) + { + // if defining a macro, do nothing with this + return(0); + } + + TEvaluator eval(a); int64_t eval_value = 0; @@ -165,6 +173,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) @@ -211,78 +223,96 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) std::string op = Poco::toUpper(line.opcode); - if (op == "LUP") + if (a.macrostack.size() == 0) // if defining a macro (size>0), don't process here { - line.flags |= FLAG_NOLINEPRINT; - len = line.lineno - 1; // MerlinLine line numbers are +1 from actual array idx - if (len >= 0) + if (op == "LUP") { - - shift = 0; - eval_value = 0; - int x = eval.evaluate(line.operand_expr, eval_value, shift); - - a.LUPstack.push(a.curLUP); - - a.curLUP.lupoffset = len; - a.curLUP.lupct = eval_value & 0xFFFF; // evaluate here - a.curLUP.luprunning++; - - if ((x < 0) || (eval_value <= 0) || (eval_value > 0x8000)) + line.flags |= FLAG_NOLINEPRINT; + len = line.lineno - 1; // MerlinLine line numbers are +1 from actual array idx + if (len >= 0) { - // merlin just ignores LUP if the value is out of range - a.curLUP.lupct = 0; - a.curLUP.lupskip = true; - } - } - else - { - err = errUnexpectedOp; - } - } - if (op == "--^") - { - line.flags |= FLAG_NOLINEPRINT; + shift = 0; + eval_value = 0; + int x = eval.evaluate(line.operand_expr, eval_value, shift); - if (a.curLUP.luprunning > 0) - { - lidx = line.lineno - 1; - len = lidx - a.curLUP.lupoffset - 1; + a.LUPstack.push(a.curLUP); - if (a.curLUP.lupct > 0) - { - a.curLUP.lupct--; - if (a.curLUP.lupct != 0) + if (a.expand_macrostack.size() > 0) { - a.lineno = a.curLUP.lupoffset; - goto out; + a.curLUP.lupoffset = a.expand_macro.currentline; } - } - // kind of a silent error here, just make sure we reinitialize - a.curLUP.luprunning = 0; - a.curLUP.lupct = 0; - a.curLUP.lupskip = false; + else + { + a.curLUP.lupoffset = len; + } + a.curLUP.lupct = eval_value & 0xFFFF; // evaluate here + a.curLUP.luprunning++; - //printf("start=%d end=%d len=%d\n", a.curLUP.lupoffset, lidx, len); - if (a.LUPstack.size() > 0) - { - a.curLUP = a.LUPstack.top(); - a.LUPstack.pop(); + if ((x < 0) || (eval_value <= 0) || (eval_value > 0x8000)) + { + // merlin just ignores LUP if the value is out of range + a.curLUP.lupct = 0; + a.curLUP.lupskip = true; + } } else { err = errUnexpectedOp; } } - else + + if (op == "--^") { - a.curLUP.lupskip = false; - // SGQ - found a '--^' without a LUP, should we just ignore? - //err = errUnexpectedOp; + line.flags |= FLAG_NOLINEPRINT; + + if (a.curLUP.luprunning > 0) + { + + + lidx = line.lineno - 1; + len = lidx - a.curLUP.lupoffset - 1; + + if (a.curLUP.lupct > 0) + { + a.curLUP.lupct--; + if (a.curLUP.lupct != 0) + { + if (a.expand_macrostack.size() > 0) + { + a.expand_macro.currentline=a.curLUP.lupoffset; + } + else + { + a.lineno = a.curLUP.lupoffset; + } + goto out; + } + } + // kind of a silent error here, just make sure we reinitialize + a.curLUP.luprunning = 0; + a.curLUP.lupct = 0; + a.curLUP.lupskip = false; + + //printf("start=%d end=%d len=%d\n", a.curLUP.lupoffset, lidx, len); + if (a.LUPstack.size() > 0) + { + a.curLUP = a.LUPstack.top(); + a.LUPstack.pop(); + } + else + { + err = errUnexpectedOp; + } + } + else + { + a.curLUP.lupskip = false; + // SGQ - found a '--^' without a LUP, should we just ignore? + //err = errUnexpectedOp; + } } } - out: if (err > 0) {