Merge pull request #26 from marketideas/lane_qasm_main

Lane qasm main
This commit is contained in:
Lane Roathe 2019-12-11 10:38:38 -08:00 committed by GitHub
commit 3e568ad47a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 103 additions and 61 deletions

6
README
View File

@ -46,3 +46,9 @@ make
To test:
./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
View File

@ -343,7 +343,7 @@ std::string commentEx = "^(\\s*)((;|\\/{2}))+(.*)";
void CLASS::set(std::string line)
{
int state = 0;
int l = line.length();
int l = (int)line.length();
int i = 0;
int x;
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());
operand = strs[0];
//printf("which=%d operand=|%s|\n",ct,operand.c_str());
i = operand.length();
i = (int)operand.length();
restofline = restofline.substr(i, restofline.length());
comment = Poco::trim(restofline);
match = true;
@ -510,7 +510,7 @@ void CLASS::set(std::string line)
}
}
printlable = lable;
x = lable.length();
x = (int)lable.length();
if (x > 1)
{
// 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)
{
uint32_t ct = lines.size();
uint32_t ct = (uint32_t)lines.size();
uint32_t len, t, pos;
@ -1239,6 +1239,11 @@ TSymbol * CLASS::findVariable(std::string symname, TVariable &vars)
{
TSymbol *res = NULL;
if (!casesen)
{
symname = Poco::toUpper(symname);
}
if ((expand_macrostack.size() > 0) && (vars.id != expand_macro.variables.id))
{
res = findVariable(symname, expand_macro.variables);
@ -1693,7 +1698,7 @@ void CLASS::complete(void)
std::ofstream f(savepath);
uint32_t lineno = 0;
uint32_t l = lines.size();
uint32_t l = (uint32_t)lines.size();
while (lineno < l)
{
MerlinLine &line = lines.at(lineno++);
@ -1971,14 +1976,14 @@ restart:
offset = slen;
}
x = mVec.size();
x = (int)mVec.size();
if (x > 0)
{
res = 0;
off = mVec[0].offset;
len = mVec[0].length;
off = (uint32_t)mVec[0].offset;
len = (uint32_t)mVec[0].length;
s = oper.substr(off, len);
slen = s.length();
sym = NULL;
if (expand_macrostack.size() > 0)
{
@ -1995,6 +2000,7 @@ restart:
if (sym->var_text != "")
{
oper = oper.replace(off, len, sym->var_text);
slen = oper.length();
ct++;
if (pass > 0)
{
@ -2037,7 +2043,7 @@ bool CLASS::doOFF(void)
std::stack<TDOstruct> tmpstack;
TDOstruct doitem;
uint32_t ct = DOstack.size();
uint32_t ct = (uint32_t)DOstack.size();
if (ct > 0)
{
tmpstack = DOstack;
@ -2095,7 +2101,7 @@ void CLASS::process(void)
{
initpass();
l = lines.size();
l = (uint32_t)lines.size();
bool passdone = false;
while ((!passdone) && (!passcomplete))
{
@ -2201,7 +2207,11 @@ void CLASS::process(void)
std::string outop;
line.printoperand = line.operand;
x = substituteVariables(line, outop);
x = 0;
if (macrostack.size() == 0)
{
x = substituteVariables(line, outop);
}
if (x > 0)
{
line.printoperand = outop;
@ -2243,20 +2253,23 @@ void CLASS::process(void)
{
TMacro *mac = NULL;
bool inoperand = false;
mac = findMacro(realop);
if (mac == NULL)
if (macrostack.size() == 0)
{
if (op == ">>>") // specal merlin way of calling a macro
mac = findMacro(realop);
if (mac == NULL)
{
Poco::StringTokenizer tok(operand, ", ", Poco::StringTokenizer::TOK_TRIM |
Poco::StringTokenizer::TOK_IGNORE_EMPTY);
std::string s = "";
if (tok.count() > 0)
if (op == ">>>") // specal merlin way of calling a macro
{
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)

View File

@ -391,7 +391,7 @@ int CLASS::parseAscii(std::string n, int64_t &val)
bool high = false;
uint8_t c;
uint32_t l = n.length();
uint32_t l = (uint32_t)n.length();
for (uint32_t i = 0; i < l - 1; i++)
{
c = n[i];
@ -442,7 +442,7 @@ int CLASS::parseNumber(std::string n, int64_t &val)
//printf("parseNumber |%s|\n",n.c_str());
i = 0;
l = n.length();
l = (uint32_t)n.length();
s = "";
for (i = 0; i < l; i++)
{

View File

@ -20,17 +20,14 @@ for S in $SRC ; do
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
cd .. >/dev/null
mv ./testdata/$S1 $OUTDIR/$S1.bin 2>/dev/null
rm -f ./testdata/*.txt 2>/dev/null
rm -f ./testdata/$S1 2>/dev/null
R=?$
done

View File

@ -829,7 +829,11 @@ void CLASS::insertOpcodes(void)
{
pushopcode("=", 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("ORG", P_ORG, 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("USE", P_USE, 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("END", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doEND));
pushopcode("DUM", P_DUM, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DEND", P_DEND, 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("DAT", 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("ADRL", P_DATA, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("HEX", P_HEX, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DS", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("DO", 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));
@ -880,11 +882,9 @@ void CLASS::insertOpcodes(void)
pushopcode("KBD", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("LUP", 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("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", P_MAC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("EOM", 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("BCS", 0x82, 0, OPHANDLER(&CLASS::doBRANCH));
pushopcode("BGE", 0x82, 0, OPHANDLER(&CLASS::doBRANCH));
pushopcode("BEQ", 0x83, 0, OPHANDLER(&CLASS::doBRANCH));
pushopcode("BIT", 0x01, OP_C0, OPHANDLER(&CLASS::doBase6502));
pushopcode("BMI", 0x80, 0, OPHANDLER(&CLASS::doBRANCH));

View File

@ -36,7 +36,7 @@ int CLASS::doDO(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
UNUSED(opinfo);
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;
uint8_t shift;
@ -141,8 +141,9 @@ int CLASS::doMAC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
std::string op = Poco::toUpper(line.opcode);
if (op == "MAC")
{
if (a.expand_macrostack.size()>0)
if (a.expand_macrostack.size() > 0)
{
line.flags |= FLAG_NOLINEPRINT;
goto out;
}
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.start = line.lineno;
a.currentmacro.running = true;
if (!a.casesen)
{
a.currentmacro.name = Poco::toUpper(a.currentmacro.name);
}
if (a.pass == 0)
{
}
@ -399,7 +406,7 @@ int CLASS::doDATA(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
line.setError(errBadEvaluation);
}
}
eval_value = doShift(eval_value, shift);
eval_value = (uint64_t)doShift((uint32_t)eval_value, shift);
}
outct += wordsize;
@ -477,7 +484,7 @@ int CLASS::doDS(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
line.setError(errBadOperand);
goto out;
}
eval_value = doShift(eval_value, shift);
eval_value = (uint64_t)doShift((uint32_t)eval_value, shift);
datact = eval_value & 0xFFFF;
if (datact < 0)
{
@ -497,7 +504,7 @@ int CLASS::doDS(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
line.setError(errBadOperand);
goto out;
}
eval_value = doShift(eval_value, shift);
eval_value = (uint64_t)doShift((uint32_t)eval_value, shift);
fill = eval_value & 0xFF;
}
else if (ct > 1)
@ -696,20 +703,21 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
std::string os = line.operand;
std::string op = Poco::toUpper(line.opcode);
uint8_t lastdelimbyte = 0x00;
uint8_t firstdelim = 0xFF;
uint8_t firstdelim = 0;
uint32_t bytect = 0;
uint8_t b = 0;
uint8_t b1;
uint8_t ct = 0;
char delimiter = 0;
uint8_t delimiter = 0;
uint32_t ss = 0;
uint32_t lastdelimidx = 0;
std::vector<uint8_t> bytes;
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 )
{
char c = os[i];
uint8_t c = os[i];
// are we inside a delimited string?
if ( delimiter )
@ -731,9 +739,9 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
{
c |= 0x80;
}
lastdelimbyte = 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
delimiter = c;
if (firstdelim == 0xFF)
if( ! firstdelim )
{
firstdelim = c;
}
@ -784,7 +792,6 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
if (a.pass > 0)
{
bytes.push_back(b);
//line.outbytes.push_back(b);
}
b = 0;
bytect++;
@ -805,8 +812,7 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
uint8_t andval = 0xFF;
uint8_t orval = 0x00;
uint8_t addlen = 0;
uint8_t firstbyte = 0x00;
uint32_t truebytect = bytes.size();
uint32_t truebytect = (uint32_t)bytes.size();
const char *ptr = (const char *)op.c_str();
//printf("bytect=%d bytes.size()=%zu\n",bytect,bytes.size());
switch (strhash(ptr) )
@ -855,26 +861,31 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
{
b = bytes[i];
}
if (!i)
{
firstbyte = b;
}
b1 = b & 0x7F;
b1 = b & 0x7F;
if ((andval != 0xFF) || (orval != 0x00))
{
b = b1;
}
if ((b1 < 0x60))
{
b &= andval; // strip whatever bits needed to flash or invert
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
// bit seven, and invert it on this byte. The confusion arises because this text string
// could have high ASCII, but low HEX values.
if (firstbyte < 0x80)
//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
//
// 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;
}
@ -899,6 +910,7 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
{
int res = 0;
std::string s;
switch (opinfo.opcode)
{
@ -949,6 +961,18 @@ 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_CAS:
s = Poco::toUpper(line.operand);
if (s == "SE")
{
a.casesen = true;
}
if (s=="IN")
{
a.casesen=false;
}
res = 0;
break;
case P_MAC:
res = doMAC(a, line, opinfo);
break;

View File

@ -21,6 +21,7 @@ enum
P_ASC,
P_ERR,
P_MAC,
P_CAS,
P_MAX
};

View File

@ -413,6 +413,8 @@ L00BC bit L00BC
asc 02,15,"123456"
asc 0215"1234"1502
dci 8D,'Hello',8D,'there',8D
dci 8D,"Hello",8D,"there",8D
lst
lup_start: