mirror of
https://github.com/marketideas/qasm.git
synced 2024-06-10 14:29:33 +00:00
commit
41fcc6451b
11
Makefile
11
Makefile
|
@ -32,8 +32,9 @@ debug:
|
|||
|
||||
|
||||
distclean:
|
||||
rm -rf ./build
|
||||
-rm -rf ./testout
|
||||
-rm -rf ./build
|
||||
-rm -rf ./qasmout
|
||||
-rm -rf ./m32out
|
||||
|
||||
clean:
|
||||
-rm -rf ./build
|
||||
|
@ -60,13 +61,13 @@ compare:
|
|||
asm:
|
||||
|
||||
test1:
|
||||
-qasm src/main.s
|
||||
-qasm testdata/3001-lroathe.S
|
||||
|
||||
test2:
|
||||
-qasm src/testfile.s
|
||||
-qasm testdata/3002-testfile.S
|
||||
|
||||
test3:
|
||||
-qasm src/var.s
|
||||
-qasm testdata/3003-var.S
|
||||
|
||||
|
||||
|
||||
|
|
210
asm.cpp
210
asm.cpp
|
@ -211,7 +211,14 @@ void CLASS::print(uint32_t lineno)
|
|||
}
|
||||
else
|
||||
{
|
||||
pcol += printf("%s ", printoperand.c_str());
|
||||
if (printoperand.length() > 0)
|
||||
{
|
||||
pcol += printf("%s ", printoperand.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
pcol += printf("%s ", operand.c_str());
|
||||
}
|
||||
}
|
||||
//pcol += printf("%-12s %-8s %-10s ", printlable.c_str(), opcode.c_str(), operand.c_str());
|
||||
}
|
||||
|
@ -292,6 +299,7 @@ void CLASS::print(uint32_t lineno)
|
|||
void CLASS::clear()
|
||||
{
|
||||
syntax = SYNTAX_MERLIN;
|
||||
wholetext = "";
|
||||
lable = "";
|
||||
printlable = "";
|
||||
opcode = "";
|
||||
|
@ -345,6 +353,7 @@ void CLASS::set(std::string line)
|
|||
std::string tline = line;
|
||||
clear();
|
||||
|
||||
wholetext = line;
|
||||
isascii = false;
|
||||
delim = 0;
|
||||
while (i < l)
|
||||
|
@ -1117,6 +1126,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;
|
||||
|
@ -1160,7 +1191,7 @@ out:
|
|||
return (res);
|
||||
}
|
||||
|
||||
TSymbol * CLASS::addVariable(std::string symname, std::string val, bool replace)
|
||||
TSymbol * CLASS::addVariable(std::string symname, std::string val, variable_t &vars, bool replace)
|
||||
{
|
||||
TSymbol *res = NULL;
|
||||
TSymbol *fnd = NULL;
|
||||
|
@ -1172,7 +1203,7 @@ TSymbol * CLASS::addVariable(std::string symname, std::string val, bool replace)
|
|||
}
|
||||
|
||||
//printf("addvariable\n");
|
||||
fnd = findVariable(sym);
|
||||
fnd = findVariable(sym, vars);
|
||||
|
||||
if ((fnd != NULL) && (!replace))
|
||||
{
|
||||
|
@ -1199,18 +1230,18 @@ TSymbol * CLASS::addVariable(std::string symname, std::string val, bool replace)
|
|||
//printf("addvariable: %s %s\n", s.name.c_str(), s.text.c_str());
|
||||
|
||||
std::pair<std::string, TSymbol> p(sym, s);
|
||||
variables.insert(p);
|
||||
res = findVariable(sym);
|
||||
vars.insert(p);
|
||||
res = findVariable(sym, vars);
|
||||
return (res);
|
||||
}
|
||||
|
||||
TSymbol * CLASS::findVariable(std::string symname)
|
||||
TSymbol * CLASS::findVariable(std::string symname, variable_t &vars)
|
||||
{
|
||||
TSymbol *res = NULL;
|
||||
|
||||
//printf("finding: %s\n",symname.c_str());
|
||||
auto itr = variables.find(symname);
|
||||
if (itr != variables.end())
|
||||
auto itr = vars.find(symname);
|
||||
if (itr != vars.end())
|
||||
{
|
||||
//printf("Found: %s 0x%08X\n",itr->second.name.c_str(),itr->second.value);
|
||||
res = &itr->second;
|
||||
|
@ -1220,13 +1251,13 @@ TSymbol * CLASS::findVariable(std::string symname)
|
|||
return (res);
|
||||
}
|
||||
|
||||
void CLASS::showVariables(void)
|
||||
void CLASS::showVariables(variable_t &vars)
|
||||
{
|
||||
if (variables.size() > 0)
|
||||
{
|
||||
printf("\nVariables:\n");
|
||||
|
||||
for (auto itr = variables.begin(); itr != variables.end(); ++itr)
|
||||
for (auto itr = vars.begin(); itr != vars.end(); ++itr)
|
||||
{
|
||||
printf("%-16s %s\n", itr->first.c_str(), itr->second.var_text.c_str());
|
||||
}
|
||||
|
@ -1287,6 +1318,44 @@ void CLASS::showSymbolTable(bool alpha)
|
|||
}
|
||||
}
|
||||
|
||||
// set alpha to true to print table sorted by name or
|
||||
// false to print by value;
|
||||
void CLASS::showMacros(bool alpha)
|
||||
{
|
||||
if (macros.size() > 0)
|
||||
{
|
||||
std::map<std::string, uint32_t> alphamap;
|
||||
|
||||
int columns = getInt("asm.symcolumns", 3);
|
||||
int column = columns;
|
||||
|
||||
for (auto itr = macros.begin(); itr != macros.end(); itr++)
|
||||
{
|
||||
TMacro ptr = itr->second;
|
||||
alphamap.insert(pair<std::string, uint32_t>(ptr.name, 0));
|
||||
}
|
||||
|
||||
if (alpha)
|
||||
{
|
||||
printf("\n\nmacros sorted alphabetically:\n\n");
|
||||
|
||||
for (auto itr = alphamap.begin(); itr != alphamap.end(); ++itr)
|
||||
{
|
||||
printf("%-16s 0x%08X ", itr->first.c_str(), itr->second);
|
||||
if ( !--column )
|
||||
{
|
||||
printf("\n");
|
||||
column = columns;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (column > 0)
|
||||
{
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CLASS::callOpCode(std::string op, MerlinLine &line)
|
||||
{
|
||||
int res = -1;
|
||||
|
@ -1331,16 +1400,22 @@ int CLASS::callOpCode(std::string op, MerlinLine &line)
|
|||
switch (line.expr_shift)
|
||||
{
|
||||
case '<':
|
||||
line.expr_value &= 0xFF;
|
||||
//line.expr_value &= 0xFF;
|
||||
break;
|
||||
case '>':
|
||||
line.expr_value >>= 8;
|
||||
line.expr_value &= 0xFFFF;
|
||||
//line.expr_value &= 0xFFFF;
|
||||
break;
|
||||
case '^':
|
||||
line.expr_value = (line.expr_value >> 16) & 0xFFFF;
|
||||
line.expr_value = (line.expr_value >> 16);
|
||||
//line.expr_value = (line.expr_value >> 16) & 0xFFFF;
|
||||
break;
|
||||
case '|':
|
||||
if (syntax == SYNTAX_MERLIN)
|
||||
{
|
||||
line.setError(errBadLabel);
|
||||
line.expr_value = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1352,12 +1427,14 @@ int CLASS::callOpCode(std::string op, MerlinLine &line)
|
|||
line.flags |= FLAG_DP;
|
||||
break;
|
||||
case '>':
|
||||
#if 0
|
||||
if ((syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32)
|
||||
{
|
||||
// bug in M32 or not, do what it does
|
||||
line.flags |= FLAG_FORCEABS;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
line.flags |= FLAG_FORCELONG;
|
||||
}
|
||||
|
@ -1406,13 +1483,6 @@ typedef struct
|
|||
// these are the regular expressions that determine the addressing mode
|
||||
// and extract the 'expr' part of the addr-mode
|
||||
|
||||
// ^([_,a-z,A-Z,0-9:\]].+)\,[s,S]{1}$ // might be a better syn_s
|
||||
|
||||
// "^([:-~][0-Z_-~]*)$" // this is a valid identifier
|
||||
// "^([$][0-9A-Fa-f]+)$" // hex digit
|
||||
// "^([%][0-1][0-1_]+[0-1])$" - binary numbera
|
||||
// "^([0-9]+)$" - decimal number
|
||||
// "^([:-~][^\],()]*)$" - valid expression
|
||||
const TaddrMode addrRegEx[] =
|
||||
{
|
||||
{ "^(?'expr'.+)\\,[s,S]{1}$", syn_s, "e,s"}, // expr,s
|
||||
|
@ -1430,9 +1500,6 @@ const TaddrMode addrRegEx[] =
|
|||
{"", 0, ""}
|
||||
};
|
||||
|
||||
// keep this next line for awhile
|
||||
// {"^#{1}(?'shift'[<,>,^,|]?)(.+)$", syn_imm, "immediate"}, //#expr,#^expr,#|expr,#<expr,#>expr
|
||||
|
||||
// one or more of any character except ][,();
|
||||
const std::string valExpression = "^([^\\]\\[,();]+)$";
|
||||
|
||||
|
@ -1561,9 +1628,13 @@ void CLASS::initpass(void)
|
|||
truncdata = 0;
|
||||
variables.clear(); // clear the variables for each pass
|
||||
|
||||
while (!PCstack.empty())
|
||||
while (!macrostack.empty())
|
||||
{
|
||||
PCstack.pop();
|
||||
macrostack.pop();
|
||||
}
|
||||
while (!expand_macrostack.empty())
|
||||
{
|
||||
expand_macrostack.pop();
|
||||
}
|
||||
while (!LUPstack.empty())
|
||||
{
|
||||
|
@ -1577,6 +1648,12 @@ void CLASS::initpass(void)
|
|||
{
|
||||
LSTstack.pop();
|
||||
}
|
||||
while (!PCstack.empty())
|
||||
{
|
||||
PCstack.pop();
|
||||
}
|
||||
currentmacro.clear();
|
||||
expand_macro.clear();
|
||||
curLUP.clear();
|
||||
curDO.clear();
|
||||
}
|
||||
|
@ -1630,8 +1707,10 @@ void CLASS::complete(void)
|
|||
{
|
||||
showSymbolTable(true);
|
||||
showSymbolTable(false);
|
||||
showVariables();
|
||||
showVariables(variables);
|
||||
showMacros(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int CLASS::evaluate(MerlinLine &line, std::string expr, int64_t &value)
|
||||
|
@ -1878,7 +1957,7 @@ restart:
|
|||
off = mVec[0].offset;
|
||||
len = mVec[0].length;
|
||||
s = oper.substr(off, len);
|
||||
sym = findVariable(s);
|
||||
sym = findVariable(s, variables);
|
||||
if (sym != NULL)
|
||||
{
|
||||
//printf("match |%s|\n",sym->var_text.c_str());
|
||||
|
@ -1929,6 +2008,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);
|
||||
|
||||
|
@ -1963,7 +2043,42 @@ void CLASS::process(void)
|
|||
l = lines.size();
|
||||
while ((lineno < l) && (!passcomplete))
|
||||
{
|
||||
MerlinLine &line = lines[lineno];
|
||||
|
||||
MerlinLine *ml = NULL;
|
||||
bool srcline = true;
|
||||
if (expand_macro.running)
|
||||
{
|
||||
srcline = false;
|
||||
if (expand_macro.currentline >= expand_macro.len)
|
||||
{
|
||||
// macro is complete
|
||||
lineno = expand_macro.sourceline + 1;
|
||||
if (expand_macrostack.size() > 0)
|
||||
{
|
||||
expand_macro = expand_macrostack.top();
|
||||
expand_macrostack.pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
expand_macro.clear();
|
||||
}
|
||||
srcline = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ml = &expand_macro.lines[expand_macro.currentline];
|
||||
lineno = expand_macro.sourceline;
|
||||
expand_macro.currentline++;
|
||||
}
|
||||
}
|
||||
if (srcline)
|
||||
{
|
||||
ml = &lines[lineno];
|
||||
}
|
||||
|
||||
MerlinLine &line = *ml;
|
||||
|
||||
//printf("lineno=%u %s\n", lineno, line.wholetext.c_str());
|
||||
|
||||
line.eval_result = 0;
|
||||
line.lineno = lineno + 1;
|
||||
|
@ -1991,7 +2106,7 @@ void CLASS::process(void)
|
|||
case ']':
|
||||
sprintf(buff, "$%X", PC.currentpc);
|
||||
ls = buff;
|
||||
sym = addVariable(line.lable, ls, true);
|
||||
sym = addVariable(line.lable, ls, variables, true);
|
||||
//if (sym == NULL) { dupsym = true; }
|
||||
break;
|
||||
|
||||
|
@ -2019,10 +2134,8 @@ void CLASS::process(void)
|
|||
}
|
||||
}
|
||||
std::string outop;
|
||||
if (pass == 0)
|
||||
{
|
||||
line.printoperand = line.operand;
|
||||
}
|
||||
line.printoperand = line.operand;
|
||||
|
||||
x = substituteVariables(line, outop);
|
||||
if (x > 0)
|
||||
{
|
||||
|
@ -2051,7 +2164,31 @@ 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
|
||||
{
|
||||
expand_macrostack.push(expand_macro);
|
||||
expand_macro = *mac;
|
||||
|
||||
expand_macro.lines.clear();
|
||||
//printf("mac start=%u end=%u\n", expand_macro.start, expand_macro.end);
|
||||
for (uint32_t lc = expand_macro.start; lc < expand_macro.end; lc++)
|
||||
{
|
||||
//printf("pushing %s\n", lines[lc].wholetext.c_str());
|
||||
MerlinLine nl(lines[lc].wholetext); // create a new clean line (without errors,data)
|
||||
expand_macro.lines.push_back(nl);
|
||||
}
|
||||
expand_macro.running = true;
|
||||
expand_macro.sourceline = lineno;
|
||||
expand_macro.variables.clear();
|
||||
// set the variables for the macro here SGQ
|
||||
expand_macro.currentline = 0;
|
||||
x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((x > 0) && (codeSkipped())) // has a psuedo-op turned off code generation? (LUP, IF, etc)
|
||||
|
@ -2100,7 +2237,10 @@ void CLASS::process(void)
|
|||
{
|
||||
if ((line.pass0bytect != line.bytect) && (line.errorcode == 0))
|
||||
{
|
||||
line.setError(errBadByteCount);
|
||||
if (expand_macrostack.size() == 0) // if macro expanding, you can't make this check
|
||||
{
|
||||
line.setError(errBadByteCount);
|
||||
}
|
||||
}
|
||||
|
||||
if (line.errorcode != 0)
|
||||
|
|
74
asm.h
74
asm.h
|
@ -144,6 +144,7 @@ enum
|
|||
syn_MAX
|
||||
};
|
||||
|
||||
|
||||
class TOriginSection
|
||||
{
|
||||
// SGQ - if you do something unusual here, be aware of copy constructor
|
||||
|
@ -190,6 +191,7 @@ class MerlinLine
|
|||
public:
|
||||
|
||||
uint32_t syntax;
|
||||
std::string wholetext;
|
||||
std::string lable;
|
||||
std::string printlable;
|
||||
std::string printoperand;
|
||||
|
@ -280,11 +282,12 @@ public:
|
|||
{
|
||||
clear();
|
||||
}
|
||||
void clear(void) {
|
||||
lupct=0;
|
||||
lupoffset=0;
|
||||
luprunning=0;
|
||||
lupskip=false;
|
||||
void clear(void)
|
||||
{
|
||||
lupct = 0;
|
||||
lupoffset = 0;
|
||||
luprunning = 0;
|
||||
lupskip = false;
|
||||
}
|
||||
uint16_t lupct;
|
||||
bool lupskip;
|
||||
|
@ -299,9 +302,10 @@ public:
|
|||
{
|
||||
clear();
|
||||
}
|
||||
void clear(void) {
|
||||
doskip=false;
|
||||
value=0;
|
||||
void clear(void)
|
||||
{
|
||||
doskip = false;
|
||||
value = 0;
|
||||
}
|
||||
uint32_t value;
|
||||
bool doskip;
|
||||
|
@ -334,7 +338,7 @@ public:
|
|||
value = 0;
|
||||
used = false;
|
||||
//text = "";
|
||||
var_text="";
|
||||
var_text = "";
|
||||
name = "";
|
||||
namelc = "";
|
||||
stype = 0;
|
||||
|
@ -343,6 +347,38 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
typedef Poco::HashMap<std::string, TSymbol> variable_t;
|
||||
|
||||
class TMacro
|
||||
{
|
||||
public:
|
||||
std::string name;
|
||||
std::string lcname;
|
||||
variable_t variables;
|
||||
std::vector<MerlinLine> lines;
|
||||
uint32_t start,end,currentline,len;
|
||||
uint32_t sourceline;
|
||||
bool running;
|
||||
|
||||
TMacro()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
void clear(void)
|
||||
{
|
||||
name="";
|
||||
lcname="";
|
||||
variables.clear();
|
||||
lines.clear();
|
||||
sourceline=0;
|
||||
currentline=0;
|
||||
len=0;
|
||||
start = 0;
|
||||
end=0;
|
||||
running = false;
|
||||
}
|
||||
};
|
||||
|
||||
class TPsuedoOp;
|
||||
|
||||
class T65816Asm : public TFileProcessor
|
||||
|
@ -371,14 +407,16 @@ public:
|
|||
|
||||
std::string currentsymstr;
|
||||
std::vector<MerlinLine> lines;
|
||||
Poco::HashMap<std::string, TSymbol>opcodes;
|
||||
Poco::HashMap<std::string, TSymbol> macros;
|
||||
Poco::HashMap<std::string, TMacro> macros;
|
||||
Poco::HashMap<std::string, TSymbol> opcodes;
|
||||
Poco::HashMap<std::string, TSymbol> symbols;
|
||||
Poco::HashMap<std::string, TSymbol> variables;
|
||||
variable_t variables;
|
||||
|
||||
TOriginSection PC;
|
||||
TLUPstruct curLUP;
|
||||
TDOstruct curDO;
|
||||
TMacro currentmacro;
|
||||
TMacro expand_macro;
|
||||
bool listing;
|
||||
uint8_t truncdata; // for the TR opcode
|
||||
|
||||
|
@ -386,6 +424,8 @@ public:
|
|||
std::stack<TLUPstruct> LUPstack;
|
||||
std::stack<TDOstruct> DOstack;
|
||||
std::stack<bool> LSTstack;
|
||||
std::stack<TMacro> macrostack;
|
||||
std::stack<TMacro> expand_macrostack;
|
||||
|
||||
TPsuedoOp *psuedoops;
|
||||
|
||||
|
@ -403,15 +443,19 @@ 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);
|
||||
TSymbol *addVariable(std::string sym, std::string val, bool replace);
|
||||
TSymbol *findVariable(std::string sym, variable_t &vars);
|
||||
TSymbol *addVariable(std::string sym, std::string val, variable_t &vars,bool replace);
|
||||
|
||||
|
||||
void initpass(void);
|
||||
void showSymbolTable(bool alpha);
|
||||
void showVariables(void);
|
||||
void showMacros(bool alpha);
|
||||
|
||||
void showVariables(variable_t &vars);
|
||||
int evaluate(MerlinLine &line, std::string expr, int64_t &value);
|
||||
|
||||
int substituteVariables(MerlinLine & line, std::string &outop);
|
||||
|
|
2
eval.cpp
2
eval.cpp
|
@ -665,7 +665,7 @@ int CLASS::evaluate(std::string & e, int64_t &res, uint8_t &_shiftmode)
|
|||
}
|
||||
else if (token.str == "<")
|
||||
{
|
||||
//rhs = (rhs << 8 ) & 0xFFFF;
|
||||
//rhs = (rhs) & 0xFFFF;
|
||||
}
|
||||
else if (token.str == ">")
|
||||
{
|
||||
|
|
40
merlintests.sh
Executable file
40
merlintests.sh
Executable file
|
@ -0,0 +1,40 @@
|
|||
#!/bin/bash
|
||||
|
||||
X=
|
||||
if [ "$1""L" != "L" ] ; then
|
||||
X=_$1
|
||||
fi
|
||||
|
||||
OUTDIR=./m32out
|
||||
|
||||
rm -rf $OUTDIR
|
||||
mkdir -p $OUTDIR
|
||||
|
||||
SRC=`ls ./testdata | grep -E '^([0-9]+)(.*)\.[Ss]'`
|
||||
|
||||
#SRC=`ls ./testdata | grep -E '^([0-9]+)(.*)\.[Ss]' | grep -i 2007`
|
||||
|
||||
for S in $SRC ; do
|
||||
|
||||
S1=$S
|
||||
S1=${S1/.S/}
|
||||
S1=${S1/.s/}
|
||||
|
||||
BASE=${S/.S/}
|
||||
BASE=${BASE/.s/}
|
||||
cd ./testdata
|
||||
merlin32$X . $S 2>/dev/null >/dev/null
|
||||
#merlin32 . $S 2>/dev/null
|
||||
|
||||
R=?$
|
||||
cd - >/dev/null
|
||||
cp ./testdata/$S1 $OUTDIR/$S1.bin 2>/dev/null
|
||||
rm -f ./testdata/*.txt 2>/dev/null
|
||||
rm -f ./testdata/$S1 2>/dev/null
|
||||
R=?$
|
||||
|
||||
done
|
||||
ls $OUTDIR
|
||||
|
||||
|
||||
|
19
opcodes.cpp
19
opcodes.cpp
|
@ -99,10 +99,10 @@ int CLASS::doEQU(MerlinLine &line, TSymbol &sym)
|
|||
char buff[32];
|
||||
sprintf(buff, "$%08X", line.expr_value);
|
||||
std::string s1 = buff;
|
||||
s = addVariable(line.lable, s1, true);
|
||||
s = addVariable(line.lable, s1, variables,true);
|
||||
#else
|
||||
// do this if you want to do this more as a #define
|
||||
s = addVariable(line.lable, line.operand, true);
|
||||
s = addVariable(line.lable, line.operand, variables,true);
|
||||
#endif
|
||||
if (s != NULL)
|
||||
{
|
||||
|
@ -194,9 +194,14 @@ int CLASS::doMVN(MerlinLine &line, TSymbol &sym)
|
|||
//line.errorText = line.operand_expr2;
|
||||
}
|
||||
|
||||
uint32_t v=(value & 0xFFFFFFFF);
|
||||
//printf("val1 %08X\n",v);
|
||||
//printf("val1 %08X\n",line.expr_value);
|
||||
|
||||
setOpcode(line, op);
|
||||
line.outbytes.push_back(value & 0xFF);
|
||||
line.outbytes.push_back(line.expr_value & 0xFF);
|
||||
// these bytes are the two bank registers
|
||||
line.outbytes.push_back((v>>16) & 0xFF);
|
||||
line.outbytes.push_back((line.expr_value>>16) & 0xFF);
|
||||
|
||||
line.outbytect = res;
|
||||
}
|
||||
|
@ -880,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));
|
||||
|
|
98
psuedo.cpp
98
psuedo.cpp
|
@ -18,15 +18,15 @@ uint32_t CLASS::doShift(uint32_t value, uint8_t shift)
|
|||
{
|
||||
if (shift == '<')
|
||||
{
|
||||
value = (value) & 0xFF;
|
||||
value = (value) & 0xFFFFFF;
|
||||
}
|
||||
if (shift == '>')
|
||||
{
|
||||
value = (value >> 8) & 0xFF;
|
||||
value = (value >> 8) & 0xFFFFFF;
|
||||
}
|
||||
else if ((shift == '^') || (shift == '|'))
|
||||
{
|
||||
value = (value >> 16) & 0xFF;
|
||||
value = (value >> 16) & 0xFFFFFF;
|
||||
}
|
||||
return (value);
|
||||
}
|
||||
|
@ -130,6 +130,73 @@ 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;
|
||||
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 - 1;
|
||||
a.currentmacro.len = 0;
|
||||
if (a.currentmacro.end >= a.currentmacro.start)
|
||||
{
|
||||
a.currentmacro.len = a.currentmacro.end - a.currentmacro.start;
|
||||
}
|
||||
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 +407,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 +421,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 +487,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 +911,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 +925,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);
|
||||
|
|
3
psuedo.h
3
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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
OUTDIR=./testout
|
||||
OUTDIR=./qasmout
|
||||
TMPFILE=/tmp/qasm_out.txt
|
||||
|
||||
rm -f $TMPFILE
|
||||
|
@ -40,14 +40,15 @@ for S in $SRC ; do
|
|||
MSHA="Q"
|
||||
QSHA="M"
|
||||
|
||||
if [ -f ./testdata/M32_expected/$BASE ] ; then
|
||||
MSHA=`sha256sum ./testdata/M32_expected/$BASE | awk '{ print $1;}'` 2>/dev/null >/dev/null
|
||||
|
||||
if [ -f ./m32out/$BASE.bin ] ; then
|
||||
MSHA=`sha256sum ./m32out/$BASE.bin | awk '{ print $1;}'` 2>/dev/null >/dev/null
|
||||
fi
|
||||
|
||||
if [ -f $OUTDIR/$BASE.bin ] ; then
|
||||
QSHA=`sha256sum $OUTDIR/$BASE.bin |awk '{print $1;}'` 2>/dev/null >/dev/null
|
||||
fi
|
||||
#echo "$MSHA $QSHA"
|
||||
#echo "MSHA=$MSHA QSHA=$QSHA"
|
||||
|
||||
shapass=0;
|
||||
CX=" "
|
||||
|
|
4
testdata/1000-allops-value-65816.S
vendored
4
testdata/1000-allops-value-65816.S
vendored
|
@ -5,7 +5,7 @@
|
|||
ZP EQU $FF
|
||||
ABS EQU $FEFF
|
||||
LONG EQU $FDFEFF
|
||||
MV0 EQU ZP ;Merlin 32 bug -- must use 8-bit constant, or
|
||||
MV1 EQU ZP-1 ; '^' modifier is implicitly applied
|
||||
MV0 EQU LONG ;Merlin 32 bug -- must use 8-bit constant, or
|
||||
MV1 EQU LONG-$10000 ; '^' modifier is implicitly applied
|
||||
|
||||
PUT allops-common-65816.S
|
||||
|
|
8
testdata/2007-labels-and-symbols.S
vendored
8
testdata/2007-labels-and-symbols.S
vendored
|
@ -219,13 +219,13 @@ next
|
|||
:skiphex
|
||||
|
||||
; extract bytes from 32-bit value with short regs
|
||||
lda #<thirty2 + 2
|
||||
lda #>thirty2 + 768
|
||||
lda #<thirty2+2
|
||||
lda #>thirty2+768
|
||||
lda #^thirty2
|
||||
rep #$30
|
||||
mx %00
|
||||
lda #<thirty2 + 3
|
||||
lda #>thirty2 + 1024
|
||||
lda #<thirty2+3
|
||||
lda #>thirty2+1024
|
||||
lda #^thirty2
|
||||
|
||||
rts
|
||||
|
|
28
testdata/3000-addresses.S
vendored
Normal file
28
testdata/3000-addresses.S
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
lst
|
||||
xc
|
||||
xc
|
||||
org $018200
|
||||
|
||||
bank02 equ $020000
|
||||
bank03 equ $030000
|
||||
dp equ $A5
|
||||
long equ $020304
|
||||
|
||||
mx %00
|
||||
start nop
|
||||
pea ^start
|
||||
pea start
|
||||
mvn bank02,bank03
|
||||
mvp bank03,bank02
|
||||
lda dp
|
||||
lda <dp
|
||||
lda >dp
|
||||
lda ^dp
|
||||
lda |dp
|
||||
lda #long
|
||||
lda #<long
|
||||
lda #>long
|
||||
lda #^long
|
||||
lda #long
|
||||
|
||||
lst off
|
10
src/main.s → testdata/3001-lroathe.S
vendored
10
src/main.s → testdata/3001-lroathe.S
vendored
|
@ -114,7 +114,7 @@ START
|
|||
adc _num1+dum1
|
||||
sbc _num1+dum1
|
||||
bit _num1+dum0
|
||||
sta _num1+dum0 ;(FIXED): can't use sta _num1+dum0
|
||||
sta _num1+dum0 ;(FIXED): can't use sta _num1+dum0 '
|
||||
stz _num1+dum0
|
||||
|
||||
lda _num1+dum0,x
|
||||
|
@ -180,7 +180,7 @@ myQuit
|
|||
|
||||
|
||||
ldaz $FFFF ; forced DP
|
||||
lda: $FFFF ; forced ABS (any char but 'L', 'D', and 'Z"
|
||||
lda: $FFFF ; forced ABS (any char but 'L', 'D', and 'Z'
|
||||
ldal $FFFF ; forced long abs (3 byte address)
|
||||
|
||||
ldaz $05
|
||||
|
@ -338,8 +338,6 @@ myQuit
|
|||
lda #^$A51234 ;bank
|
||||
|
||||
|
||||
mx MX
|
||||
|
||||
lda $0008 ;ZP
|
||||
lda $08 ;ZP
|
||||
lda $ffff-$fff7 ;ZP
|
||||
|
@ -362,8 +360,8 @@ L00BC bit L00BC
|
|||
|
||||
hex ;no error
|
||||
hex 11,22,33,44,55,66,77,88,99
|
||||
hex 112233445566778899F
|
||||
hex 112233445I566778899FF
|
||||
;hex 112233445566778899F
|
||||
;hex 112233445I566778899FF
|
||||
|
||||
hex aabb,CC,0123456789abcdefABCDEF,ff
|
||||
|
4
src/testfile.s → testdata/3002-testfile.S
vendored
4
src/testfile.s → testdata/3002-testfile.S
vendored
|
@ -14,7 +14,7 @@ lexpr = $010203
|
|||
immed = $123456
|
||||
neg equ -16
|
||||
|
||||
]var1 = v1234
|
||||
*]var1 = v1234
|
||||
|
||||
;lst off
|
||||
start00
|
||||
|
@ -308,5 +308,5 @@ startF0
|
|||
inc expr,x
|
||||
sbcl lexpr,x
|
||||
lst off
|
||||
sav ./test.bin
|
||||
;sav ./test.bin
|
||||
|
6
src/var.s → testdata/3003-var.S
vendored
6
src/var.s → testdata/3003-var.S
vendored
|
@ -13,13 +13,13 @@ start nop
|
|||
ldy #$00
|
||||
]loop sta $800,y
|
||||
dey
|
||||
bne ]loop;]loop2
|
||||
bne ]myvar;
|
||||
;dw ]loop;]loop2
|
||||
;bne ]myvar;
|
||||
|
||||
bcs ]loop
|
||||
bpl ]loop
|
||||
rts
|
||||
|
||||
use var
|
||||
;use var
|
||||
lst on
|
||||
|
BIN
testdata/M32_expected/1000-allops-value-65816
vendored
BIN
testdata/M32_expected/1000-allops-value-65816
vendored
Binary file not shown.
BIN
testdata/M32_expected/1001-allops-zero-65816
vendored
BIN
testdata/M32_expected/1001-allops-zero-65816
vendored
Binary file not shown.
BIN
testdata/M32_expected/1002-embedded-instructions
vendored
BIN
testdata/M32_expected/1002-embedded-instructions
vendored
Binary file not shown.
BIN
testdata/M32_expected/1003-flags-and-branches
vendored
BIN
testdata/M32_expected/1003-flags-and-branches
vendored
Binary file not shown.
BIN
testdata/M32_expected/1004-data-recognition
vendored
BIN
testdata/M32_expected/1004-data-recognition
vendored
Binary file not shown.
BIN
testdata/M32_expected/2000-allops-value-6502
vendored
BIN
testdata/M32_expected/2000-allops-value-6502
vendored
Binary file not shown.
BIN
testdata/M32_expected/2001-allops-zero-6502
vendored
BIN
testdata/M32_expected/2001-allops-zero-6502
vendored
Binary file not shown.
BIN
testdata/M32_expected/2002-allops-value-65C02
vendored
BIN
testdata/M32_expected/2002-allops-value-65C02
vendored
Binary file not shown.
BIN
testdata/M32_expected/2003-allops-zero-65C02
vendored
BIN
testdata/M32_expected/2003-allops-zero-65C02
vendored
Binary file not shown.
BIN
testdata/M32_expected/2004-numeric-types
vendored
BIN
testdata/M32_expected/2004-numeric-types
vendored
Binary file not shown.
BIN
testdata/M32_expected/2005-string-types
vendored
BIN
testdata/M32_expected/2005-string-types
vendored
Binary file not shown.
BIN
testdata/M32_expected/2006-operand-formats
vendored
BIN
testdata/M32_expected/2006-operand-formats
vendored
Binary file not shown.
BIN
testdata/M32_expected/2007-labels-and-symbols
vendored
BIN
testdata/M32_expected/2007-labels-and-symbols
vendored
Binary file not shown.
BIN
testdata/M32_expected/2008-address-changes
vendored
BIN
testdata/M32_expected/2008-address-changes
vendored
Binary file not shown.
BIN
testdata/M32_expected/2010-target-adjustment
vendored
BIN
testdata/M32_expected/2010-target-adjustment
vendored
Binary file not shown.
2
testdata/M32_expected/2011-hinting
vendored
2
testdata/M32_expected/2011-hinting
vendored
|
@ -1,2 +0,0 @@
|
|||
,,©ę,˘˙ę
|
||||
ę,˘˙ę V$©˘" ( V$©3˘D : =ęV$ E` V$©U˘f`<60>‚<EFBFBD>©™`
|
BIN
testdata/M32_expected/2012-label-localizer
vendored
BIN
testdata/M32_expected/2012-label-localizer
vendored
Binary file not shown.
BIN
testdata/M32_expected/2013-notes-and-comments
vendored
BIN
testdata/M32_expected/2013-notes-and-comments
vendored
Binary file not shown.
BIN
testdata/M32_expected/2014-label-dp
vendored
BIN
testdata/M32_expected/2014-label-dp
vendored
Binary file not shown.
BIN
testdata/M32_expected/2019-local-variables
vendored
BIN
testdata/M32_expected/2019-local-variables
vendored
Binary file not shown.
BIN
testdata/M32_expected/2020-cycle-counts-65816
vendored
BIN
testdata/M32_expected/2020-cycle-counts-65816
vendored
Binary file not shown.
BIN
testdata/M32_expected/2021-external-symbols
vendored
BIN
testdata/M32_expected/2021-external-symbols
vendored
Binary file not shown.
BIN
testdata/M32_expected/2022-extension-scripts
vendored
BIN
testdata/M32_expected/2022-extension-scripts
vendored
Binary file not shown.
Loading…
Reference in New Issue
Block a user