This commit is contained in:
marketideas
2019-11-16 09:27:24 -08:00
parent fe34518911
commit 568c09b91e
5 changed files with 208 additions and 27 deletions
+48 -3
View File
@@ -34,6 +34,8 @@ void CLASS::print(uint32_t lineno)
uint32_t b = 4; // how many bytes show on the first line
bool merlinstyle=true;
if (datafillct > 0)
{
l = datafillct;
@@ -46,7 +48,25 @@ void CLASS::print(uint32_t lineno)
{
l = b;
}
if (errorcode > 0)
{
if (merlinstyle)
{
//printf("errorcode=%d\n",errorcode);
printf("%s in line: %d", errStrings[errorcode].c_str(), lineno+1);
if (errorText != "")
{
printf("%s", errorText.c_str());
}
printf("\n");
}
flags &= (~FLAG_NOLINEPRINT);
}
if (flags & FLAG_NOLINEPRINT)
{
return;
}
if (!checked)
{
nc1 = getBool("option.nocolor", false);
@@ -57,7 +77,7 @@ void CLASS::print(uint32_t lineno)
nc = nc1;
}
if (!isatty(STDOUT_FILENO))
if ((!isatty(STDOUT_FILENO)) || (merlinstyle))
{
nc = true;
}
@@ -158,7 +178,7 @@ void CLASS::print(uint32_t lineno)
{
pcol += printf("%-12s %-8s %-10s ", printlable.c_str(), opcode.c_str(), operand.c_str());
}
if (errorcode > 0)
if ((errorcode > 0) && (!merlinstyle))
{
while (pcol < commentcol)
{
@@ -1229,6 +1249,7 @@ void CLASS::initpass(void)
allowdup = getBool("asm.allowduplicate", true);
skiplist = false;
generateCode = true;
PC.origin = 0x8000;
PC.currentpc = PC.origin;
@@ -1278,7 +1299,12 @@ void CLASS::initpass(void)
{
LUPstack.pop();
}
while (!DOstack.empty())
{
DOstack.pop();
}
curLUP.clear();
curDO.clear();
savepath = "";
}
@@ -1315,7 +1341,7 @@ void CLASS::complete(void)
}
}
printf("\n\nEnd qASM assembly, %d bytes, %u errors, %lu lines, %lu symbols.\n", PC.totalbytes, errorct,lines.size(),symbols.size());
printf("\n\nEnd qASM assembly, %d bytes, %u errors, %lu lines, %lu symbols.\n", PC.totalbytes, errorct, lines.size(), symbols.size());
TFileProcessor::complete();
@@ -1557,6 +1583,18 @@ int CLASS::substituteVariables(MerlinLine & line)
return (res);
}
bool CLASS::codeSkipped(void)
{
bool res = false;
if (curLUP.lupskip)
{
res = true;
}
return (res);
}
void CLASS::process(void)
{
uint32_t l;
@@ -1649,6 +1687,11 @@ void CLASS::process(void)
x = callOpCode(op, line);
}
if ((x > 0) && (codeSkipped())) // has a psuedo-op turned off code generation? (LUP, IF, etc)
{
x = 0;
}
if (x > 0)
{
if (!PCstack.empty()) // are we inside a DUM section?
@@ -1707,6 +1750,7 @@ void CLASS::process(void)
// end of file reached here, do some final checks
#if 0
if (LUPstack.size() > 0)
{
errLine.clear();
@@ -1714,6 +1758,7 @@ void CLASS::process(void)
errLine.print(lineno);
pass = 2;
}
#endif
pass++;
}
+33 -6
View File
@@ -19,6 +19,7 @@
#define FLAG_INDUM 0x20
#define FLAG_FORCEADDRPRINT 0x0100
#define FLAG_NOLINEPRINT 0x2000
#define OP_A 0x0001
#define OP_XY 0x0002
@@ -50,7 +51,6 @@ enum asmErrors
errBadBranch,
errForwardRef,
errNoRedefinition,
errBadOperand,
errDupSymbol,
errBadDUMop,
errOverflow,
@@ -60,11 +60,13 @@ enum asmErrors
errFileNotFound,
errFileNoAccess,
errBadEvaluation,
errMalformed,
errIllegalCharOperand,
errBadCharacter,
errUnexpectedOp,
errUnexpectedEOF,
errBadLUPOperand,
errBadLabel,
errBadOperand,
errMAX
};
@@ -83,7 +85,6 @@ const std::string errStrings[errMAX + 1] =
"Relative branch offset too large",
"Forward Reference to symbol",
"Unable to redefine symbol",
"Error in expression",
"Duplicate Symbol",
"Invalid use of DUM/DEND",
"Overflow detected",
@@ -93,11 +94,13 @@ const std::string errStrings[errMAX + 1] =
"File not found",
"File no access",
"Unable to evaluate",
"Malformed Operand",
"Illegal char in operand",
"Unexpected character in input",
"Unexpected opcode",
"Unexpected End of File",
"LUP value must be 0 < VAL <= $8000"
"LUP value must be 0 < VAL <= $8000",
"Unknown label",
"Bad operand",
""
};
@@ -263,12 +266,29 @@ public:
lupct=0;
lupoffset=0;
luprunning=0;
lupskip=false;
}
uint16_t lupct;
bool lupskip;
uint32_t lupoffset;
uint16_t luprunning;
};
class TDOstruct
{
public:
TDOstruct()
{
clear();
}
void clear(void) {
dooff=false;
value=0;
}
uint32_t value;
bool dooff;
};
class TSymbol;
typedef int (*TOpCB)(MerlinLine &line, TSymbol &sym);
typedef std::function<int (MerlinLine &line, TSymbol &sym)> TOpCallback;
@@ -325,6 +345,8 @@ public:
bool skiplist; // used if lst is on, but LST opcode turns it off
uint32_t lineno;
bool generateCode;
std::string savepath;
TSymbol *currentsym;
std::vector<MerlinLine> lines;
@@ -334,9 +356,12 @@ public:
Poco::HashMap<std::string, TSymbol> variables;
TOriginSection PC;
TLUPstruct curLUP;
TDOstruct curDO;
std::stack<TOriginSection> PCstack;
std::stack<TLUPstruct> LUPstack;
TLUPstruct curLUP;
std::stack<TDOstruct> DOstack;
TPsuedoOp *psuedoops;
@@ -366,6 +391,8 @@ public:
int evaluate(MerlinLine &line, std::string expr, int64_t &value);
int substituteVariables(MerlinLine & line);
bool codeSkipped(void);
int parseOperand(MerlinLine &line);
int getAddrMode(MerlinLine &line);
void setOpcode(MerlinLine &line, uint8_t op);
+4 -4
View File
@@ -754,10 +754,10 @@ void CLASS::insertOpcodes(void)
pushopcode("ADRL",P_DATA, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("HEX", P_HEX, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DS", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DO", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ELSE", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("IF", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("FIN", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DO", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ELSE",P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("IF", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("FIN", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("CHK", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ERR", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("KBD", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
+120 -14
View File
@@ -13,6 +13,94 @@ CLASS::~CLASS()
}
int CLASS::doDO(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
{
UNUSED(opinfo);
TEvaluator eval(a);
int64_t eval_result = 0;
uint8_t shift;
int res = 0;
int err = 0;
std::string op = Poco::toUpper(line.opcode);
std::string oper = Poco::toUpper(line.operand);
if (op == "IF")
{
if (oper == "")
{
err = errIllegalCharOperand;
}
goto out;
}
if (op == "DO")
{
if (oper == "")
{
err = errIllegalCharOperand;
goto out;
}
//line.flags |= FLAG_NOLINEPRINT;
shift = 0;
eval_result = 0;
int x = eval.evaluate(line.operand, eval_result, shift);
a.curDO.dooff = (eval_result & 0xFFFFFF); // evaluate here
if (x < 0)
{
a.curDO.dooff = false;
err = errBadLabel;
if (a.pass == 0)
{
err = errForwardRef;
}
}
a.DOstack.push(a.curDO);
goto out;
}
if (op == "ELSE")
{
//line.flags |= FLAG_NOLINEPRINT;
a.curDO.dooff = !a.curDO.dooff;
goto out;
}
if (op == "FIN")
{
//line.flags |= FLAG_NOLINEPRINT;
if (a.DOstack.size() > 0)
{
// kind of a silent error here, just make sure we reinitialize
a.curDO.dooff = false;
a.curDO = a.DOstack.top();
a.DOstack.pop();
}
else
{
// kind of a silent error here, just make sure we reinitialize
a.curDO.dooff = false;
}
goto out;
}
out:
if (err > 0)
{
line.setError(err);
}
return (res);
}
int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
{
UNUSED(opinfo);
@@ -29,6 +117,7 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
if (op == "LUP")
{
line.flags |= FLAG_NOLINEPRINT;
len = line.lineno - 1; // MerlinLine line numbers are +1 from actual array idx
if (len >= 0)
{
@@ -36,19 +125,19 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
shift = 0;
eval_result = 0;
int x = eval.evaluate(line.operand, eval_result, shift);
if ((x < 0) || (eval_result<=0) || (eval_result>0x8000))
{
// merlin just ignores LUP if the value is out of range
a.curLUP.lupct=0;
goto out;
}
a.LUPstack.push(a.curLUP);
a.curLUP.lupoffset = len;
a.curLUP.lupct = eval_result&0xFF; // evaluate here
a.curLUP.lupct = eval_result & 0xFFFF; // evaluate here
a.curLUP.luprunning++;
if ((x < 0) || (eval_result <= 0) || (eval_result > 0x8000))
{
// merlin just ignores LUP if the value is out of range
a.curLUP.lupct = 0;
a.curLUP.lupskip = true;
}
}
else
{
@@ -58,6 +147,8 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
if (op == "--^")
{
line.flags |= FLAG_NOLINEPRINT;
if (a.curLUP.luprunning > 0)
{
lidx = line.lineno - 1;
@@ -73,8 +164,9 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
}
}
// kind of a silent error here, just make sure we reinitialize
a.curLUP.luprunning=0;
a.curLUP.lupct=0;
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)
@@ -89,6 +181,7 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
}
else
{
a.curLUP.lupskip = false;
// SGQ - found a '--^' without a LUP, should we just ignore?
//err = errUnexpectedOp;
}
@@ -305,6 +398,14 @@ int CLASS::doHEX(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
uint32_t bytect = 0;
uint8_t b = 0;
uint8_t ct = 0;
if (os.length() == 0)
{
// case where HEX has no operand, Merlin does not flag as error
//line.setError(errIllegalCharOperand);
bytect = 0;
goto out;
}
for ( uint32_t i = 0; i < os.length(); ++i )
{
char c = os[i];
@@ -327,8 +428,9 @@ int CLASS::doHEX(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
}
else
{
line.setError(errBadCharacter);
return 0;
line.setError(errIllegalCharOperand);
bytect = 0;
goto out;
}
// Got a good char, append to hex string and see if we've got a byte
@@ -354,9 +456,10 @@ int CLASS::doHEX(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
}
if (ct & 0x01) // we got an odd number of nibbles
{
line.setError(errMalformed);
line.setError(errBadOperand);
bytect = 0;
}
out:
line.outbytect = bytect;
return bytect;
}
@@ -414,8 +517,11 @@ int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
break;
case P_LUP:
res = doLUP(a, line, opinfo);
res = 0;
break;
case P_DO:
res = doDO(a, line, opinfo);
break;
}
return (res);
}
+3
View File
@@ -16,6 +16,7 @@ enum
P_HEX,
P_DATA,
P_LUP,
P_DO,
P_MAX
};
@@ -32,6 +33,8 @@ public:
int doHEX(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);
int doDATA(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);
int doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);
int doDO(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);;
};