mirror of
https://github.com/marketideas/qasm.git
synced 2024-06-03 00:29:53 +00:00
fixed a few bugs, got more tests to pass, added some parms.json options
This commit is contained in:
parent
2f79abe461
commit
6e9eb6cfcc
11
.gitignore
vendored
11
.gitignore
vendored
|
@ -1,3 +1,14 @@
|
||||||
**/build
|
**/build
|
||||||
|
**/testdata1
|
||||||
|
*.bin
|
||||||
|
*.BIN
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
Finder.Data
|
||||||
|
test.s
|
||||||
|
disk_commands.txt
|
||||||
|
.vscode/browse*
|
||||||
|
.vscode/book*
|
||||||
|
|
||||||
*.xcuserstate
|
*.xcuserstate
|
||||||
*.xcbkptlist
|
*.xcbkptlist
|
||||||
|
|
296
asm.cpp
296
asm.cpp
|
@ -217,11 +217,13 @@ void CLASS::print(uint32_t lineno)
|
||||||
if (printoperand.length() > 0)
|
if (printoperand.length() > 0)
|
||||||
{
|
{
|
||||||
pcol += printf("%s ", printoperand.c_str());
|
pcol += printf("%s ", printoperand.c_str());
|
||||||
|
//pcol += printf("%s ", orig_operand.c_str());
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pcol += printf("%s ", operand.c_str());
|
pcol += printf("%s ", printoperand.c_str());
|
||||||
|
//pcol += printf("%s ", orig_operand.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//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());
|
||||||
|
@ -309,6 +311,7 @@ void CLASS::clear()
|
||||||
opcodelower = "";
|
opcodelower = "";
|
||||||
operand = "";
|
operand = "";
|
||||||
printoperand = "";
|
printoperand = "";
|
||||||
|
orig_operand="";
|
||||||
comment = "";
|
comment = "";
|
||||||
operand_expr = "";
|
operand_expr = "";
|
||||||
operand_expr2 = "";
|
operand_expr2 = "";
|
||||||
|
@ -494,6 +497,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];
|
||||||
|
orig_operand=operand;
|
||||||
//printf("which=%d operand=|%s|\n",ct,operand.c_str());
|
//printf("which=%d operand=|%s|\n",ct,operand.c_str());
|
||||||
i = (int)operand.length();
|
i = (int)operand.length();
|
||||||
restofline = restofline.substr(i, restofline.length());
|
restofline = restofline.substr(i, restofline.length());
|
||||||
|
@ -579,7 +583,9 @@ void CLASS::init(void)
|
||||||
filecount = 0;
|
filecount = 0;
|
||||||
syntax = SYNTAX_QASM;
|
syntax = SYNTAX_QASM;
|
||||||
|
|
||||||
std::string tabstr = getConfig("reformat.tabs", "8,16,32");
|
//std::string tabstr = getConfig("reformat.tabs", "8,16,32");
|
||||||
|
std::string tabstr = getConfig("reformat.tabs", "12,24,40,70");
|
||||||
|
|
||||||
tabstr = Poco::trim(tabstr);
|
tabstr = Poco::trim(tabstr);
|
||||||
|
|
||||||
memset(tabs, 0x00, sizeof(tabs));
|
memset(tabs, 0x00, sizeof(tabs));
|
||||||
|
@ -722,7 +728,7 @@ std::string CLASS::processFilename(std::string fn, std::string curDir, int level
|
||||||
int CLASS::processfile(std::string p, std::string &newfilename)
|
int CLASS::processfile(std::string p, std::string &newfilename)
|
||||||
{
|
{
|
||||||
//Poco::File fn(p);
|
//Poco::File fn(p);
|
||||||
int c;
|
int c,c1;
|
||||||
int res = -1;
|
int res = -1;
|
||||||
uint32_t linect;
|
uint32_t linect;
|
||||||
bool done, valid;
|
bool done, valid;
|
||||||
|
@ -804,7 +810,7 @@ int CLASS::processfile(std::string p, std::string &newfilename)
|
||||||
}
|
}
|
||||||
if ((fn.isDirectory()) || (!fn.canRead()))
|
if ((fn.isDirectory()) || (!fn.canRead()))
|
||||||
{
|
{
|
||||||
LOG_DEBUG << "File is a directory: " << p1 << endl;
|
LOG_DEBUG << "File is a directory or can not read: " << p1 << endl;
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -847,22 +853,34 @@ int CLASS::processfile(std::string p, std::string &newfilename)
|
||||||
{
|
{
|
||||||
//printf("file is open\n");
|
//printf("file is open\n");
|
||||||
line = "";
|
line = "";
|
||||||
|
|
||||||
while ((!done) && (f.good()) && (!f.eof()))
|
while ((!done) && (f.good()) && (!f.eof()))
|
||||||
{
|
{
|
||||||
c = f.get();
|
c = f.get();
|
||||||
|
c1 = c & 0x7F;
|
||||||
if (c == 0x8D) // merlin line ending
|
if (c == 0x8D) // merlin line ending
|
||||||
{
|
{
|
||||||
c = 0x0A; // convert to linux
|
c = 0x0A; // convert to linux
|
||||||
}
|
}
|
||||||
if (c == 0x8A) // possible merlin line ending
|
else if (c == 0x8A) // possible merlin line ending
|
||||||
{
|
{
|
||||||
c = 0x00; // ignore
|
c = 0x0D; // ignore
|
||||||
|
}
|
||||||
|
else if ((c1<0x20) || (c1==127)) // see if it might be a control character
|
||||||
|
{
|
||||||
|
if ((c1==0x0D) || (c1==0x0A) || (c1==0x09))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c=0x00;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c &= 0x7F;
|
c &= 0x7F;
|
||||||
int x;
|
int x;
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
|
case 0x00:
|
||||||
case 0x0D:
|
case 0x0D:
|
||||||
break;
|
break;
|
||||||
case 0x09:
|
case 0x09:
|
||||||
|
@ -870,6 +888,7 @@ int CLASS::processfile(std::string p, std::string &newfilename)
|
||||||
break;
|
break;
|
||||||
case 0x0A:
|
case 0x0A:
|
||||||
linect++;
|
linect++;
|
||||||
|
line=Poco::trimRight(line); //get rid of any space at end of line
|
||||||
x = doline(linect, line);
|
x = doline(linect, line);
|
||||||
if (x < 0)
|
if (x < 0)
|
||||||
{
|
{
|
||||||
|
@ -907,36 +926,11 @@ int CLASS::processfile(std::string p, std::string &newfilename)
|
||||||
return (res);
|
return (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef CLASS
|
|
||||||
#define CLASS TImageProcessor
|
|
||||||
|
|
||||||
CLASS::CLASS() : TFileProcessor()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
CLASS::~TImageProcessor()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int CLASS::doline(int lineno, std::string line)
|
|
||||||
{
|
|
||||||
printf("%05d: %s\n",lineno,line.c_str());
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
void CLASS::process(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
void CLASS::complete(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef CLASS
|
#undef CLASS
|
||||||
#define CLASS TMerlinConverter
|
#define CLASS TMerlinConverter
|
||||||
CLASS::CLASS() : TFileProcessor()
|
CLASS::CLASS() : TFileProcessor()
|
||||||
{
|
{
|
||||||
|
format_flags=CONVERT_TEST;
|
||||||
}
|
}
|
||||||
CLASS::~CLASS()
|
CLASS::~CLASS()
|
||||||
{
|
{
|
||||||
|
@ -962,72 +956,130 @@ void CLASS::process(void)
|
||||||
|
|
||||||
char buff[128*1024];
|
char buff[128*1024];
|
||||||
uint32_t ct = (uint32_t)lines.size();
|
uint32_t ct = (uint32_t)lines.size();
|
||||||
uint8_t orval=0x80;
|
uint8_t orval=0x00;
|
||||||
|
uint32_t flags;
|
||||||
|
string s;
|
||||||
|
int llen,oplen,operlen,comlen;
|
||||||
|
string lable,opcode,operand,comment;
|
||||||
|
|
||||||
uint32_t len, tlen,t, pos,i;
|
uint32_t len, tlen,t, pos,i;
|
||||||
|
|
||||||
tlen=0;
|
tlen=0;
|
||||||
|
flags=format_flags;
|
||||||
|
|
||||||
for (uint32_t lineno = 0; lineno < ct; lineno++)
|
for (uint32_t lineno = 0; lineno < ct; lineno++)
|
||||||
{
|
{
|
||||||
MerlinLine &line = lines.at(lineno);
|
MerlinLine &line = lines.at(lineno);
|
||||||
|
orval=0x00;
|
||||||
|
if (flags&CONVERT_HIGH)
|
||||||
|
{
|
||||||
|
orval=0x80;
|
||||||
|
}
|
||||||
len=0;
|
len=0;
|
||||||
pos = 0;
|
pos = 0;
|
||||||
if ((line.lable.length() == 0)
|
|
||||||
&& (line.opcode.length() == 0)
|
lable=Poco::trimRight(line.printlable);
|
||||||
&& (line.operand.length() == 0))
|
llen=lable.length();
|
||||||
|
opcode=Poco::trimRight(line.opcode);
|
||||||
|
oplen=opcode.length();
|
||||||
|
operand=Poco::trimRight(line.operand);
|
||||||
|
operlen=operand.length();
|
||||||
|
comment=Poco::trimRight(line.comment);
|
||||||
|
comlen=comment.length();
|
||||||
|
|
||||||
|
if ((llen+oplen+operlen)==0)
|
||||||
{
|
{
|
||||||
if (line.comment.length() > 0)
|
if (comlen > 0)
|
||||||
{
|
{
|
||||||
char c = line.comment[0];
|
char c = comment[0];
|
||||||
if ((c == '*') || (c == '/'))
|
if ((c == '*') || (c == '/'))
|
||||||
{
|
{
|
||||||
sprintf(&buff[len+tlen],"%s", line.comment.c_str());
|
len+=sprintf(&buff[len+tlen],"%s", comment.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
t = tabs[2];
|
t = tabs[2];
|
||||||
|
if (flags&CONVERT_COMPRESS)
|
||||||
|
{
|
||||||
|
len += sprintf(&buff[len+tlen]," ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
while (len < t)
|
while (len < t)
|
||||||
{
|
{
|
||||||
len += sprintf(&buff[len+tlen]," ");
|
len += sprintf(&buff[len+tlen]," ");
|
||||||
}
|
}
|
||||||
sprintf(&buff[len+tlen],"%s", line.comment.c_str());
|
}
|
||||||
|
len+=sprintf(&buff[len+tlen],"%s", comment.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sprintf(&buff[len+tlen],"\r");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
t = tabs[pos++];
|
t = tabs[pos++];
|
||||||
len = sprintf(&buff[len+tlen],"%s ", line.printlable.c_str());
|
len += sprintf(&buff[len+tlen],"%s", lable.c_str());
|
||||||
while (len < t)
|
if ((oplen+operlen+comlen)>0)
|
||||||
|
{
|
||||||
|
if (flags&CONVERT_COMPRESS)
|
||||||
{
|
{
|
||||||
len += sprintf(&buff[len+tlen]," ");
|
len += sprintf(&buff[len+tlen]," ");
|
||||||
}
|
}
|
||||||
|
|
||||||
t = tabs[pos++];
|
|
||||||
len += sprintf(&buff[len+tlen],"%s ", line.opcode.c_str());
|
|
||||||
while (len < t)
|
|
||||||
{
|
|
||||||
len += sprintf(&buff[len+tlen]," ");
|
|
||||||
}
|
|
||||||
|
|
||||||
t = tabs[pos++];
|
|
||||||
len += sprintf(&buff[len+tlen],"%s ", line.operand.c_str());
|
|
||||||
while (len < t)
|
|
||||||
{
|
|
||||||
len += sprintf(&buff[len+tlen]," ");
|
|
||||||
}
|
|
||||||
|
|
||||||
t = tabs[pos++];
|
|
||||||
len += sprintf(&buff[len+tlen],"%s", line.comment.c_str());
|
|
||||||
while (len < t)
|
|
||||||
{
|
|
||||||
len += sprintf(&buff[len+tlen]," ");
|
|
||||||
}
|
|
||||||
if (syntax ==SYNTAX_MERLIN)
|
|
||||||
len += sprintf(&buff[len+tlen],"\r");
|
|
||||||
else
|
else
|
||||||
len += sprintf(&buff[len+tlen],"\n");
|
{
|
||||||
|
while (len < t)
|
||||||
|
{
|
||||||
|
len += sprintf(&buff[len+tlen]," ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t = tabs[pos++];
|
||||||
|
len += sprintf(&buff[len+tlen],"%s", opcode.c_str());
|
||||||
|
if ((operlen+comlen)>0)
|
||||||
|
{
|
||||||
|
if (flags&CONVERT_COMPRESS)
|
||||||
|
{
|
||||||
|
len += sprintf(&buff[len+tlen]," ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (len < t)
|
||||||
|
{
|
||||||
|
len += sprintf(&buff[len+tlen]," ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t = tabs[pos++];
|
||||||
|
len += sprintf(&buff[len+tlen],"%s", operand.c_str());
|
||||||
|
if ((comlen)>0)
|
||||||
|
{
|
||||||
|
if (flags&CONVERT_COMPRESS)
|
||||||
|
{
|
||||||
|
len += sprintf(&buff[len+tlen]," ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (len < t)
|
||||||
|
{
|
||||||
|
len += sprintf(&buff[len+tlen]," ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len += sprintf(&buff[len+tlen],"%s", comment.c_str());
|
||||||
|
}
|
||||||
|
if (flags&CONVERT_CRLF)
|
||||||
|
{
|
||||||
|
len+=sprintf(&buff[len+tlen],"\r\n");
|
||||||
|
}
|
||||||
|
else if (flags&CONVERT_LF)
|
||||||
|
{
|
||||||
|
len+=sprintf(&buff[len+tlen],"\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len+=sprintf(&buff[len+tlen],"\r");
|
||||||
}
|
}
|
||||||
tlen+=len;
|
tlen+=len;
|
||||||
}
|
}
|
||||||
|
@ -1035,45 +1087,58 @@ void CLASS::process(void)
|
||||||
if (tlen>0)
|
if (tlen>0)
|
||||||
{
|
{
|
||||||
int tct=0;
|
int tct=0;
|
||||||
|
int idx=0;
|
||||||
for (i=0; i<tlen; i++)
|
for (i=0; i<tlen; i++)
|
||||||
{
|
{
|
||||||
char c=buff[i];
|
char c=buff[i];
|
||||||
if (c==0x20)
|
if (c==0x20)
|
||||||
{
|
{
|
||||||
if (tct<3)
|
if (tct<3)
|
||||||
buff[i]=0x20 | orval;
|
{
|
||||||
|
buff[idx++]=0x20 | orval;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buff[i]=0x20;
|
buff[idx++]=0x20;
|
||||||
}
|
}
|
||||||
tct++;
|
tct++;
|
||||||
}
|
}
|
||||||
else if (c==0x0D)
|
else if (c==0x0D)
|
||||||
{
|
{
|
||||||
buff[i]=0x0D;
|
buff[idx++]=0x0D | orval;
|
||||||
tct=0;
|
tct=0;
|
||||||
}
|
}
|
||||||
else if (c==0x0A)
|
else if (c==0x0A)
|
||||||
{
|
{
|
||||||
buff[i]=0x0D;
|
if ((flags&(CONVERT_COMPRESS|CONVERT_HIGH))==(CONVERT_COMPRESS | CONVERT_HIGH))
|
||||||
|
{
|
||||||
|
// don't allow any LFs if converting to merlin
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buff[idx++]=0x0A;
|
||||||
|
}
|
||||||
tct=0;
|
tct=0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buff[i]=c|orval;
|
buff[idx++]=c|orval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FILE *f=NULL;
|
FILE *f=NULL;
|
||||||
|
//string outfile=
|
||||||
f=fopen("./aout.s","w+");
|
f=fopen("./aout.s","w+");
|
||||||
if (f!=NULL)
|
if (f!=NULL)
|
||||||
{
|
{
|
||||||
fwrite(buff,1,tlen,f);
|
fwrite(buff,1,idx,f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
printf("file ok\n");
|
printf("file ok\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
printf("file error\n");
|
printf("file error\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLASS::complete(void)
|
void CLASS::complete(void)
|
||||||
|
@ -1227,7 +1292,25 @@ TSymbol * CLASS::findSymbol(std::string symname)
|
||||||
}
|
}
|
||||||
if (symname.length() > 0)
|
if (symname.length() > 0)
|
||||||
{
|
{
|
||||||
if (symname[0] == ':')
|
if (symname[0] == ']')
|
||||||
|
{
|
||||||
|
//printf("finding symbol: |%s|\n",symname.c_str());
|
||||||
|
res = findVariable(symname, variables);
|
||||||
|
if (res!=NULL)
|
||||||
|
{
|
||||||
|
//printf("symbol found: |%s| |%s|\n",symname.c_str(),res->var_text.c_str());
|
||||||
|
TEvaluator eval(*this);
|
||||||
|
int64_t er_val=0;
|
||||||
|
uint8_t shift=0;
|
||||||
|
int er;
|
||||||
|
er = eval.evaluate(res->var_text, er_val, shift);
|
||||||
|
if (er == 0)
|
||||||
|
{
|
||||||
|
res->value=er_val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (symname[0] == ':')
|
||||||
{
|
{
|
||||||
if (currentsym == NULL)
|
if (currentsym == NULL)
|
||||||
{
|
{
|
||||||
|
@ -1582,23 +1665,25 @@ const TaddrMode addrRegEx[] =
|
||||||
{ "^(?'expr'.+)\\,[s,S]{1}$", syn_s, "e,s"}, // expr,s
|
{ "^(?'expr'.+)\\,[s,S]{1}$", syn_s, "e,s"}, // expr,s
|
||||||
{"^[(]{1}(?'expr'.+)[,]{1}[(S|s)]{1}[)]{1}[,]{1}[(Y|y)]{1}$", syn_sy, "(e,s),y"}, // (expr,s),y
|
{"^[(]{1}(?'expr'.+)[,]{1}[(S|s)]{1}[)]{1}[,]{1}[(Y|y)]{1}$", syn_sy, "(e,s),y"}, // (expr,s),y
|
||||||
{"^#{1}(.+)$", syn_imm, "immediate"}, //#expr,#^expr,#|expr,#<expr,#>expr
|
{"^#{1}(.+)$", syn_imm, "immediate"}, //#expr,#^expr,#|expr,#<expr,#>expr
|
||||||
{"^[(]{1}(?'expr'.+)[,]{1}[x,X]{1}\\)$", syn_diix, "(e,x)"}, // (expr,x)
|
{"^[(]{1}(?'expr'.+)[,]{1}[x,X]{1}\\)$", syn_diix, "(dp,x)"}, // (expr,x)
|
||||||
{"^[(]{1}(?'expr'.+)[\\)]{1}[\\,][(Y|y]{1}$", syn_diiy, "(e),y"}, //(expr),y
|
{"^[(]{1}(?'expr'.+)[\\)]{1}[\\,][(Y|y]{1}$", syn_diiy, "(dp),y"}, //(expr),y
|
||||||
{"^[(]{1}(?'expr'.+)[\\)]{1}$", syn_di, "(e)"}, // (expr)
|
{"^[(]{1}(?'expr'.+)[\\)]{1}$", syn_di, "(dp)"}, // (expr)
|
||||||
{"^\\[{1}(?'expr'.+)\\]{1}[,]{1}[(Y|y)]{1}$", syn_iyl, "[e],y"}, // [expr],y
|
{"^\\[{1}(?'expr'.+)\\]{1}[,]{1}[(Y|y)]{1}$", syn_iyl, "[laddr],y"}, // [expr],y
|
||||||
{"^\\[(?'expr'.+)\\]$", syn_dil, "[e]"}, // [expr]
|
{"^\\[(?'expr'.+)\\]$", syn_dil, "[e]"}, // [expr]
|
||||||
{"^(?'expr'.+)[,]{1}[(X|x)]{1}$", syn_absx, "e,x"}, // expr,x
|
{"^(?'expr'.+)[,]{1}[(X|x)]{1}$", syn_absx, "addr,x"}, // expr,x
|
||||||
{"^(?'expr'.+)[,]{1}[(Y|y)]{1}$", syn_absy, "e,y"}, // expr,y
|
{"^(?'expr'.+)[,]{1}[(Y|y)]{1}$", syn_absy, "addr,y"}, // expr,y
|
||||||
{"^(?'expr'.+)[,]{1}(?'expr2'.+)$", syn_bm, "block"}, // block move expr,expr1
|
{"^(?'expr'.+)[,]{1}(?'expr2'.+)$", syn_bm, "block"}, // block move expr,expr1
|
||||||
{"^(?'expr'.+)$", syn_abs, "absolute"}, // expr (MUST BE LAST)
|
{"^(?'expr'.+)$", syn_abs, "absolute"}, // expr (MUST BE LAST)
|
||||||
{"", 0, ""}
|
{"", 0, ""}
|
||||||
};
|
};
|
||||||
|
|
||||||
// one or more of any character except ][,();
|
// one or more of any character except ][,();
|
||||||
const std::string valExpression = "^([^\\]\\[,();]+)$";
|
//const std::string valExpression = "^([^\\]\\[,();]+)$";
|
||||||
|
const std::string valExpression = "^([^\\[,();]+)$";
|
||||||
|
|
||||||
// this one looks for ]variables
|
// this one looks for ]variables
|
||||||
const std::string varExpression = "([]]{1}[:0-9A-Z_a-z]{1}[0-9A-Z_a-z]*)";
|
const std::string varExpression = "([]]{1}[:0-9A-Z_a-z]{1}[0-9A-Z_a-z]*)";
|
||||||
|
const std::string varMACExpression = "([]]{1}[:0-9]{1}[0-9]*)";
|
||||||
|
|
||||||
// opcode check. emitted opcodes are compared against this
|
// opcode check. emitted opcodes are compared against this
|
||||||
// table, and if the XC status doesn't meet the requirements
|
// table, and if the XC status doesn't meet the requirements
|
||||||
|
@ -1646,7 +1731,7 @@ void CLASS::initpass(void)
|
||||||
|
|
||||||
casesen = getBool("asm.casesen", true);
|
casesen = getBool("asm.casesen", true);
|
||||||
listing = getBool("asm.lst", true);
|
listing = getBool("asm.lst", true);
|
||||||
showmx = getBool("asm.showmx", false);
|
showmx = getBool("asm.showmx", true);
|
||||||
merlinerrors = getBool("asm.merlinerrors", true);
|
merlinerrors = getBool("asm.merlinerrors", true);
|
||||||
|
|
||||||
trackrep = getBool("asm.trackrep", false);
|
trackrep = getBool("asm.trackrep", false);
|
||||||
|
@ -1675,15 +1760,16 @@ void CLASS::initpass(void)
|
||||||
PC.totalbytes = 0;
|
PC.totalbytes = 0;
|
||||||
PC.orgsave = PC.origin;
|
PC.orgsave = PC.origin;
|
||||||
|
|
||||||
s = getConfig("asm.cpu", "M65816");
|
s = getConfig("asm.cpu", "M6502");
|
||||||
s = Poco::trim(Poco::toUpper(s));
|
s = Poco::trim(Poco::toUpper(s));
|
||||||
|
|
||||||
cpumode = MODE_65816;
|
cpumode = MODE_65816;
|
||||||
|
mx = 0x03;
|
||||||
|
|
||||||
if (s == "M65816")
|
if (s == "M65816")
|
||||||
{
|
{
|
||||||
cpumode = MODE_65816;
|
cpumode = MODE_65816;
|
||||||
mx = 0x00;
|
mx = 0x03;
|
||||||
}
|
}
|
||||||
else if (s == "M65C02")
|
else if (s == "M65C02")
|
||||||
{
|
{
|
||||||
|
@ -1698,7 +1784,7 @@ void CLASS::initpass(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("Unknown CPU type in .ini\n");
|
printf("Unknown CPU type in .ini\n");
|
||||||
mx = 0x00;
|
mx = 0x03;
|
||||||
}
|
}
|
||||||
mx = getInt("asm.startmx", mx);;
|
mx = getInt("asm.startmx", mx);;
|
||||||
|
|
||||||
|
@ -1893,6 +1979,7 @@ int CLASS::getAddrMode(MerlinLine & line)
|
||||||
x = 0;
|
x = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
//printf("oper: |%s|\n",oper.c_str());
|
||||||
x = regex.split(oper, 0, groups, 0);
|
x = regex.split(oper, 0, groups, 0);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
|
@ -2007,7 +2094,7 @@ int CLASS::parseOperand(MerlinLine & line)
|
||||||
int CLASS::substituteVariables(MerlinLine & line, std::string &outop)
|
int CLASS::substituteVariables(MerlinLine & line, std::string &outop)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int x;
|
int x,x1;
|
||||||
std::string::size_type offset, slen;
|
std::string::size_type offset, slen;
|
||||||
std::string oper = line.operand;
|
std::string oper = line.operand;
|
||||||
std::string s;
|
std::string s;
|
||||||
|
@ -2018,10 +2105,12 @@ int CLASS::substituteVariables(MerlinLine & line, std::string &outop)
|
||||||
bool done = false;
|
bool done = false;
|
||||||
operin = oper;
|
operin = oper;
|
||||||
ct = 0;
|
ct = 0;
|
||||||
|
bool mac_var;
|
||||||
restart:
|
restart:
|
||||||
while (!done)
|
while (!done)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
mac_var=false;
|
||||||
slen = oper.length();
|
slen = oper.length();
|
||||||
if (slen > 0)
|
if (slen > 0)
|
||||||
{
|
{
|
||||||
|
@ -2055,13 +2144,44 @@ restart:
|
||||||
sym = NULL;
|
sym = NULL;
|
||||||
if (expand_macrostack.size() > 0)
|
if (expand_macrostack.size() > 0)
|
||||||
{
|
{
|
||||||
|
mac_var=true;
|
||||||
sym = findVariable(s, expand_macro.variables);
|
sym = findVariable(s, expand_macro.variables);
|
||||||
|
if (sym!=NULL)
|
||||||
|
{
|
||||||
|
RegularExpression varEx1(varMACExpression, 0, true);
|
||||||
|
Poco::RegularExpression::MatchVec mVec1;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
varEx1.match(oper, 0, mVec1, 0);
|
||||||
|
x1 = (int)mVec1.size();
|
||||||
|
if (x1>0)
|
||||||
|
{
|
||||||
|
mac_var=true;
|
||||||
|
//printf("Found MACvar: |%s| |%s|\n",sym->name.c_str(),sym->var_text.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//mac_var=true;
|
||||||
}
|
}
|
||||||
if (sym == NULL)
|
if (sym == NULL)
|
||||||
{
|
{
|
||||||
sym = findVariable(s, variables);
|
sym = findVariable(s, variables);
|
||||||
}
|
}
|
||||||
if (sym != NULL)
|
|
||||||
|
if ((expand_macrostack.size() == 0) && (!mac_var))
|
||||||
|
{
|
||||||
|
//mac_var=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((sym != NULL) && (mac_var))
|
||||||
{
|
{
|
||||||
//printf("match |%s|\n",sym->var_text.c_str());
|
//printf("match |%s|\n",sym->var_text.c_str());
|
||||||
|
|
||||||
|
|
28
asm.h
28
asm.h
|
@ -15,6 +15,8 @@
|
||||||
#define SYNTAX_MPW 0x08
|
#define SYNTAX_MPW 0x08
|
||||||
#define SYNTAX_ORCA 0x10
|
#define SYNTAX_ORCA 0x10
|
||||||
#define SYNTAX_CC65 0x20
|
#define SYNTAX_CC65 0x20
|
||||||
|
#define SYNTAX_LISA 0x40
|
||||||
|
|
||||||
#define SYNTAX_QASM (0x80 | SYNTAX_MERLIN)
|
#define SYNTAX_QASM (0x80 | SYNTAX_MERLIN)
|
||||||
#define OPTION_ALLOW_A_OPERAND 0x0100
|
#define OPTION_ALLOW_A_OPERAND 0x0100
|
||||||
#define OPTION_ALLOW_LOCAL 0x0200
|
#define OPTION_ALLOW_LOCAL 0x0200
|
||||||
|
@ -23,7 +25,7 @@
|
||||||
#define OPTION_NO_REPSEP 0x1000
|
#define OPTION_NO_REPSEP 0x1000
|
||||||
#define OPTION_CFG_REPSEP 0x2000
|
#define OPTION_CFG_REPSEP 0x2000
|
||||||
#define OPTION_M32_VARS 0x4000
|
#define OPTION_M32_VARS 0x4000
|
||||||
|
#define OPTION_M16_PLUS 0x8000
|
||||||
|
|
||||||
#define FLAG_FORCELONG 0x01
|
#define FLAG_FORCELONG 0x01
|
||||||
#define FLAG_FORCEABS 0x02
|
#define FLAG_FORCEABS 0x02
|
||||||
|
@ -201,6 +203,7 @@ public:
|
||||||
std::string printoperand;
|
std::string printoperand;
|
||||||
std::string opcode;
|
std::string opcode;
|
||||||
std::string opcodelower;
|
std::string opcodelower;
|
||||||
|
std::string orig_operand;
|
||||||
std::string operand;
|
std::string operand;
|
||||||
std::string operand_expr;
|
std::string operand_expr;
|
||||||
std::string operand_expr2;
|
std::string operand_expr2;
|
||||||
|
@ -254,6 +257,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
uint32_t errorct;
|
uint32_t errorct;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
|
uint32_t format_flags;
|
||||||
|
|
||||||
TFileProcessor();
|
TFileProcessor();
|
||||||
virtual ~TFileProcessor();
|
virtual ~TFileProcessor();
|
||||||
|
@ -267,18 +271,18 @@ public:
|
||||||
virtual void setSyntax(uint32_t syn);
|
virtual void setSyntax(uint32_t syn);
|
||||||
};
|
};
|
||||||
|
|
||||||
class TImageProcessor : public TFileProcessor
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
std::vector<MerlinLine> lines;
|
|
||||||
|
|
||||||
public:
|
#define CONVERT_NONE 0x00
|
||||||
TImageProcessor();
|
#define CONVERT_LF 0x01
|
||||||
virtual ~TImageProcessor();
|
#define CONVERT_CRLF 0x02
|
||||||
virtual int doline(int lineno, std::string line);
|
#define CONVERT_COMPRESS 0x04
|
||||||
virtual void process(void);
|
#define CONVERT_HIGH 0x08
|
||||||
virtual void complete(void);
|
#define CONVERT_MERLIN (CONVERT_HIGH|CONVERT_COMPRESS)
|
||||||
};
|
#define CONVERT_LINUX (CONVERT_LF)
|
||||||
|
#define CONVERT_WINDOWS (CONVERT_CRLF)
|
||||||
|
#define CONVERT_APW (CONVERT_NONE)
|
||||||
|
#define CONVERT_MPW (CONVERT_NONE)
|
||||||
|
#define CONVERT_TEST (CONVERT_COMPRESS|CONVERT_LF)
|
||||||
|
|
||||||
class TMerlinConverter : public TFileProcessor
|
class TMerlinConverter : public TFileProcessor
|
||||||
{
|
{
|
||||||
|
|
36
cider.cpp
36
cider.cpp
|
@ -1,3 +1,5 @@
|
||||||
|
#ifdef CIDERPRESS
|
||||||
|
|
||||||
#include "asm.h"
|
#include "asm.h"
|
||||||
#include "eval.h"
|
#include "eval.h"
|
||||||
#include "psuedo.h"
|
#include "psuedo.h"
|
||||||
|
@ -7,6 +9,9 @@
|
||||||
|
|
||||||
#include <cider.h>
|
#include <cider.h>
|
||||||
#include <DiskImg.h>
|
#include <DiskImg.h>
|
||||||
|
#include <util.h>
|
||||||
|
|
||||||
|
#undef CLASS
|
||||||
#define CLASS CiderPress
|
#define CLASS CiderPress
|
||||||
|
|
||||||
using namespace DiskImgLib;
|
using namespace DiskImgLib;
|
||||||
|
@ -14,11 +19,13 @@ using DiskImgLib::DiskImg;
|
||||||
|
|
||||||
void dbgMessage(const char *file, int line, const char *msg)
|
void dbgMessage(const char *file, int line, const char *msg)
|
||||||
{
|
{
|
||||||
|
if (isDebug()>0)
|
||||||
|
{
|
||||||
printf("DEBUG: %s\n",msg);
|
printf("DEBUG: %s\n",msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CLASS::CLASS()
|
CLASS::CLASS() : TFileProcessor()
|
||||||
{
|
{
|
||||||
if (!Global::GetAppInitCalled())
|
if (!Global::GetAppInitCalled())
|
||||||
{
|
{
|
||||||
|
@ -27,6 +34,11 @@ CLASS::CLASS()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CLASS::~CLASS()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int CLASS::RunScript(string path)
|
int CLASS::RunScript(string path)
|
||||||
{
|
{
|
||||||
int res=-1;
|
int res=-1;
|
||||||
|
@ -56,7 +68,27 @@ int CLASS::CreateVolume(string OSName, string VolName, uint64_t size, CIDER_VOLF
|
||||||
);
|
);
|
||||||
printf("create error: %d\n",err);
|
printf("create error: %d\n",err);
|
||||||
if (err== kDIErrNone )
|
if (err== kDIErrNone )
|
||||||
|
{
|
||||||
interr=0;
|
interr=0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return (interr);
|
return (interr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CLASS::doline(int lineno, std::string line)
|
||||||
|
{
|
||||||
|
printf("%05d: %s\n",lineno,line.c_str());
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
void CLASS::process(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void CLASS::complete(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CLASS
|
||||||
|
|
||||||
|
#endif
|
12
cider.h
12
cider.h
|
@ -1,3 +1,4 @@
|
||||||
|
#ifdef CIDERPRESS
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "asm.h"
|
#include "asm.h"
|
||||||
|
@ -11,12 +12,19 @@
|
||||||
#define CLASS CiderPress
|
#define CLASS CiderPress
|
||||||
|
|
||||||
enum CIDER_VOLFORMAT {CP_PRODOS,CP_HFS};
|
enum CIDER_VOLFORMAT {CP_PRODOS,CP_HFS};
|
||||||
class CLASS
|
class CLASS : public TFileProcessor
|
||||||
{
|
{
|
||||||
public:
|
protected:
|
||||||
|
std::vector<MerlinLine> lines;
|
||||||
|
public:
|
||||||
CLASS();
|
CLASS();
|
||||||
|
virtual ~CLASS();
|
||||||
int CreateVolume(string OSName, string VolName, uint64_t size, CIDER_VOLFORMAT format);
|
int CreateVolume(string OSName, string VolName, uint64_t size, CIDER_VOLFORMAT format);
|
||||||
int RunScript(string path);
|
int RunScript(string path);
|
||||||
|
virtual int doline(int lineno, std::string line);
|
||||||
|
virtual void process(void);
|
||||||
|
virtual void complete(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef CLASS
|
#undef CLASS
|
||||||
|
#endif
|
2
eval.cpp
2
eval.cpp
|
@ -607,7 +607,7 @@ int CLASS::evaluate(std::string & e, int64_t &res, uint8_t &_shiftmode)
|
||||||
std::string expr = Poco::trim(e);
|
std::string expr = Poco::trim(e);
|
||||||
expr += " "; // add a space at end to make parsing easier
|
expr += " "; // add a space at end to make parsing easier
|
||||||
|
|
||||||
if (isDebug() >= 4)
|
if (isDebug() >= 1)
|
||||||
{
|
{
|
||||||
printf("eval: expression: |%s|\n", expr.c_str());
|
printf("eval: expression: |%s|\n", expr.c_str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,9 @@ for S in $SRC ; do
|
||||||
S1=${S1/.s/}
|
S1=${S1/.s/}
|
||||||
|
|
||||||
cd ./testdata
|
cd ./testdata
|
||||||
merlin32$X . $S 2>/dev/null >/dev/null
|
#merlin32$X . $S 2>/dev/null >/dev/null
|
||||||
|
merlin32$X -V . $S
|
||||||
|
|
||||||
#merlin32 . $S 2>/dev/null
|
#merlin32 . $S 2>/dev/null
|
||||||
|
|
||||||
R=?$
|
R=?$
|
||||||
|
|
|
@ -12,6 +12,7 @@ void CLASS::setOpcode(MerlinLine &line, uint8_t op)
|
||||||
uint8_t m = opCodeCompatibility[op];
|
uint8_t m = opCodeCompatibility[op];
|
||||||
if ((m > 0) && (cpumode < MODE_65C02)) // if the instruction is non-zero, and we are in 6502 base mode, error
|
if ((m > 0) && (cpumode < MODE_65C02)) // if the instruction is non-zero, and we are in 6502 base mode, error
|
||||||
{
|
{
|
||||||
|
//printf("incompatable: %02X %02X\n",op,m);
|
||||||
if (line.errorcode == 0) // don't replace other errors
|
if (line.errorcode == 0) // don't replace other errors
|
||||||
{
|
{
|
||||||
line.setError(errIncompatibleOpcode);
|
line.setError(errIncompatibleOpcode);
|
||||||
|
@ -706,7 +707,8 @@ int CLASS::doBase6502(MerlinLine & line, TSymbol & sym)
|
||||||
|
|
||||||
if (err) // not a 6502 address mode
|
if (err) // not a 6502 address mode
|
||||||
{
|
{
|
||||||
if (cpumode >= MODE_65816)
|
//if (cpumode >= MODE_65816)
|
||||||
|
if (cpumode >= MODE_65C02)
|
||||||
{
|
{
|
||||||
cc = 0x03;
|
cc = 0x03;
|
||||||
err = false;
|
err = false;
|
||||||
|
@ -950,6 +952,7 @@ void CLASS::insertOpcodes(void)
|
||||||
pushopcode("MVP", 0x01, 0, OPHANDLER(&CLASS::doMVN));
|
pushopcode("MVP", 0x01, 0, OPHANDLER(&CLASS::doMVN));
|
||||||
pushopcode("NOP", 0xEA, 0, OPHANDLER(&CLASS::doBYTE));
|
pushopcode("NOP", 0xEA, 0, OPHANDLER(&CLASS::doBYTE));
|
||||||
pushopcode("ORA", 0x00, OP_STD | OP_A, OPHANDLER(&CLASS::doBase6502));
|
pushopcode("ORA", 0x00, OP_STD | OP_A, OPHANDLER(&CLASS::doBase6502));
|
||||||
|
|
||||||
pushopcode("PEA", 0xF4, 2, OPHANDLER(&CLASS::doAddress));
|
pushopcode("PEA", 0xF4, 2, OPHANDLER(&CLASS::doAddress));
|
||||||
pushopcode("PEI", 0xD4, 1, OPHANDLER(&CLASS::doAddress));
|
pushopcode("PEI", 0xD4, 1, OPHANDLER(&CLASS::doAddress));
|
||||||
pushopcode("PER", 0x62, 2, OPHANDLER(&CLASS::doPER));
|
pushopcode("PER", 0x62, 2, OPHANDLER(&CLASS::doPER));
|
||||||
|
|
28
parms.json
28
parms.json
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"version": "1.1",
|
"version": "1.1",
|
||||||
"general": {
|
"general": {
|
||||||
|
"color_output": true,
|
||||||
"prefix": [
|
"prefix": [
|
||||||
{
|
{
|
||||||
"0": "${PWD}"
|
"0": "${PWD}"
|
||||||
|
@ -16,16 +17,27 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"assembler": {
|
"asm": {
|
||||||
"cpu_default": "6502",
|
"syntax": "merlin16plus", //merlin8, merlin16, merlin16plus,merlin32
|
||||||
"syntax": "merlin",
|
"cpu": "M6502",
|
||||||
"listmode": "on"
|
"startmx": 3,
|
||||||
|
"listmode": "on",
|
||||||
|
"casesend": true,
|
||||||
|
"lst": false,
|
||||||
|
"showmx": true,
|
||||||
|
"allowduplicate": true,
|
||||||
|
"trackrep": false,
|
||||||
|
"merlinerrors": true,
|
||||||
|
"m32vars": false,
|
||||||
|
"allowA": true,
|
||||||
|
"allowLocal": true,
|
||||||
|
"allowColon": true,
|
||||||
|
"repsep": "force", //force,no,cfg
|
||||||
|
"linebytes": 4,
|
||||||
|
"line2bytes": 8
|
||||||
},
|
},
|
||||||
"linker": {},
|
"linker": {},
|
||||||
"format": {
|
"format": {
|
||||||
"tabs": "12,18,30"
|
"tabs": "12,18,30,48"
|
||||||
},
|
|
||||||
"diskimg": {
|
|
||||||
"script": "./disk_commands.txt"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -944,6 +944,10 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
||||||
|
|
||||||
if (dci && (i == lastdelimidx))
|
if (dci && (i == lastdelimidx))
|
||||||
{
|
{
|
||||||
|
// SGQ BUG - Merlin16+ does it like Merlin32 and now does the last
|
||||||
|
// byte not the way merlin816 and earlier do it documented below.
|
||||||
|
// use OPTION_M16_PLUS when implemented.
|
||||||
|
|
||||||
//lr - Merlin only toggles the high bit of string chars, not hex values
|
//lr - Merlin only toggles the high bit of string chars, not hex values
|
||||||
// 8D,'Hello',8D,'there',8D becomes 8D 48 65 6C 6C 6F 8D 74 68 65 72 E5
|
// 8D,'Hello',8D,'there',8D becomes 8D 48 65 6C 6C 6F 8D 74 68 65 72 E5
|
||||||
//
|
//
|
||||||
|
|
54
qasm.cpp
54
qasm.cpp
|
@ -20,7 +20,7 @@ programOption PAL::appOptions[] =
|
||||||
{ "debug", "d", "enable debug info (repeat for more verbosity)", "", false, true},
|
{ "debug", "d", "enable debug info (repeat for more verbosity)", "", false, true},
|
||||||
#endif
|
#endif
|
||||||
//{ "config", "f", "load configuration data from a <file>", "<file>", false, false},
|
//{ "config", "f", "load configuration data from a <file>", "<file>", false, false},
|
||||||
{ "exec", "x", "execute a command [asm, link, reformat, script] default=asm", "<command>", false, false},
|
{ "exec", "x", "execute a command [asm, link, format, script] default=asm", "<command>", false, false},
|
||||||
{ "objfile", "o", "write output to file", "<file>", false, false},
|
{ "objfile", "o", "write output to file", "<file>", false, false},
|
||||||
{ "syntax", "s", "enforce syntax of other assembler [qasm, merlin, merlin32, ORCA, APW, MPW, CC65]", "<syntax>", false, false},
|
{ "syntax", "s", "enforce syntax of other assembler [qasm, merlin, merlin32, ORCA, APW, MPW, CC65]", "<syntax>", false, false},
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ int CLASS::runCommandLineApp(void)
|
||||||
syn=Poco::toUpper(syn);
|
syn=Poco::toUpper(syn);
|
||||||
syn=Poco::trim(syn);
|
syn=Poco::trim(syn);
|
||||||
syntax=SYNTAX_QASM;
|
syntax=SYNTAX_QASM;
|
||||||
if ((syn=="MERLIN") || (syn=="MERLIN16") || (syn=="MERLIN8") || (syn=="MERLIN16+"))
|
if ((syn=="MERLIN") || (syn=="MERLIN16") || (syn=="MERLIN8") || (syn=="MERLIN16PLUS"))
|
||||||
{
|
{
|
||||||
syntax=SYNTAX_MERLIN;
|
syntax=SYNTAX_MERLIN;
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ int CLASS::runCommandLineApp(void)
|
||||||
syntax=SYNTAX_CC65;
|
syntax=SYNTAX_CC65;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("SYNTAX: |%s|\n",syn.c_str());
|
//printf("SYNTAX: |%s|\n",syn.c_str());
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -148,6 +148,7 @@ int CLASS::runCommandLineApp(void)
|
||||||
|
|
||||||
for (ArgVec::const_iterator it = commandargs.begin(); it != commandargs.end(); ++it)
|
for (ArgVec::const_iterator it = commandargs.begin(); it != commandargs.end(); ++it)
|
||||||
{
|
{
|
||||||
|
int32_t format_flags=CONVERT_LINUX;
|
||||||
Poco::File fn(*it);
|
Poco::File fn(*it);
|
||||||
int x;
|
int x;
|
||||||
std::string p = fn.path();
|
std::string p = fn.path();
|
||||||
|
@ -158,10 +159,50 @@ int CLASS::runCommandLineApp(void)
|
||||||
|
|
||||||
std::string cmd = Poco::toUpper(getConfig("option.exec", "asm"));
|
std::string cmd = Poco::toUpper(getConfig("option.exec", "asm"));
|
||||||
|
|
||||||
//printf("DEBUG=%d\n",isDebug());
|
Poco::StringTokenizer toks(cmd,"-");
|
||||||
|
if (toks.count()>1)
|
||||||
|
{
|
||||||
|
if (toks[0]=="FORMAT")
|
||||||
|
{
|
||||||
|
if (toks[1]=="LINUX")
|
||||||
|
{
|
||||||
|
format_flags=CONVERT_LINUX;
|
||||||
|
}
|
||||||
|
else if (toks[1]=="WINDOWS")
|
||||||
|
{
|
||||||
|
format_flags=CONVERT_WINDOWS;
|
||||||
|
}
|
||||||
|
else if (toks[1]=="MERLIN")
|
||||||
|
{
|
||||||
|
format_flags=CONVERT_MERLIN;
|
||||||
|
}
|
||||||
|
else if (toks[1]=="APW")
|
||||||
|
{
|
||||||
|
format_flags=CONVERT_APW;
|
||||||
|
}
|
||||||
|
else if (toks[1]=="MPW")
|
||||||
|
{
|
||||||
|
format_flags=CONVERT_MPW;
|
||||||
|
}
|
||||||
|
else if (toks[1]=="MAC")
|
||||||
|
{
|
||||||
|
format_flags=CONVERT_LINUX;
|
||||||
|
}
|
||||||
|
else if (toks[1]=="CC65")
|
||||||
|
{
|
||||||
|
format_flags=CONVERT_LINUX;
|
||||||
|
}
|
||||||
|
else if (toks[1]=="COMPRESS")
|
||||||
|
{
|
||||||
|
format_flags=CONVERT_TEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd=toks[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
if (cmd.length() > 0)
|
if (cmd.length() > 0)
|
||||||
{
|
{
|
||||||
if (cmd == "REFORMAT")
|
if (cmd == "FORMAT")
|
||||||
{
|
{
|
||||||
res = 0;
|
res = 0;
|
||||||
t = new TMerlinConverter();
|
t = new TMerlinConverter();
|
||||||
|
@ -171,6 +212,7 @@ int CLASS::runCommandLineApp(void)
|
||||||
{
|
{
|
||||||
t->init();
|
t->init();
|
||||||
t->setSyntax(syntax);
|
t->setSyntax(syntax);
|
||||||
|
t->format_flags=format_flags;
|
||||||
|
|
||||||
std::string f = path.toString();
|
std::string f = path.toString();
|
||||||
t->filename = f;
|
t->filename = f;
|
||||||
|
@ -233,7 +275,7 @@ int CLASS::runCommandLineApp(void)
|
||||||
else if (cmd == "SCRIPT")
|
else if (cmd == "SCRIPT")
|
||||||
{
|
{
|
||||||
res = 0;
|
res = 0;
|
||||||
t = new TImageProcessor();
|
t = new CiderPress();
|
||||||
if (t!=NULL)
|
if (t!=NULL)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
4
testdata/1000-allops-value-65816.S
vendored
4
testdata/1000-allops-value-65816.S
vendored
|
@ -2,6 +2,10 @@
|
||||||
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||||
;
|
;
|
||||||
; Assembler: Merlin 32
|
; Assembler: Merlin 32
|
||||||
|
xc off
|
||||||
|
xc
|
||||||
|
xc
|
||||||
|
mx %00
|
||||||
ZP EQU $FF
|
ZP EQU $FF
|
||||||
ABS EQU $FEFF
|
ABS EQU $FEFF
|
||||||
LONG EQU $FDFEFF
|
LONG EQU $FDFEFF
|
||||||
|
|
4
testdata/1001-allops-zero-65816.S
vendored
4
testdata/1001-allops-zero-65816.S
vendored
|
@ -3,6 +3,10 @@
|
||||||
;
|
;
|
||||||
; Assembler: Merlin 32
|
; Assembler: Merlin 32
|
||||||
|
|
||||||
|
xc off
|
||||||
|
xc
|
||||||
|
xc
|
||||||
|
mx %00
|
||||||
ZP EQU $00
|
ZP EQU $00
|
||||||
ABS EQU $0000
|
ABS EQU $0000
|
||||||
LONG EQU $000000
|
LONG EQU $000000
|
||||||
|
|
80
testdata/1002-embedded-instructions.S
vendored
80
testdata/1002-embedded-instructions.S
vendored
|
@ -1,11 +1,15 @@
|
||||||
; Copyright 2018 faddenSoft. All Rights Reserved.
|
; Copyright 2018 faddenSoft. All Rights Reserved.
|
||||||
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||||
;
|
;
|
||||||
; Assembler: Merlin 32
|
; Assembler: Merlin 32
|
||||||
|
|
||||||
|
xc off
|
||||||
|
xc
|
||||||
|
xc
|
||||||
|
mx %11
|
||||||
org $1000
|
org $1000
|
||||||
|
|
||||||
; 65816 mode with short regs
|
; 65816 mode with short regs
|
||||||
clc
|
clc
|
||||||
xce
|
xce
|
||||||
sep #$30
|
sep #$30
|
||||||
|
@ -18,28 +22,28 @@
|
||||||
jsr test5
|
jsr test5
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; TEST #1: simple example
|
; TEST #1: simple example
|
||||||
test1 lda #$00
|
test1 lda #$00
|
||||||
dfb $2c ;BIT abs
|
dfb $2c ;BIT abs
|
||||||
:inner lda #$01
|
:inner lda #$01
|
||||||
beq :inner
|
beq :inner
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; TEST #2: embedded with break path
|
; TEST #2: embedded with break path
|
||||||
;
|
;
|
||||||
; Example inspired by incorrect analysis...
|
; Example inspired by incorrect analysis...
|
||||||
;
|
;
|
||||||
; The code analyzer sees:
|
; The code analyzer sees:
|
||||||
; beq {+03} ;jumps to the $8f
|
; beq {+03} ;jumps to the $8f
|
||||||
; lda #$00
|
; lda #$00
|
||||||
; brk $8f
|
; brk $8f
|
||||||
; and stops, then pursues the branch. If we try to walk from top
|
; and stops, then pursues the branch. If we try to walk from top
|
||||||
; to bottom, skipping forward by the full length of an instruction,
|
; to bottom, skipping forward by the full length of an instruction,
|
||||||
; we'll appear to find ourselves in the middle of an embedded
|
; we'll appear to find ourselves in the middle of an embedded
|
||||||
; instruction.
|
; instruction.
|
||||||
;
|
;
|
||||||
; This is different from the typical embedded instruction,
|
; This is different from the typical embedded instruction,
|
||||||
; where the inner is contained entirely within the outer.
|
; where the inner is contained entirely within the outer.
|
||||||
test2 sep #$30 ;short regs
|
test2 sep #$30 ;short regs
|
||||||
mx %00 ;pretend they're long
|
mx %00 ;pretend they're long
|
||||||
|
|
||||||
|
@ -49,15 +53,15 @@ test2 sep #$30 ;short regs
|
||||||
:store stal $012345
|
:store stal $012345
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; TEST #3: embedded with non-instruction byte
|
; TEST #3: embedded with non-instruction byte
|
||||||
;
|
;
|
||||||
; The code analyzer sees two paths, involving the three bytes.
|
; The code analyzer sees two paths, involving the three bytes.
|
||||||
; The first is the three-byte JSR, the second is the one-byte
|
; The first is the three-byte JSR, the second is the one-byte
|
||||||
; RTS. The third NOP byte is never "executed" by the analyzer,
|
; RTS. The third NOP byte is never "executed" by the analyzer,
|
||||||
; but because of the way we display embedded instructions it
|
; but because of the way we display embedded instructions it
|
||||||
; gets put on its own line. Since it's not an instruction start
|
; gets put on its own line. Since it's not an instruction start
|
||||||
; or a data item, things get confused. (This is referred to as
|
; or a data item, things get confused. (This is referred to as
|
||||||
; an "embedded orphan" in the code.)
|
; an "embedded orphan" in the code.)
|
||||||
|
|
||||||
test3 dfb $20 ;JSR
|
test3 dfb $20 ;JSR
|
||||||
:mid dfb $60 ;RTS
|
:mid dfb $60 ;RTS
|
||||||
|
@ -65,10 +69,10 @@ test3 dfb $20 ;JSR
|
||||||
bra :mid
|
bra :mid
|
||||||
|
|
||||||
|
|
||||||
; TEST #4: overlapping chain
|
; TEST #4: overlapping chain
|
||||||
;
|
;
|
||||||
; Each BIT instruction is three bytes, and each byte is a branch target,
|
; Each BIT instruction is three bytes, and each byte is a branch target,
|
||||||
; so we get a string of embedded instructions.
|
; so we get a string of embedded instructions.
|
||||||
test4
|
test4
|
||||||
:bits hex 2c2c2c2c2c2c2c2c2ceaea
|
:bits hex 2c2c2c2c2c2c2c2c2ceaea
|
||||||
asl
|
asl
|
||||||
|
@ -93,9 +97,9 @@ test4
|
||||||
bcc :bits+9
|
bcc :bits+9
|
||||||
rts
|
rts
|
||||||
|
|
||||||
; TEST #5: another overlap
|
; TEST #5: another overlap
|
||||||
;
|
;
|
||||||
; Trying to be a little different.
|
; Trying to be a little different.
|
||||||
test5 dfb $2c
|
test5 dfb $2c
|
||||||
:mid1 nop
|
:mid1 nop
|
||||||
hex ad
|
hex ad
|
||||||
|
@ -105,6 +109,6 @@ test5 dfb $2c
|
||||||
asl
|
asl
|
||||||
bcc :mid2
|
bcc :mid2
|
||||||
|
|
||||||
; TEST #6: "embedded" off the end of the file
|
; TEST #6: "embedded" off the end of the file
|
||||||
dfb $af ;ldal
|
dfb $af ;ldal
|
||||||
|
|
||||||
|
|
4
testdata/1003-flags-and-branches.S
vendored
4
testdata/1003-flags-and-branches.S
vendored
|
@ -2,7 +2,9 @@
|
||||||
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||||
;
|
;
|
||||||
; Assembler: Merlin 32
|
; Assembler: Merlin 32
|
||||||
|
xc off
|
||||||
|
xc
|
||||||
|
xc
|
||||||
org $1000
|
org $1000
|
||||||
clc
|
clc
|
||||||
xce
|
xce
|
||||||
|
|
10
testdata/2000-allops-value-6502.S
vendored
10
testdata/2000-allops-value-6502.S
vendored
|
@ -1,8 +1,8 @@
|
||||||
; Copyright 2018 faddenSoft. All Rights Reserved.
|
; Copyright 2018 faddenSoft. All Rights Reserved.
|
||||||
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||||
;
|
;
|
||||||
; Assembler: Merlin 32
|
; Assembler: Merlin 32
|
||||||
|
xc off
|
||||||
ZP EQU $FF
|
ZP EQU $FF
|
||||||
ABS EQU $FEFF
|
ABS EQU $FEFF
|
||||||
|
|
||||||
|
|
4
testdata/2002-allops-value-65C02.S
vendored
4
testdata/2002-allops-value-65C02.S
vendored
|
@ -2,7 +2,9 @@
|
||||||
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||||
;
|
;
|
||||||
; Assembler: Merlin 32
|
; Assembler: Merlin 32
|
||||||
|
xc off
|
||||||
|
xc
|
||||||
|
;xc
|
||||||
ZP EQU $FF
|
ZP EQU $FF
|
||||||
ABS EQU $FEFF
|
ABS EQU $FEFF
|
||||||
|
|
||||||
|
|
2
testdata/2003-allops-zero-65C02.S
vendored
2
testdata/2003-allops-zero-65C02.S
vendored
|
@ -2,6 +2,8 @@
|
||||||
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||||
;
|
;
|
||||||
; Assembler: Merlin 32
|
; Assembler: Merlin 32
|
||||||
|
xc off
|
||||||
|
xc
|
||||||
|
|
||||||
ZP EQU $00
|
ZP EQU $00
|
||||||
ABS EQU $0000
|
ABS EQU $0000
|
||||||
|
|
1
testdata/3008-macro-strings.S
vendored
1
testdata/3008-macro-strings.S
vendored
|
@ -12,3 +12,4 @@ xx mac
|
||||||
xx "hello"
|
xx "hello"
|
||||||
xx 'abc',00
|
xx 'abc',00
|
||||||
xx ff
|
xx ff
|
||||||
|
|
||||||
|
|
10
testdata/allops-common-6502.S
vendored
10
testdata/allops-common-6502.S
vendored
|
@ -1,7 +1,7 @@
|
||||||
; Copyright 2018 faddenSoft. All Rights Reserved.
|
; Copyright 2018 faddenSoft. All Rights Reserved.
|
||||||
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||||
;
|
;
|
||||||
; Assembler: Merlin 32
|
; Assembler: Merlin 32
|
||||||
|
|
||||||
ORG $1000
|
ORG $1000
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ PostH32 DFB $33,ZP
|
||||||
AND: ABS,Y
|
AND: ABS,Y
|
||||||
DFB $3A
|
DFB $3A
|
||||||
DFB $3B,#<ABS,#>ABS
|
DFB $3B,#<ABS,#>ABS
|
||||||
BIT: ABS,X
|
;BIT: ABS,X // not available on standard 6502 (but is on 65C02)
|
||||||
AND: ABS,X
|
AND: ABS,X
|
||||||
ROL: ABS,X
|
ROL: ABS,X
|
||||||
DFB $3F,#<ABS,#>ABS
|
DFB $3F,#<ABS,#>ABS
|
||||||
|
|
1
testdata/allops-common-65816.S
vendored
1
testdata/allops-common-65816.S
vendored
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
ORG $1000
|
ORG $1000
|
||||||
|
|
||||||
|
mx %00
|
||||||
SEC
|
SEC
|
||||||
XCE
|
XCE
|
||||||
JSR L101F
|
JSR L101F
|
||||||
|
|
1
testdata/allops-common-65C02.S
vendored
1
testdata/allops-common-65C02.S
vendored
|
@ -1,6 +1,5 @@
|
||||||
; Copyright 2018 faddenSoft. All Rights Reserved.
|
; Copyright 2018 faddenSoft. All Rights Reserved.
|
||||||
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||||
;
|
|
||||||
; Assembler: Merlin 32
|
; Assembler: Merlin 32
|
||||||
|
|
||||||
ORG $1000
|
ORG $1000
|
||||||
|
|
Loading…
Reference in New Issue
Block a user