mirror of
https://github.com/marketideas/qasm.git
synced 2024-12-28 06:29:58 +00:00
commit
3e568ad47a
6
README
6
README
@ -46,3 +46,9 @@ make
|
|||||||
|
|
||||||
To test:
|
To test:
|
||||||
./qasm src/testfile.s
|
./qasm src/testfile.s
|
||||||
|
|
||||||
|
|
||||||
|
Some notes on compatibility:
|
||||||
|
|
||||||
|
ERR does not support the ($300)-$4C style of checking, because we are not running on Apple // hardware, so there is no need to check for a USR vector having been setup in this manner.
|
||||||
|
|
||||||
|
57
asm.cpp
57
asm.cpp
@ -343,7 +343,7 @@ std::string commentEx = "^(\\s*)((;|\\/{2}))+(.*)";
|
|||||||
void CLASS::set(std::string line)
|
void CLASS::set(std::string line)
|
||||||
{
|
{
|
||||||
int state = 0;
|
int state = 0;
|
||||||
int l = line.length();
|
int l = (int)line.length();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int x;
|
int x;
|
||||||
char c, delim;
|
char c, delim;
|
||||||
@ -491,7 +491,7 @@ void CLASS::set(std::string line)
|
|||||||
//printf("%d regex %d match |%s|\n", ct, x, restofline.c_str());
|
//printf("%d regex %d match |%s|\n", ct, x, restofline.c_str());
|
||||||
operand = strs[0];
|
operand = strs[0];
|
||||||
//printf("which=%d operand=|%s|\n",ct,operand.c_str());
|
//printf("which=%d operand=|%s|\n",ct,operand.c_str());
|
||||||
i = operand.length();
|
i = (int)operand.length();
|
||||||
restofline = restofline.substr(i, restofline.length());
|
restofline = restofline.substr(i, restofline.length());
|
||||||
comment = Poco::trim(restofline);
|
comment = Poco::trim(restofline);
|
||||||
match = true;
|
match = true;
|
||||||
@ -510,7 +510,7 @@ void CLASS::set(std::string line)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
printlable = lable;
|
printlable = lable;
|
||||||
x = lable.length();
|
x = (int)lable.length();
|
||||||
if (x > 1)
|
if (x > 1)
|
||||||
{
|
{
|
||||||
// M32 syntax allows a colon after lable, and it is not part of the lable
|
// M32 syntax allows a colon after lable, and it is not part of the lable
|
||||||
@ -941,7 +941,7 @@ int CLASS::doline(int lineno, std::string line)
|
|||||||
void CLASS::process(void)
|
void CLASS::process(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint32_t ct = lines.size();
|
uint32_t ct = (uint32_t)lines.size();
|
||||||
|
|
||||||
uint32_t len, t, pos;
|
uint32_t len, t, pos;
|
||||||
|
|
||||||
@ -1239,6 +1239,11 @@ TSymbol * CLASS::findVariable(std::string symname, TVariable &vars)
|
|||||||
{
|
{
|
||||||
TSymbol *res = NULL;
|
TSymbol *res = NULL;
|
||||||
|
|
||||||
|
if (!casesen)
|
||||||
|
{
|
||||||
|
symname = Poco::toUpper(symname);
|
||||||
|
}
|
||||||
|
|
||||||
if ((expand_macrostack.size() > 0) && (vars.id != expand_macro.variables.id))
|
if ((expand_macrostack.size() > 0) && (vars.id != expand_macro.variables.id))
|
||||||
{
|
{
|
||||||
res = findVariable(symname, expand_macro.variables);
|
res = findVariable(symname, expand_macro.variables);
|
||||||
@ -1693,7 +1698,7 @@ void CLASS::complete(void)
|
|||||||
std::ofstream f(savepath);
|
std::ofstream f(savepath);
|
||||||
|
|
||||||
uint32_t lineno = 0;
|
uint32_t lineno = 0;
|
||||||
uint32_t l = lines.size();
|
uint32_t l = (uint32_t)lines.size();
|
||||||
while (lineno < l)
|
while (lineno < l)
|
||||||
{
|
{
|
||||||
MerlinLine &line = lines.at(lineno++);
|
MerlinLine &line = lines.at(lineno++);
|
||||||
@ -1971,14 +1976,14 @@ restart:
|
|||||||
offset = slen;
|
offset = slen;
|
||||||
}
|
}
|
||||||
|
|
||||||
x = mVec.size();
|
x = (int)mVec.size();
|
||||||
if (x > 0)
|
if (x > 0)
|
||||||
{
|
{
|
||||||
res = 0;
|
res = 0;
|
||||||
off = mVec[0].offset;
|
off = (uint32_t)mVec[0].offset;
|
||||||
len = mVec[0].length;
|
len = (uint32_t)mVec[0].length;
|
||||||
s = oper.substr(off, len);
|
s = oper.substr(off, len);
|
||||||
|
slen = s.length();
|
||||||
sym = NULL;
|
sym = NULL;
|
||||||
if (expand_macrostack.size() > 0)
|
if (expand_macrostack.size() > 0)
|
||||||
{
|
{
|
||||||
@ -1995,6 +2000,7 @@ restart:
|
|||||||
if (sym->var_text != "")
|
if (sym->var_text != "")
|
||||||
{
|
{
|
||||||
oper = oper.replace(off, len, sym->var_text);
|
oper = oper.replace(off, len, sym->var_text);
|
||||||
|
slen = oper.length();
|
||||||
ct++;
|
ct++;
|
||||||
if (pass > 0)
|
if (pass > 0)
|
||||||
{
|
{
|
||||||
@ -2037,7 +2043,7 @@ bool CLASS::doOFF(void)
|
|||||||
std::stack<TDOstruct> tmpstack;
|
std::stack<TDOstruct> tmpstack;
|
||||||
TDOstruct doitem;
|
TDOstruct doitem;
|
||||||
|
|
||||||
uint32_t ct = DOstack.size();
|
uint32_t ct = (uint32_t)DOstack.size();
|
||||||
if (ct > 0)
|
if (ct > 0)
|
||||||
{
|
{
|
||||||
tmpstack = DOstack;
|
tmpstack = DOstack;
|
||||||
@ -2095,7 +2101,7 @@ void CLASS::process(void)
|
|||||||
{
|
{
|
||||||
initpass();
|
initpass();
|
||||||
|
|
||||||
l = lines.size();
|
l = (uint32_t)lines.size();
|
||||||
bool passdone = false;
|
bool passdone = false;
|
||||||
while ((!passdone) && (!passcomplete))
|
while ((!passdone) && (!passcomplete))
|
||||||
{
|
{
|
||||||
@ -2201,7 +2207,11 @@ void CLASS::process(void)
|
|||||||
std::string outop;
|
std::string outop;
|
||||||
line.printoperand = line.operand;
|
line.printoperand = line.operand;
|
||||||
|
|
||||||
x = substituteVariables(line, outop);
|
x = 0;
|
||||||
|
if (macrostack.size() == 0)
|
||||||
|
{
|
||||||
|
x = substituteVariables(line, outop);
|
||||||
|
}
|
||||||
if (x > 0)
|
if (x > 0)
|
||||||
{
|
{
|
||||||
line.printoperand = outop;
|
line.printoperand = outop;
|
||||||
@ -2243,20 +2253,23 @@ void CLASS::process(void)
|
|||||||
{
|
{
|
||||||
TMacro *mac = NULL;
|
TMacro *mac = NULL;
|
||||||
bool inoperand = false;
|
bool inoperand = false;
|
||||||
mac = findMacro(realop);
|
if (macrostack.size() == 0)
|
||||||
if (mac == NULL)
|
|
||||||
{
|
{
|
||||||
if (op == ">>>") // specal merlin way of calling a macro
|
mac = findMacro(realop);
|
||||||
|
if (mac == NULL)
|
||||||
{
|
{
|
||||||
Poco::StringTokenizer tok(operand, ", ", Poco::StringTokenizer::TOK_TRIM |
|
if (op == ">>>") // specal merlin way of calling a macro
|
||||||
Poco::StringTokenizer::TOK_IGNORE_EMPTY);
|
|
||||||
std::string s = "";
|
|
||||||
if (tok.count() > 0)
|
|
||||||
{
|
{
|
||||||
s = tok[0];
|
Poco::StringTokenizer tok(operand, ", ", Poco::StringTokenizer::TOK_TRIM |
|
||||||
|
Poco::StringTokenizer::TOK_IGNORE_EMPTY);
|
||||||
|
std::string s = "";
|
||||||
|
if (tok.count() > 0)
|
||||||
|
{
|
||||||
|
s = tok[0];
|
||||||
|
}
|
||||||
|
mac = findMacro(s);
|
||||||
|
inoperand = true;
|
||||||
}
|
}
|
||||||
mac = findMacro(s);
|
|
||||||
inoperand = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mac == NULL)
|
if (mac == NULL)
|
||||||
|
4
eval.cpp
4
eval.cpp
@ -391,7 +391,7 @@ int CLASS::parseAscii(std::string n, int64_t &val)
|
|||||||
bool high = false;
|
bool high = false;
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
|
|
||||||
uint32_t l = n.length();
|
uint32_t l = (uint32_t)n.length();
|
||||||
for (uint32_t i = 0; i < l - 1; i++)
|
for (uint32_t i = 0; i < l - 1; i++)
|
||||||
{
|
{
|
||||||
c = n[i];
|
c = n[i];
|
||||||
@ -442,7 +442,7 @@ int CLASS::parseNumber(std::string n, int64_t &val)
|
|||||||
|
|
||||||
//printf("parseNumber |%s|\n",n.c_str());
|
//printf("parseNumber |%s|\n",n.c_str());
|
||||||
i = 0;
|
i = 0;
|
||||||
l = n.length();
|
l = (uint32_t)n.length();
|
||||||
s = "";
|
s = "";
|
||||||
for (i = 0; i < l; i++)
|
for (i = 0; i < l; i++)
|
||||||
{
|
{
|
||||||
|
@ -20,17 +20,14 @@ for S in $SRC ; do
|
|||||||
S1=${S1/.S/}
|
S1=${S1/.S/}
|
||||||
S1=${S1/.s/}
|
S1=${S1/.s/}
|
||||||
|
|
||||||
BASE=${S/.S/}
|
|
||||||
BASE=${BASE/.s/}
|
|
||||||
cd ./testdata
|
cd ./testdata
|
||||||
merlin32$X . $S 2>/dev/null >/dev/null
|
merlin32$X . $S 2>/dev/null >/dev/null
|
||||||
#merlin32 . $S 2>/dev/null
|
#merlin32 . $S 2>/dev/null
|
||||||
|
|
||||||
R=?$
|
R=?$
|
||||||
cd - >/dev/null
|
cd .. >/dev/null
|
||||||
cp ./testdata/$S1 $OUTDIR/$S1.bin 2>/dev/null
|
mv ./testdata/$S1 $OUTDIR/$S1.bin 2>/dev/null
|
||||||
rm -f ./testdata/*.txt 2>/dev/null
|
rm -f ./testdata/*.txt 2>/dev/null
|
||||||
rm -f ./testdata/$S1 2>/dev/null
|
|
||||||
R=?$
|
R=?$
|
||||||
|
|
||||||
done
|
done
|
||||||
|
13
opcodes.cpp
13
opcodes.cpp
@ -829,7 +829,11 @@ void CLASS::insertOpcodes(void)
|
|||||||
{
|
{
|
||||||
pushopcode("=", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doEQU));
|
pushopcode("=", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doEQU));
|
||||||
pushopcode("EQU", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doEQU));
|
pushopcode("EQU", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doEQU));
|
||||||
pushopcode("EXT", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("END", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doEND));
|
||||||
|
pushopcode("MX", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doMX));
|
||||||
|
pushopcode("XC", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doXC));
|
||||||
|
|
||||||
|
pushopcode("EXT", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("ENT", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("ENT", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("ORG", P_ORG, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("ORG", P_ORG, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("DSK", P_SAV, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("DSK", P_SAV, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
@ -840,12 +844,11 @@ void CLASS::insertOpcodes(void)
|
|||||||
pushopcode("PUT", P_PUT, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("PUT", P_PUT, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("USE", P_USE, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("USE", P_USE, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("VAR", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("VAR", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("SAV", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
|
||||||
pushopcode("TYP", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("TYP", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("END", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doEND));
|
|
||||||
pushopcode("DUM", P_DUM, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("DUM", P_DUM, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("DEND", P_DEND, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("DEND", P_DEND, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("AST", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("AST", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
|
pushopcode("CAS", P_CAS, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("CYC", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("CYC", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("DAT", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("DAT", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("EXP", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("EXP", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
@ -870,7 +873,6 @@ void CLASS::insertOpcodes(void)
|
|||||||
pushopcode("ADR", P_DATA, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("ADR", P_DATA, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
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("DO", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("DO", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("ELSE", 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("IF", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
@ -880,11 +882,9 @@ void CLASS::insertOpcodes(void)
|
|||||||
pushopcode("KBD", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("KBD", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("LUP", P_LUP, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("LUP", P_LUP, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("--^", P_LUP, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("--^", P_LUP, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("MX", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doMX));
|
|
||||||
pushopcode("PAU", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("PAU", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("SW", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("SW", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("USR", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("USR", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("XC", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doXC));
|
|
||||||
pushopcode("MAC", P_MAC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
pushopcode("MAC", P_MAC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
|
||||||
pushopcode("EOM", 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));
|
||||||
@ -898,7 +898,6 @@ void CLASS::insertOpcodes(void)
|
|||||||
pushopcode("BLT", 0x02, 0, OPHANDLER(&CLASS::doBRANCH));
|
pushopcode("BLT", 0x02, 0, OPHANDLER(&CLASS::doBRANCH));
|
||||||
pushopcode("BCS", 0x82, 0, OPHANDLER(&CLASS::doBRANCH));
|
pushopcode("BCS", 0x82, 0, OPHANDLER(&CLASS::doBRANCH));
|
||||||
pushopcode("BGE", 0x82, 0, OPHANDLER(&CLASS::doBRANCH));
|
pushopcode("BGE", 0x82, 0, OPHANDLER(&CLASS::doBRANCH));
|
||||||
|
|
||||||
pushopcode("BEQ", 0x83, 0, OPHANDLER(&CLASS::doBRANCH));
|
pushopcode("BEQ", 0x83, 0, OPHANDLER(&CLASS::doBRANCH));
|
||||||
pushopcode("BIT", 0x01, OP_C0, OPHANDLER(&CLASS::doBase6502));
|
pushopcode("BIT", 0x01, OP_C0, OPHANDLER(&CLASS::doBase6502));
|
||||||
pushopcode("BMI", 0x80, 0, OPHANDLER(&CLASS::doBRANCH));
|
pushopcode("BMI", 0x80, 0, OPHANDLER(&CLASS::doBRANCH));
|
||||||
|
74
psuedo.cpp
74
psuedo.cpp
@ -36,7 +36,7 @@ int CLASS::doDO(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
UNUSED(opinfo);
|
UNUSED(opinfo);
|
||||||
|
|
||||||
TEvaluator eval(a);
|
TEvaluator eval(a);
|
||||||
eval.allowMX=true; // allow the built in MX symbol
|
eval.allowMX = true; // allow the built in MX symbol
|
||||||
|
|
||||||
int64_t eval_value = 0;
|
int64_t eval_value = 0;
|
||||||
uint8_t shift;
|
uint8_t shift;
|
||||||
@ -141,8 +141,9 @@ int CLASS::doMAC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
std::string op = Poco::toUpper(line.opcode);
|
std::string op = Poco::toUpper(line.opcode);
|
||||||
if (op == "MAC")
|
if (op == "MAC")
|
||||||
{
|
{
|
||||||
if (a.expand_macrostack.size()>0)
|
if (a.expand_macrostack.size() > 0)
|
||||||
{
|
{
|
||||||
|
line.flags |= FLAG_NOLINEPRINT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (line.lable.length() == 0)
|
if (line.lable.length() == 0)
|
||||||
@ -157,6 +158,12 @@ int CLASS::doMAC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
a.currentmacro.lcname = Poco::toLower(line.lable);
|
a.currentmacro.lcname = Poco::toLower(line.lable);
|
||||||
a.currentmacro.start = line.lineno;
|
a.currentmacro.start = line.lineno;
|
||||||
a.currentmacro.running = true;
|
a.currentmacro.running = true;
|
||||||
|
|
||||||
|
if (!a.casesen)
|
||||||
|
{
|
||||||
|
a.currentmacro.name = Poco::toUpper(a.currentmacro.name);
|
||||||
|
}
|
||||||
|
|
||||||
if (a.pass == 0)
|
if (a.pass == 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -399,7 +406,7 @@ int CLASS::doDATA(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
line.setError(errBadEvaluation);
|
line.setError(errBadEvaluation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
eval_value = doShift(eval_value, shift);
|
eval_value = (uint64_t)doShift((uint32_t)eval_value, shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
outct += wordsize;
|
outct += wordsize;
|
||||||
@ -477,7 +484,7 @@ int CLASS::doDS(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
line.setError(errBadOperand);
|
line.setError(errBadOperand);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
eval_value = doShift(eval_value, shift);
|
eval_value = (uint64_t)doShift((uint32_t)eval_value, shift);
|
||||||
datact = eval_value & 0xFFFF;
|
datact = eval_value & 0xFFFF;
|
||||||
if (datact < 0)
|
if (datact < 0)
|
||||||
{
|
{
|
||||||
@ -497,7 +504,7 @@ int CLASS::doDS(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
line.setError(errBadOperand);
|
line.setError(errBadOperand);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
eval_value = doShift(eval_value, shift);
|
eval_value = (uint64_t)doShift((uint32_t)eval_value, shift);
|
||||||
fill = eval_value & 0xFF;
|
fill = eval_value & 0xFF;
|
||||||
}
|
}
|
||||||
else if (ct > 1)
|
else if (ct > 1)
|
||||||
@ -696,20 +703,21 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
std::string os = line.operand;
|
std::string os = line.operand;
|
||||||
std::string op = Poco::toUpper(line.opcode);
|
std::string op = Poco::toUpper(line.opcode);
|
||||||
|
|
||||||
uint8_t lastdelimbyte = 0x00;
|
uint8_t firstdelim = 0;
|
||||||
uint8_t firstdelim = 0xFF;
|
|
||||||
uint32_t bytect = 0;
|
uint32_t bytect = 0;
|
||||||
uint8_t b = 0;
|
uint8_t b = 0;
|
||||||
uint8_t b1;
|
uint8_t b1;
|
||||||
uint8_t ct = 0;
|
uint8_t ct = 0;
|
||||||
char delimiter = 0;
|
uint8_t delimiter = 0;
|
||||||
uint32_t ss = 0;
|
uint32_t ss = 0;
|
||||||
|
uint32_t lastdelimidx = 0;
|
||||||
|
|
||||||
std::vector<uint8_t> bytes;
|
std::vector<uint8_t> bytes;
|
||||||
|
|
||||||
line.eval_result = 0; // since this is an ASCII p-op, clear the global 'bad operand' flag
|
line.eval_result = 0; // since this is an ASCII p-op, clear the global 'bad operand' flag
|
||||||
for ( uint32_t i = 0; i < os.length(); ++i )
|
for ( uint32_t i = 0; i < os.length(); ++i )
|
||||||
{
|
{
|
||||||
char c = os[i];
|
uint8_t c = os[i];
|
||||||
|
|
||||||
// are we inside a delimited string?
|
// are we inside a delimited string?
|
||||||
if ( delimiter )
|
if ( delimiter )
|
||||||
@ -731,9 +739,9 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
{
|
{
|
||||||
c |= 0x80;
|
c |= 0x80;
|
||||||
}
|
}
|
||||||
lastdelimbyte = c;
|
|
||||||
bytes.push_back(c);
|
bytes.push_back(c);
|
||||||
//line.outbytes.push_back(c);
|
lastdelimidx = (uint32_t)(bytes.size() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -756,7 +764,7 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
{
|
{
|
||||||
// if not a hex value, then consider the character to be the string delimiter
|
// if not a hex value, then consider the character to be the string delimiter
|
||||||
delimiter = c;
|
delimiter = c;
|
||||||
if (firstdelim == 0xFF)
|
if( ! firstdelim )
|
||||||
{
|
{
|
||||||
firstdelim = c;
|
firstdelim = c;
|
||||||
}
|
}
|
||||||
@ -784,7 +792,6 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
if (a.pass > 0)
|
if (a.pass > 0)
|
||||||
{
|
{
|
||||||
bytes.push_back(b);
|
bytes.push_back(b);
|
||||||
//line.outbytes.push_back(b);
|
|
||||||
}
|
}
|
||||||
b = 0;
|
b = 0;
|
||||||
bytect++;
|
bytect++;
|
||||||
@ -805,8 +812,7 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
uint8_t andval = 0xFF;
|
uint8_t andval = 0xFF;
|
||||||
uint8_t orval = 0x00;
|
uint8_t orval = 0x00;
|
||||||
uint8_t addlen = 0;
|
uint8_t addlen = 0;
|
||||||
uint8_t firstbyte = 0x00;
|
uint32_t truebytect = (uint32_t)bytes.size();
|
||||||
uint32_t truebytect = bytes.size();
|
|
||||||
const char *ptr = (const char *)op.c_str();
|
const char *ptr = (const char *)op.c_str();
|
||||||
//printf("bytect=%d bytes.size()=%zu\n",bytect,bytes.size());
|
//printf("bytect=%d bytes.size()=%zu\n",bytect,bytes.size());
|
||||||
switch (strhash(ptr) )
|
switch (strhash(ptr) )
|
||||||
@ -855,26 +861,31 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
{
|
{
|
||||||
b = bytes[i];
|
b = bytes[i];
|
||||||
}
|
}
|
||||||
if (!i)
|
|
||||||
{
|
b1 = b & 0x7F;
|
||||||
firstbyte = b;
|
|
||||||
}
|
|
||||||
b1 = b & 0x7F;
|
|
||||||
if ((andval != 0xFF) || (orval != 0x00))
|
if ((andval != 0xFF) || (orval != 0x00))
|
||||||
{
|
{
|
||||||
b = b1;
|
b = b1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((b1 < 0x60))
|
if ((b1 < 0x60))
|
||||||
{
|
{
|
||||||
b &= andval; // strip whatever bits needed to flash or invert
|
b &= andval; // strip whatever bits needed to flash or invert
|
||||||
b |= orval;
|
b |= orval;
|
||||||
}
|
}
|
||||||
if ((dci) && (i == (truebytect - 1)))
|
|
||||||
|
if (dci && (i == lastdelimidx))
|
||||||
{
|
{
|
||||||
// this one might be a bug. I am going to compare the first byte in the string for
|
//lr - Merlin only toggles the high bit of string chars, not hex values
|
||||||
// bit seven, and invert it on this byte. The confusion arises because this text string
|
// 8D,'Hello',8D,'there',8D becomes 8D 48 65 6C 6C 6F 8D 74 68 65 72 E5
|
||||||
// could have high ASCII, but low HEX values.
|
//
|
||||||
if (firstbyte < 0x80)
|
// The DCI instruction is documented to work like this on page 108
|
||||||
|
// (regardless of how this effects the desired lda, (bpl/bmi) functionality)
|
||||||
|
//
|
||||||
|
// I am now checking the delimiter character to determine hi/lo toggle (reversed)
|
||||||
|
// and am tracking the index to the last delimited character put into 'bytes'.
|
||||||
|
// This produces the same results as Merlin 16+ in my testing.
|
||||||
|
if ( firstdelim >= '\'' )
|
||||||
{
|
{
|
||||||
b |= 0x80;
|
b |= 0x80;
|
||||||
}
|
}
|
||||||
@ -899,6 +910,7 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
std::string s;
|
||||||
|
|
||||||
switch (opinfo.opcode)
|
switch (opinfo.opcode)
|
||||||
{
|
{
|
||||||
@ -949,6 +961,18 @@ int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
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);
|
||||||
break;
|
break;
|
||||||
|
case P_CAS:
|
||||||
|
s = Poco::toUpper(line.operand);
|
||||||
|
if (s == "SE")
|
||||||
|
{
|
||||||
|
a.casesen = true;
|
||||||
|
}
|
||||||
|
if (s=="IN")
|
||||||
|
{
|
||||||
|
a.casesen=false;
|
||||||
|
}
|
||||||
|
res = 0;
|
||||||
|
break;
|
||||||
case P_MAC:
|
case P_MAC:
|
||||||
res = doMAC(a, line, opinfo);
|
res = doMAC(a, line, opinfo);
|
||||||
break;
|
break;
|
||||||
|
1
psuedo.h
1
psuedo.h
@ -21,6 +21,7 @@ enum
|
|||||||
P_ASC,
|
P_ASC,
|
||||||
P_ERR,
|
P_ERR,
|
||||||
P_MAC,
|
P_MAC,
|
||||||
|
P_CAS,
|
||||||
|
|
||||||
P_MAX
|
P_MAX
|
||||||
};
|
};
|
||||||
|
2
testdata/3001-lroathe.S
vendored
2
testdata/3001-lroathe.S
vendored
@ -413,6 +413,8 @@ L00BC bit L00BC
|
|||||||
asc 02,15,"123456"
|
asc 02,15,"123456"
|
||||||
asc 0215"1234"1502
|
asc 0215"1234"1502
|
||||||
|
|
||||||
|
dci 8D,'Hello',8D,'there',8D
|
||||||
|
dci 8D,"Hello",8D,"there",8D
|
||||||
|
|
||||||
lst
|
lst
|
||||||
lup_start:
|
lup_start:
|
||||||
|
Loading…
Reference in New Issue
Block a user