start of macro code

This commit is contained in:
marketideas 2019-11-20 21:50:00 -08:00
parent 0b8a9dfae4
commit e2203ca1d3
5 changed files with 149 additions and 23 deletions

49
asm.cpp
View File

@ -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)

27
asm.h
View File

@ -352,8 +352,26 @@ public:
std::string name;
std::string lcname;
uint32_t currentline;
std::vector<MerlinLine> lines;
std::vector<std::string> variables;
std::vector<MerlinLine> 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<MerlinLine> lines;
Poco::HashMap<std::string, TMacro> macros;
Poco::HashMap<std::string, TSymbol>opcodes;
Poco::HashMap<std::string, TSymbol> opcodes;
Poco::HashMap<std::string, TSymbol> symbols;
Poco::HashMap<std::string, TSymbol> 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<TLUPstruct> LUPstack;
std::stack<TDOstruct> DOstack;
std::stack<bool> LSTstack;
std::stack<TMacro> curMacro;
std::stack<TMacro> 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);

View File

@ -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));

View File

@ -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<std::string, TMacro> 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);

View File

@ -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