mirror of
https://github.com/marketideas/qasm.git
synced 2024-12-28 06:29:58 +00:00
Merge branch 'sgq_qasm_main' of https://github.com/marketideas/qasm
This commit is contained in:
commit
df8c9ef7d3
74
asm.cpp
74
asm.cpp
@ -34,6 +34,8 @@ void CLASS::print(uint32_t lineno)
|
|||||||
|
|
||||||
uint32_t b = 4; // how many bytes show on the first line
|
uint32_t b = 4; // how many bytes show on the first line
|
||||||
|
|
||||||
|
bool merlinstyle=true;
|
||||||
|
|
||||||
if (datafillct > 0)
|
if (datafillct > 0)
|
||||||
{
|
{
|
||||||
l = datafillct;
|
l = datafillct;
|
||||||
@ -46,7 +48,25 @@ void CLASS::print(uint32_t lineno)
|
|||||||
{
|
{
|
||||||
l = b;
|
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)
|
if (!checked)
|
||||||
{
|
{
|
||||||
nc1 = getBool("option.nocolor", false);
|
nc1 = getBool("option.nocolor", false);
|
||||||
@ -57,7 +77,7 @@ void CLASS::print(uint32_t lineno)
|
|||||||
nc = nc1;
|
nc = nc1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isatty(STDOUT_FILENO))
|
if ((!isatty(STDOUT_FILENO)) || (merlinstyle))
|
||||||
{
|
{
|
||||||
nc = true;
|
nc = true;
|
||||||
}
|
}
|
||||||
@ -87,7 +107,12 @@ void CLASS::print(uint32_t lineno)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pcol = 0;
|
pcol = 0;
|
||||||
if (!empty)
|
|
||||||
|
bool saddr = flags & FLAG_FORCEADDRPRINT;
|
||||||
|
saddr = (outbytect > 0) ? true : saddr;
|
||||||
|
saddr = (printlable != "") ? true : saddr;
|
||||||
|
|
||||||
|
if (saddr)
|
||||||
{
|
{
|
||||||
pcol += printf("%02X/%04X:", (startpc >> 16), startpc & 0xFFFF);
|
pcol += printf("%02X/%04X:", (startpc >> 16), startpc & 0xFFFF);
|
||||||
}
|
}
|
||||||
@ -143,14 +168,17 @@ void CLASS::print(uint32_t lineno)
|
|||||||
pcol += printf(" ");
|
pcol += printf(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//pcol += printf("%s", comment.c_str());
|
else
|
||||||
|
{
|
||||||
|
pcol += printf("%s", comment.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pcol += printf("%-12s %-8s %-10s ", printlable.c_str(), opcode.c_str(), operand.c_str());
|
pcol += printf("%-12s %-8s %-10s ", printlable.c_str(), opcode.c_str(), operand.c_str());
|
||||||
}
|
}
|
||||||
if (errorcode > 0)
|
if ((errorcode > 0) && (!merlinstyle))
|
||||||
{
|
{
|
||||||
while (pcol < commentcol)
|
while (pcol < commentcol)
|
||||||
{
|
{
|
||||||
@ -456,12 +484,12 @@ void CLASS::complete(void)
|
|||||||
{
|
{
|
||||||
|
|
||||||
uint64_t n = GetTickCount();
|
uint64_t n = GetTickCount();
|
||||||
if (isDebug())
|
//if (isDebug())
|
||||||
{
|
{
|
||||||
//cout << "Processing Time: " << n - starttime << "ms" << endl;
|
//cout << "Processing Time: " << n - starttime << "ms" << endl;
|
||||||
uint64_t x = n - starttime;
|
uint64_t x = n - starttime;
|
||||||
uint32_t x1 = x & 0xFFFFFFFF;
|
uint32_t x1 = x & 0xFFFFFFFF;
|
||||||
printf("Processing Time: %u ms\n", x1);
|
printf("Elapsed time: %u ms\n", x1);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -606,7 +634,7 @@ int CLASS::processfile(std::string p, std::string &newfilename)
|
|||||||
{
|
{
|
||||||
// is this the first file in the compilation, or a PUT/USE?
|
// is this the first file in the compilation, or a PUT/USE?
|
||||||
// if first, change CWD to location of file
|
// if first, change CWD to location of file
|
||||||
LOG_DEBUG << "Changing directory to: " << dir << endl;
|
//LOG_DEBUG << "Changing directory to: " << dir << endl;
|
||||||
if (chdir(dir.c_str())) {} // change directory to where the file is
|
if (chdir(dir.c_str())) {} // change directory to where the file is
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1221,6 +1249,7 @@ void CLASS::initpass(void)
|
|||||||
allowdup = getBool("asm.allowduplicate", true);
|
allowdup = getBool("asm.allowduplicate", true);
|
||||||
|
|
||||||
skiplist = false;
|
skiplist = false;
|
||||||
|
generateCode = true;
|
||||||
|
|
||||||
PC.origin = 0x8000;
|
PC.origin = 0x8000;
|
||||||
PC.currentpc = PC.origin;
|
PC.currentpc = PC.origin;
|
||||||
@ -1270,14 +1299,17 @@ void CLASS::initpass(void)
|
|||||||
{
|
{
|
||||||
LUPstack.pop();
|
LUPstack.pop();
|
||||||
}
|
}
|
||||||
|
while (!DOstack.empty())
|
||||||
|
{
|
||||||
|
DOstack.pop();
|
||||||
|
}
|
||||||
curLUP.clear();
|
curLUP.clear();
|
||||||
|
curDO.clear();
|
||||||
savepath = "";
|
savepath = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLASS::complete(void)
|
void CLASS::complete(void)
|
||||||
{
|
{
|
||||||
printf("\n\n=== Assembly Complete: %d bytes %u errors.\n", PC.totalbytes, errorct);
|
|
||||||
|
|
||||||
if (savepath != "")
|
if (savepath != "")
|
||||||
{
|
{
|
||||||
if (errorct == 0)
|
if (errorct == 0)
|
||||||
@ -1309,13 +1341,16 @@ 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());
|
||||||
|
|
||||||
|
TFileProcessor::complete();
|
||||||
|
|
||||||
if (listing)
|
if (listing)
|
||||||
{
|
{
|
||||||
showSymbolTable(true);
|
showSymbolTable(true);
|
||||||
showSymbolTable(false);
|
showSymbolTable(false);
|
||||||
showVariables();
|
showVariables();
|
||||||
}
|
}
|
||||||
TFileProcessor::complete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CLASS::evaluate(MerlinLine &line, std::string expr, int64_t &value)
|
int CLASS::evaluate(MerlinLine &line, std::string expr, int64_t &value)
|
||||||
@ -1548,6 +1583,18 @@ int CLASS::substituteVariables(MerlinLine & line)
|
|||||||
return (res);
|
return (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CLASS::codeSkipped(void)
|
||||||
|
{
|
||||||
|
bool res = false;
|
||||||
|
|
||||||
|
if (curLUP.lupskip)
|
||||||
|
{
|
||||||
|
res = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
|
||||||
void CLASS::process(void)
|
void CLASS::process(void)
|
||||||
{
|
{
|
||||||
uint32_t l;
|
uint32_t l;
|
||||||
@ -1640,6 +1687,11 @@ void CLASS::process(void)
|
|||||||
x = callOpCode(op, line);
|
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 (x > 0)
|
||||||
{
|
{
|
||||||
if (!PCstack.empty()) // are we inside a DUM section?
|
if (!PCstack.empty()) // are we inside a DUM section?
|
||||||
@ -1698,6 +1750,7 @@ void CLASS::process(void)
|
|||||||
|
|
||||||
// end of file reached here, do some final checks
|
// end of file reached here, do some final checks
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (LUPstack.size() > 0)
|
if (LUPstack.size() > 0)
|
||||||
{
|
{
|
||||||
errLine.clear();
|
errLine.clear();
|
||||||
@ -1705,6 +1758,7 @@ void CLASS::process(void)
|
|||||||
errLine.print(lineno);
|
errLine.print(lineno);
|
||||||
pass = 2;
|
pass = 2;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
pass++;
|
pass++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
40
asm.h
40
asm.h
@ -18,6 +18,8 @@
|
|||||||
#define FLAG_BIGNUM 0x10
|
#define FLAG_BIGNUM 0x10
|
||||||
#define FLAG_INDUM 0x20
|
#define FLAG_INDUM 0x20
|
||||||
|
|
||||||
|
#define FLAG_FORCEADDRPRINT 0x0100
|
||||||
|
#define FLAG_NOLINEPRINT 0x2000
|
||||||
|
|
||||||
#define OP_A 0x0001
|
#define OP_A 0x0001
|
||||||
#define OP_XY 0x0002
|
#define OP_XY 0x0002
|
||||||
@ -49,7 +51,6 @@ enum asmErrors
|
|||||||
errBadBranch,
|
errBadBranch,
|
||||||
errForwardRef,
|
errForwardRef,
|
||||||
errNoRedefinition,
|
errNoRedefinition,
|
||||||
errBadOperand,
|
|
||||||
errDupSymbol,
|
errDupSymbol,
|
||||||
errBadDUMop,
|
errBadDUMop,
|
||||||
errOverflow,
|
errOverflow,
|
||||||
@ -59,10 +60,13 @@ enum asmErrors
|
|||||||
errFileNotFound,
|
errFileNotFound,
|
||||||
errFileNoAccess,
|
errFileNoAccess,
|
||||||
errBadEvaluation,
|
errBadEvaluation,
|
||||||
errMalformed,
|
errIllegalCharOperand,
|
||||||
errBadCharacter,
|
errBadCharacter,
|
||||||
errUnexpectedOp,
|
errUnexpectedOp,
|
||||||
errUnexpectedEOF,
|
errUnexpectedEOF,
|
||||||
|
errBadLUPOperand,
|
||||||
|
errBadLabel,
|
||||||
|
errBadOperand,
|
||||||
errMAX
|
errMAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -81,7 +85,6 @@ const std::string errStrings[errMAX + 1] =
|
|||||||
"Relative branch offset too large",
|
"Relative branch offset too large",
|
||||||
"Forward Reference to symbol",
|
"Forward Reference to symbol",
|
||||||
"Unable to redefine symbol",
|
"Unable to redefine symbol",
|
||||||
"Error in expression",
|
|
||||||
"Duplicate Symbol",
|
"Duplicate Symbol",
|
||||||
"Invalid use of DUM/DEND",
|
"Invalid use of DUM/DEND",
|
||||||
"Overflow detected",
|
"Overflow detected",
|
||||||
@ -91,10 +94,13 @@ const std::string errStrings[errMAX + 1] =
|
|||||||
"File not found",
|
"File not found",
|
||||||
"File no access",
|
"File no access",
|
||||||
"Unable to evaluate",
|
"Unable to evaluate",
|
||||||
"Malformed Operand",
|
"Illegal char in operand",
|
||||||
"Unexpected character in input",
|
"Unexpected character in input",
|
||||||
"Unexpected opcode",
|
"Unexpected opcode",
|
||||||
"Unexpected End of File",
|
"Unexpected End of File",
|
||||||
|
"LUP value must be 0 < VAL <= $8000",
|
||||||
|
"Unknown label",
|
||||||
|
"Bad operand",
|
||||||
|
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
@ -260,12 +266,29 @@ public:
|
|||||||
lupct=0;
|
lupct=0;
|
||||||
lupoffset=0;
|
lupoffset=0;
|
||||||
luprunning=0;
|
luprunning=0;
|
||||||
|
lupskip=false;
|
||||||
}
|
}
|
||||||
uint16_t lupct;
|
uint16_t lupct;
|
||||||
|
bool lupskip;
|
||||||
uint32_t lupoffset;
|
uint32_t lupoffset;
|
||||||
uint16_t luprunning;
|
uint16_t luprunning;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TDOstruct
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TDOstruct()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
void clear(void) {
|
||||||
|
dooff=false;
|
||||||
|
value=0;
|
||||||
|
}
|
||||||
|
uint32_t value;
|
||||||
|
bool dooff;
|
||||||
|
};
|
||||||
|
|
||||||
class TSymbol;
|
class TSymbol;
|
||||||
typedef int (*TOpCB)(MerlinLine &line, TSymbol &sym);
|
typedef int (*TOpCB)(MerlinLine &line, TSymbol &sym);
|
||||||
typedef std::function<int (MerlinLine &line, TSymbol &sym)> TOpCallback;
|
typedef std::function<int (MerlinLine &line, TSymbol &sym)> TOpCallback;
|
||||||
@ -322,6 +345,8 @@ public:
|
|||||||
bool skiplist; // used if lst is on, but LST opcode turns it off
|
bool skiplist; // used if lst is on, but LST opcode turns it off
|
||||||
uint32_t lineno;
|
uint32_t lineno;
|
||||||
|
|
||||||
|
bool generateCode;
|
||||||
|
|
||||||
std::string savepath;
|
std::string savepath;
|
||||||
TSymbol *currentsym;
|
TSymbol *currentsym;
|
||||||
std::vector<MerlinLine> lines;
|
std::vector<MerlinLine> lines;
|
||||||
@ -331,9 +356,12 @@ public:
|
|||||||
Poco::HashMap<std::string, TSymbol> variables;
|
Poco::HashMap<std::string, TSymbol> variables;
|
||||||
|
|
||||||
TOriginSection PC;
|
TOriginSection PC;
|
||||||
|
TLUPstruct curLUP;
|
||||||
|
TDOstruct curDO;
|
||||||
|
|
||||||
std::stack<TOriginSection> PCstack;
|
std::stack<TOriginSection> PCstack;
|
||||||
std::stack<TLUPstruct> LUPstack;
|
std::stack<TLUPstruct> LUPstack;
|
||||||
TLUPstruct curLUP;
|
std::stack<TDOstruct> DOstack;
|
||||||
|
|
||||||
TPsuedoOp *psuedoops;
|
TPsuedoOp *psuedoops;
|
||||||
|
|
||||||
@ -363,6 +391,8 @@ public:
|
|||||||
int evaluate(MerlinLine &line, std::string expr, int64_t &value);
|
int evaluate(MerlinLine &line, std::string expr, int64_t &value);
|
||||||
|
|
||||||
int substituteVariables(MerlinLine & line);
|
int substituteVariables(MerlinLine & line);
|
||||||
|
bool codeSkipped(void);
|
||||||
|
|
||||||
int parseOperand(MerlinLine &line);
|
int parseOperand(MerlinLine &line);
|
||||||
int getAddrMode(MerlinLine &line);
|
int getAddrMode(MerlinLine &line);
|
||||||
void setOpcode(MerlinLine &line, uint8_t op);
|
void setOpcode(MerlinLine &line, uint8_t op);
|
||||||
|
@ -754,10 +754,10 @@ void CLASS::insertOpcodes(void)
|
|||||||
pushopcode("ADRL",P_DATA, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("ADRL",P_DATA, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("HEX", P_HEX, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("HEX", P_HEX, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("DS", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("DS", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("DO", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("DO", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("ELSE", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("ELSE",P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("IF", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("IF", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("FIN", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("FIN", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("CHK", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("CHK", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("ERR", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("ERR", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("KBD", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("KBD", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
|
147
psuedo.cpp
147
psuedo.cpp
@ -13,11 +13,102 @@ 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)
|
int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
||||||
{
|
{
|
||||||
UNUSED(opinfo);
|
UNUSED(opinfo);
|
||||||
UNUSED(line);
|
|
||||||
UNUSED(a);
|
TEvaluator eval(a);
|
||||||
|
|
||||||
|
int64_t eval_result = 0;
|
||||||
|
uint8_t shift;
|
||||||
int lidx, len;
|
int lidx, len;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
@ -26,24 +117,38 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
|
|
||||||
if (op == "LUP")
|
if (op == "LUP")
|
||||||
{
|
{
|
||||||
|
line.flags |= FLAG_NOLINEPRINT;
|
||||||
len = line.lineno - 1; // MerlinLine line numbers are +1 from actual array idx
|
len = line.lineno - 1; // MerlinLine line numbers are +1 from actual array idx
|
||||||
if (len >= 0)
|
if (len >= 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
shift = 0;
|
||||||
|
eval_result = 0;
|
||||||
|
int x = eval.evaluate(line.operand, eval_result, shift);
|
||||||
|
|
||||||
a.LUPstack.push(a.curLUP);
|
a.LUPstack.push(a.curLUP);
|
||||||
|
|
||||||
a.curLUP.lupoffset = len;
|
a.curLUP.lupoffset = len;
|
||||||
a.curLUP.lupct = 3; // evaluate here
|
a.curLUP.lupct = eval_result & 0xFFFF; // evaluate here
|
||||||
a.curLUP.luprunning++;
|
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
|
else
|
||||||
{
|
{
|
||||||
printf("err 3\n");
|
|
||||||
err = errUnexpectedOp;
|
err = errUnexpectedOp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op == "--^")
|
if (op == "--^")
|
||||||
{
|
{
|
||||||
|
line.flags |= FLAG_NOLINEPRINT;
|
||||||
|
|
||||||
if (a.curLUP.luprunning > 0)
|
if (a.curLUP.luprunning > 0)
|
||||||
{
|
{
|
||||||
lidx = line.lineno - 1;
|
lidx = line.lineno - 1;
|
||||||
@ -58,6 +163,10 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
goto out;
|
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);
|
//printf("start=%d end=%d len=%d\n", a.curLUP.lupoffset, lidx, len);
|
||||||
if (a.LUPstack.size() > 0)
|
if (a.LUPstack.size() > 0)
|
||||||
@ -67,14 +176,14 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("err 2\n");
|
|
||||||
err = errUnexpectedOp;
|
err = errUnexpectedOp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("err 1\n");
|
a.curLUP.lupskip = false;
|
||||||
err = errUnexpectedOp;
|
// SGQ - found a '--^' without a LUP, should we just ignore?
|
||||||
|
//err = errUnexpectedOp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,6 +398,14 @@ int CLASS::doHEX(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
uint32_t bytect = 0;
|
uint32_t bytect = 0;
|
||||||
uint8_t b = 0;
|
uint8_t b = 0;
|
||||||
uint8_t ct = 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 )
|
for ( uint32_t i = 0; i < os.length(); ++i )
|
||||||
{
|
{
|
||||||
char c = os[i];
|
char c = os[i];
|
||||||
@ -311,8 +428,9 @@ int CLASS::doHEX(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
line.setError(errBadCharacter);
|
line.setError(errIllegalCharOperand);
|
||||||
return 0;
|
bytect = 0;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Got a good char, append to hex string and see if we've got a byte
|
// Got a good char, append to hex string and see if we've got a byte
|
||||||
@ -338,9 +456,10 @@ int CLASS::doHEX(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
}
|
}
|
||||||
if (ct & 0x01) // we got an odd number of nibbles
|
if (ct & 0x01) // we got an odd number of nibbles
|
||||||
{
|
{
|
||||||
line.setError(errMalformed);
|
line.setError(errBadOperand);
|
||||||
bytect = 0;
|
bytect = 0;
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
line.outbytect = bytect;
|
line.outbytect = bytect;
|
||||||
return bytect;
|
return bytect;
|
||||||
}
|
}
|
||||||
@ -367,6 +486,8 @@ int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
case P_DUM:
|
case P_DUM:
|
||||||
case P_DEND:
|
case P_DEND:
|
||||||
res = doDUM(a, line, opinfo);
|
res = doDUM(a, line, opinfo);
|
||||||
|
line.flags |= FLAG_FORCEADDRPRINT;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case P_ORG:
|
case P_ORG:
|
||||||
if (line.operand.length() > 0)
|
if (line.operand.length() > 0)
|
||||||
@ -380,6 +501,7 @@ int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
a.PC.currentpc = a.PC.orgsave;
|
a.PC.currentpc = a.PC.orgsave;
|
||||||
line.startpc = a.PC.orgsave;
|
line.startpc = a.PC.orgsave;
|
||||||
}
|
}
|
||||||
|
line.flags |= FLAG_FORCEADDRPRINT;
|
||||||
break;
|
break;
|
||||||
case P_SAV:
|
case P_SAV:
|
||||||
a.savepath = a.processFilename(line.operand, Poco::Path::current(), 0);
|
a.savepath = a.processFilename(line.operand, Poco::Path::current(), 0);
|
||||||
@ -395,8 +517,11 @@ int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
break;
|
break;
|
||||||
case P_LUP:
|
case P_LUP:
|
||||||
res = doLUP(a, line, opinfo);
|
res = doLUP(a, line, opinfo);
|
||||||
res = 0;
|
|
||||||
break;
|
break;
|
||||||
|
case P_DO:
|
||||||
|
res = doDO(a, line, opinfo);
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
return (res);
|
return (res);
|
||||||
}
|
}
|
||||||
|
3
psuedo.h
3
psuedo.h
@ -16,6 +16,7 @@ enum
|
|||||||
P_HEX,
|
P_HEX,
|
||||||
P_DATA,
|
P_DATA,
|
||||||
P_LUP,
|
P_LUP,
|
||||||
|
P_DO,
|
||||||
|
|
||||||
P_MAX
|
P_MAX
|
||||||
};
|
};
|
||||||
@ -32,6 +33,8 @@ public:
|
|||||||
int doHEX(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);
|
int doHEX(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);
|
||||||
int doDATA(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);
|
int doDATA(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);
|
||||||
int doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);
|
int doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);
|
||||||
|
int doDO(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
2
qasm.ini
2
qasm.ini
@ -31,7 +31,7 @@ merlincompatible=true
|
|||||||
symcolumns=3
|
symcolumns=3
|
||||||
|
|
||||||
[reformat]
|
[reformat]
|
||||||
tabs=12; 18; 36
|
tabs=12; 18; 30;
|
||||||
;tabs=0;0;0
|
;tabs=0;0;0
|
||||||
|
|
||||||
|
|
||||||
|
10
src/main.s
10
src/main.s
@ -1,4 +1,4 @@
|
|||||||
lst off
|
;lst off
|
||||||
*
|
*
|
||||||
* main.s
|
* main.s
|
||||||
* Merlin32 Test
|
* Merlin32 Test
|
||||||
@ -40,7 +40,6 @@ TSTADDR = $1000 ;absolute address for testing
|
|||||||
*==========================================================
|
*==========================================================
|
||||||
* Data Index DUM section test
|
* Data Index DUM section test
|
||||||
|
|
||||||
lst off
|
|
||||||
DUM 0
|
DUM 0
|
||||||
dum0 ds 1 ;fractional byte
|
dum0 ds 1 ;fractional byte
|
||||||
dum1 ds 1
|
dum1 ds 1
|
||||||
@ -396,11 +395,8 @@ L00BC bit L00BC
|
|||||||
|
|
||||||
lst
|
lst
|
||||||
lup_start:
|
lup_start:
|
||||||
lup 3
|
lup 0
|
||||||
;db 0 ; outside
|
db 0 ; outside
|
||||||
;lup 3
|
|
||||||
;db 1 ; inside
|
|
||||||
;--^
|
|
||||||
--^
|
--^
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user