diff --git a/asm.cpp b/asm.cpp index 19ccbaa..e2c3671 100644 --- a/asm.cpp +++ b/asm.cpp @@ -1117,6 +1117,28 @@ out: return (res); } + +TMacro * CLASS::findMacro(std::string symname) +{ + TMacro *res = NULL; + + std::string sym = symname; + if (!casesen) + { + sym = Poco::toUpper(sym); + } + if (symname.length() > 0) + { + //printf("finding: %s\n",symname.c_str()); + auto itr = macros.find(sym); + if (itr != macros.end()) + { + res = &itr->second; + } + } + return (res); +} + TSymbol * CLASS::findSymbol(std::string symname) { TSymbol *res = NULL; @@ -1342,10 +1364,10 @@ int CLASS::callOpCode(std::string op, MerlinLine &line) //line.expr_value = (line.expr_value >> 16) & 0xFFFF; break; case '|': - if (syntax==SYNTAX_MERLIN) - { + if (syntax == SYNTAX_MERLIN) + { line.setError(errBadLabel); - line.expr_value=0; + line.expr_value = 0; } break; } @@ -1559,10 +1581,9 @@ void CLASS::initpass(void) truncdata = 0; variables.clear(); // clear the variables for each pass - macros.clear(); - while (!PCstack.empty()) + while (!macrostack.empty()) { - PCstack.pop(); + macrostack.pop(); } while (!LUPstack.empty()) { @@ -1576,6 +1597,11 @@ void CLASS::initpass(void) { LSTstack.pop(); } + while (!PCstack.empty()) + { + PCstack.pop(); + } + currentmacro.clear(); curLUP.clear(); curDO.clear(); } @@ -1928,6 +1954,7 @@ bool CLASS::codeSkipped(void) res = (curLUP.lupskip) ? true : res; res = (curDO.doskip) ? true : res; + res = currentmacro.running ? true : res; //printf("codeskip: %d\n",res); @@ -2050,7 +2077,15 @@ void CLASS::process(void) x = 0; if (op.length() > 0) { - x = callOpCode(op, line); + TMacro *mac=findMacro(op); + if (mac==NULL) + { + x = callOpCode(op, line); + } + else + { + x=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 5a9573c..3a4003d 100644 --- a/asm.h +++ b/asm.h @@ -352,8 +352,26 @@ public: std::string name; std::string lcname; uint32_t currentline; - std::vector lines; std::vector variables; + std::vector lines; + int32_t start,end; + bool running; + + TMacro() + { + clear(); + } + void clear(void) + { + name=""; + lcname=""; + variables.clear(); + lines.clear(); + currentline=0; + start = -1; + end=-1; + running = false; + } }; class TPsuedoOp; @@ -385,13 +403,14 @@ public: std::string currentsymstr; std::vector lines; Poco::HashMap macros; - Poco::HashMapopcodes; + Poco::HashMap opcodes; Poco::HashMap symbols; Poco::HashMap variables; TOriginSection PC; TLUPstruct curLUP; TDOstruct curDO; + TMacro currentmacro; bool listing; uint8_t truncdata; // for the TR opcode @@ -399,7 +418,7 @@ public: std::stack LUPstack; std::stack DOstack; std::stack LSTstack; - std::stack curMacro; + std::stack macrostack; TPsuedoOp *psuedoops; @@ -417,6 +436,8 @@ public: void pushopcode(std::string op, uint8_t opcode, uint16_t flags, TOpCallback cb); int callOpCode(std::string op, MerlinLine &line); + TMacro *findMacro(std::string sym); + TSymbol *findSymbol(std::string sym); TSymbol *addSymbol(std::string sym, uint32_t val, bool replace); TSymbol *findVariable(std::string sym); diff --git a/opcodes.cpp b/opcodes.cpp index 72a8cb1..8c22620 100644 --- a/opcodes.cpp +++ b/opcodes.cpp @@ -885,9 +885,9 @@ void CLASS::insertOpcodes(void) pushopcode("SW", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("USR", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("XC", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doXC)); - pushopcode("MAC", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); - pushopcode("EOM", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); - pushopcode("<<<", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); + 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("ADC", 0x03, OP_STD | OP_A, OPHANDLER(&CLASS::doBase6502)); diff --git a/psuedo.cpp b/psuedo.cpp index bd6c4fa..0dd5f2f 100644 --- a/psuedo.cpp +++ b/psuedo.cpp @@ -130,6 +130,68 @@ out: return (res); } +int CLASS::doMAC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) +{ + UNUSED(opinfo); + + int res = 0; + int err = 0; + + std::string op = Poco::toUpper(line.opcode); + if (op == "MAC") + { + if (a.currentmacro.running) + { + err=errUnexpectedOp; + goto out; + } + if (line.lable.length()==0) + { + err=errBadLabel; + goto out; + } + a.macrostack.push(a.currentmacro); + a.currentmacro.clear(); + + a.currentmacro.name=line.lable; + a.currentmacro.lcname=Poco::toLower(line.lable); + a.currentmacro.start=line.lineno+1; + a.currentmacro.running=true; + if (a.pass == 0) + { + } + else + { + // don't need to do anything on pass > 0 + } + } + else // it is EOM or <<< + { + if (a.macrostack.size() > 0) + { + a.currentmacro.end=line.lineno; + a.currentmacro.running=false; + + std::pair p(a.currentmacro.name, a.currentmacro); + a.macros.insert(p); + + a.currentmacro = a.macrostack.top(); + a.macrostack.pop(); + } + else + { + err = errUnexpectedOp; + goto out; + } + } +out: + if (err) + { + line.setError(err); + } + return (res); +} + int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) { UNUSED(opinfo); @@ -340,6 +402,8 @@ int CLASS::doDATA(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) return (outct); } + + int CLASS::doDS(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) { UNUSED(opinfo); @@ -352,7 +416,7 @@ int CLASS::doDS(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) uint8_t shift; line.eval_result = 0; // since this is an data p-op, clear the global 'bad operand' flag - line.flags|=FLAG_FORCEADDRPRINT; + line.flags |= FLAG_FORCEADDRPRINT; std::string s; Poco::StringTokenizer tok(line.operand, ",", Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY); @@ -418,11 +482,11 @@ int CLASS::doDS(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) v = datact; if (pagefill) { - v=line.startpc&0xFF; - v=0x100-v; + v = line.startpc & 0xFF; + v = 0x100 - v; } line.datafillct = (uint16_t)v & 0xFFFF; - res=line.datafillct; + res = line.datafillct; out: //printf("res=%d %04X\n",res,res); @@ -842,12 +906,12 @@ int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) #if 0 // Merlin32 seems to have a bug where ORG seems like it can only be 16 bits - if ((line.syntax&SYNTAX_MERLIN32)==SYNTAX_MERLIN32) + if ((line.syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32) { // so clear the bank word in all variables a.PC.orgsave &= 0xFFFF; - a.PC.currentpc&=0xFFFF; - line.startpc &=0xFFFF; + a.PC.currentpc &= 0xFFFF; + line.startpc &= 0xFFFF; } #endif @@ -856,16 +920,19 @@ int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) case P_SAV: a.savepath = a.processFilename(line.operand, Poco::Path::current(), 0); break; + case P_MAC: + res = doMAC(a, line, opinfo); + break; case P_ERR: - if (a.pass>0) + if (a.pass > 0) { - if ((line.expr_value!=0) || (line.eval_result<0)) + if ((line.expr_value != 0) || (line.eval_result < 0)) { line.setError(errErrOpcode); //a.passcomplete=true; // terminate assembly } } - res=0; + res = 0; break; case P_LST: res = doLST(a, line, opinfo); diff --git a/psuedo.h b/psuedo.h index 94edb92..bf86c28 100644 --- a/psuedo.h +++ b/psuedo.h @@ -20,6 +20,7 @@ enum P_TR, P_ASC, P_ERR, + P_MAC, P_MAX }; @@ -41,6 +42,8 @@ public: int doDO(T65816Asm &a, MerlinLine &line, TSymbol &opinfo); int doTR(T65816Asm &a, MerlinLine &line, TSymbol &opinfo); int doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo); + int doMAC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo); + }; #undef CLASS \ No newline at end of file