mirror of
https://github.com/marketideas/qasm.git
synced 2024-12-27 15:29:30 +00:00
commit
3e568ad47a
6
README
6
README
@ -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
57
asm.cpp
@ -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)
|
||||
|
4
eval.cpp
4
eval.cpp
@ -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++)
|
||||
{
|
||||
|
@ -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
|
||||
|
13
opcodes.cpp
13
opcodes.cpp
@ -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));
|
||||
|
74
psuedo.cpp
74
psuedo.cpp
@ -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;
|
||||
|
2
testdata/3001-lroathe.S
vendored
2
testdata/3001-lroathe.S
vendored
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user