mirror of
https://github.com/marketideas/qasm.git
synced 2024-12-27 15:29:30 +00:00
making tests pass
This commit is contained in:
parent
1c7a91e5eb
commit
a80ff4a35c
42
asm.cpp
42
asm.cpp
@ -1427,8 +1427,10 @@ void CLASS::initpass(void)
|
|||||||
}
|
}
|
||||||
mx = getInt("asm.startmx", mx);;
|
mx = getInt("asm.startmx", mx);;
|
||||||
|
|
||||||
|
|
||||||
savepath = getConfig("option.objfile", "");
|
savepath = getConfig("option.objfile", "");
|
||||||
|
|
||||||
|
lastcarry = false;
|
||||||
relocatable = false;
|
relocatable = false;
|
||||||
currentsym = &topSymbol; // this is the default symbol for :locals without a global above;
|
currentsym = &topSymbol; // this is the default symbol for :locals without a global above;
|
||||||
currentsymstr = "";
|
currentsymstr = "";
|
||||||
@ -1485,6 +1487,14 @@ void CLASS::complete(void)
|
|||||||
f.put(line.outbytes[i]);
|
f.put(line.outbytes[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((line.datafillct > 0) && ((line.flags & FLAG_INDUM) == 0))
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < line.datafillct; i++)
|
||||||
|
{
|
||||||
|
f.put(line.datafillbyte & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1618,6 +1628,35 @@ int CLASS::getAddrMode(MerlinLine & line)
|
|||||||
if (i > 0)
|
if (i > 0)
|
||||||
{
|
{
|
||||||
v = valEx.match(s, 0, 0);
|
v = valEx.match(s, 0, 0);
|
||||||
|
if (v)
|
||||||
|
{
|
||||||
|
if (pass == 0)
|
||||||
|
{
|
||||||
|
// can only check on pass 0, because if the A"
|
||||||
|
// symbol is defined later, we will generate different
|
||||||
|
// bytes on the next pass
|
||||||
|
|
||||||
|
if (Poco::toUpper(oper) == "A") // check the whole operand, not just the expression
|
||||||
|
{
|
||||||
|
// SGQ
|
||||||
|
// Merlin32 supports the 'A" operand for immediate
|
||||||
|
// mode for opcodes like "ROR A". Problem is, Merlin16
|
||||||
|
// does not, and 'A' could be a lable.
|
||||||
|
TSymbol *sym = findSymbol("A");
|
||||||
|
if (sym == NULL)
|
||||||
|
{
|
||||||
|
line.flags |= FLAG_FORCEIMPLIED;
|
||||||
|
mode = syn_implied; // if the label hasn't been defined yet, assume Immediate addressing
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (line.flags & FLAG_FORCEIMPLIED)
|
||||||
|
{
|
||||||
|
mode = syn_implied;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!v)
|
if (!v)
|
||||||
@ -1646,7 +1685,7 @@ int CLASS::getAddrMode(MerlinLine & line)
|
|||||||
}
|
}
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
if (mode == syn_none)
|
if (mode == syn_none)
|
||||||
{
|
{
|
||||||
mode = syn_err;
|
mode = syn_err;
|
||||||
@ -1828,6 +1867,7 @@ void CLASS::process(void)
|
|||||||
int64_t value = -1;
|
int64_t value = -1;
|
||||||
x = evaluate(line, line.operand_expr, value);
|
x = evaluate(line, line.operand_expr, value);
|
||||||
|
|
||||||
|
line.eval_result = x;
|
||||||
if (x == 0)
|
if (x == 0)
|
||||||
{
|
{
|
||||||
value &= 0xFFFFFFFF;
|
value &= 0xFFFFFFFF;
|
||||||
|
6
asm.h
6
asm.h
@ -17,9 +17,10 @@
|
|||||||
#define FLAG_DP 0x08
|
#define FLAG_DP 0x08
|
||||||
#define FLAG_BIGNUM 0x10
|
#define FLAG_BIGNUM 0x10
|
||||||
#define FLAG_INDUM 0x20
|
#define FLAG_INDUM 0x20
|
||||||
|
#define FLAG_FORCEIMPLIED 0x40
|
||||||
|
|
||||||
#define FLAG_FORCEADDRPRINT 0x0100
|
#define FLAG_FORCEADDRPRINT 0x0100
|
||||||
#define FLAG_NOLINEPRINT 0x2000
|
#define FLAG_NOLINEPRINT 0x0200
|
||||||
|
|
||||||
#define OP_A 0x0001
|
#define OP_A 0x0001
|
||||||
#define OP_XY 0x0002
|
#define OP_XY 0x0002
|
||||||
@ -197,7 +198,7 @@ public:
|
|||||||
uint32_t addressmode;
|
uint32_t addressmode;
|
||||||
uint32_t expr_value;
|
uint32_t expr_value;
|
||||||
uint8_t expr_shift; // after an eval, this byte will reflect any shift code on expr (|^<>)
|
uint8_t expr_shift; // after an eval, this byte will reflect any shift code on expr (|^<>)
|
||||||
uint32_t eval_result; // this is the error code from the evaluate routing (0 or neg)
|
int32_t eval_result; // this is the error code from the evaluate routing (0 or neg)
|
||||||
uint32_t errorcode;
|
uint32_t errorcode;
|
||||||
std::string errorText;
|
std::string errorText;
|
||||||
|
|
||||||
@ -344,6 +345,7 @@ public:
|
|||||||
uint32_t dumstartaddr;
|
uint32_t dumstartaddr;
|
||||||
bool skiplist; // used if lst is on, but LST opcode turns it off
|
bool skiplist; // used if lst is on, but LST opcode turns it off
|
||||||
uint32_t lineno;
|
uint32_t lineno;
|
||||||
|
bool lastcarry;
|
||||||
|
|
||||||
std::string savepath;
|
std::string savepath;
|
||||||
TSymbol *currentsym;
|
TSymbol *currentsym;
|
||||||
|
54
opcodes.cpp
54
opcodes.cpp
@ -226,7 +226,7 @@ int CLASS::doNoPattern(MerlinLine &line, TSymbol &sym)
|
|||||||
op = (m == syn_abs ? 0x64 : op);
|
op = (m == syn_abs ? 0x64 : op);
|
||||||
op = (m == syn_absx ? 0x74 : op);
|
op = (m == syn_absx ? 0x74 : op);
|
||||||
|
|
||||||
if ((op != 0) && ((line.expr_value >= 0x100) || (line.flags&FLAG_FORCEABS)))
|
if ((op != 0) && ((line.expr_value >= 0x100) || (line.flags & FLAG_FORCEABS)))
|
||||||
{
|
{
|
||||||
res++;
|
res++;
|
||||||
op = (op == 0x64) ? 0x9C : op;
|
op = (op == 0x64) ? 0x9C : op;
|
||||||
@ -236,7 +236,7 @@ int CLASS::doNoPattern(MerlinLine &line, TSymbol &sym)
|
|||||||
case 2: // TSB
|
case 2: // TSB
|
||||||
res++;
|
res++;
|
||||||
op = (m == syn_abs ? 0x04 : op);
|
op = (m == syn_abs ? 0x04 : op);
|
||||||
if ((op != 0) && ((line.expr_value >= 0x100) || (line.flags&FLAG_FORCEABS)))
|
if ((op != 0) && ((line.expr_value >= 0x100) || (line.flags & FLAG_FORCEABS)))
|
||||||
{
|
{
|
||||||
res++;
|
res++;
|
||||||
op = 0x0C;
|
op = 0x0C;
|
||||||
@ -245,7 +245,7 @@ int CLASS::doNoPattern(MerlinLine &line, TSymbol &sym)
|
|||||||
case 3: // TRB
|
case 3: // TRB
|
||||||
res++;
|
res++;
|
||||||
op = (m == syn_abs ? 0x14 : op);
|
op = (m == syn_abs ? 0x14 : op);
|
||||||
if ((op != 0) && ((line.expr_value >= 0x100) || (line.flags&FLAG_FORCEABS)))
|
if ((op != 0) && ((line.expr_value >= 0x100) || (line.flags & FLAG_FORCEABS)))
|
||||||
{
|
{
|
||||||
res++;
|
res++;
|
||||||
op = 0x1C;
|
op = 0x1C;
|
||||||
@ -422,7 +422,7 @@ int CLASS::doBRANCH(MerlinLine & line, TSymbol & sym)
|
|||||||
if ((offset < -128) || (offset > 127))
|
if ((offset < -128) || (offset > 127))
|
||||||
{
|
{
|
||||||
err = true;
|
err = true;
|
||||||
op=0x00; // merlin does this
|
op = 0x00; // merlin does this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (res == 3) // long branch
|
else if (res == 3) // long branch
|
||||||
@ -439,8 +439,8 @@ int CLASS::doBRANCH(MerlinLine & line, TSymbol & sym)
|
|||||||
setOpcode(line, op);
|
setOpcode(line, op);
|
||||||
for (i = 0; i < (res - 1); i++)
|
for (i = 0; i < (res - 1); i++)
|
||||||
{
|
{
|
||||||
uint8_t v=(offset >> (i*8));
|
uint8_t v = (offset >> (i * 8));
|
||||||
v=err?0x00:v;
|
v = err ? 0x00 : v;
|
||||||
line.outbytes.push_back(v);
|
line.outbytes.push_back(v);
|
||||||
}
|
}
|
||||||
line.outbytect = res;
|
line.outbytect = res;
|
||||||
@ -489,7 +489,7 @@ int CLASS::doBase6502(MerlinLine & line, TSymbol & sym)
|
|||||||
bbb = 0x02;
|
bbb = 0x02;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((bbb > 0) && ((line.expr_value >= 0x100) || (line.flags&FLAG_FORCEABS)))
|
else if ((bbb > 0) && ((line.expr_value >= 0x100) || (line.flags & FLAG_FORCEABS)))
|
||||||
{
|
{
|
||||||
bbb |= 0x02;
|
bbb |= 0x02;
|
||||||
bytelen++;
|
bytelen++;
|
||||||
@ -571,9 +571,9 @@ int CLASS::doBase6502(MerlinLine & line, TSymbol & sym)
|
|||||||
bytelen++;
|
bytelen++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( ((m==syn_absx) || (m==syn_diix)) && ((sym.opcode==4) || (sym.opcode==5))) // these are STX,LDX
|
if ( ((m == syn_absx) || (m == syn_diix)) && ((sym.opcode == 4) || (sym.opcode == 5))) // these are STX,LDX
|
||||||
{
|
{
|
||||||
err=true;
|
err = true;
|
||||||
}
|
}
|
||||||
if ((m == syn_absx) || (m == syn_abs) || (m == syn_absy))
|
if ((m == syn_absx) || (m == syn_abs) || (m == syn_absy))
|
||||||
{
|
{
|
||||||
@ -747,6 +747,30 @@ int CLASS::doBYTE(MerlinLine & line, TSymbol & sym)
|
|||||||
setOpcode(line, sym.opcode);
|
setOpcode(line, sym.opcode);
|
||||||
line.outbytect = res;
|
line.outbytect = res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SGQ merlin32 apparently tracks XCE instructions when tracking MX status
|
||||||
|
// who know how they determine this. I am assuming the NEXT instruction
|
||||||
|
// after a SEC/CLC instruction must be an XCE
|
||||||
|
if (sym.opcode == 0x38) // SEC
|
||||||
|
{
|
||||||
|
lastcarry = true;
|
||||||
|
}
|
||||||
|
else if (sym.opcode == 0x18) // CLC
|
||||||
|
{
|
||||||
|
lastcarry = false;
|
||||||
|
}
|
||||||
|
else if (sym.opcode==0xFB) // XCE
|
||||||
|
{
|
||||||
|
if (trackrep)
|
||||||
|
{
|
||||||
|
if (lastcarry)
|
||||||
|
{
|
||||||
|
mx=0x03;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return (res);
|
return (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -755,23 +779,23 @@ int CLASS::doBRK(MerlinLine & line, TSymbol & sym)
|
|||||||
UNUSED(sym);
|
UNUSED(sym);
|
||||||
|
|
||||||
int res = 1;
|
int res = 1;
|
||||||
int bytes=0;
|
int bytes = 0;
|
||||||
|
|
||||||
if (line.operand_expr!="")
|
if (line.operand_expr != "")
|
||||||
{
|
{
|
||||||
bytes++;
|
bytes++;
|
||||||
}
|
}
|
||||||
if (pass > 0)
|
if (pass > 0)
|
||||||
{
|
{
|
||||||
setOpcode(line, sym.opcode);
|
setOpcode(line, sym.opcode);
|
||||||
for (int i=0;i<bytes;i++)
|
for (int i = 0; i < bytes; i++)
|
||||||
{
|
{
|
||||||
line.outbytes.push_back((line.expr_value>>(8*i))&0xFF);
|
line.outbytes.push_back((line.expr_value >> (8 * i)) & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
line.outbytect = res+bytes;
|
line.outbytect = res + bytes;
|
||||||
}
|
}
|
||||||
return (res+bytes);
|
return (res + bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLASS::insertOpcodes(void)
|
void CLASS::insertOpcodes(void)
|
||||||
|
42
psuedo.cpp
42
psuedo.cpp
@ -119,7 +119,7 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
|
|
||||||
TEvaluator eval(a);
|
TEvaluator eval(a);
|
||||||
|
|
||||||
int64_t eval_result = 0;
|
int64_t eval_value = 0;
|
||||||
uint8_t shift;
|
uint8_t shift;
|
||||||
int lidx, len;
|
int lidx, len;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
@ -135,16 +135,16 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
{
|
{
|
||||||
|
|
||||||
shift = 0;
|
shift = 0;
|
||||||
eval_result = 0;
|
eval_value = 0;
|
||||||
int x = eval.evaluate(line.operand_expr, eval_result, shift);
|
int x = eval.evaluate(line.operand_expr, eval_value, shift);
|
||||||
|
|
||||||
a.LUPstack.push(a.curLUP);
|
a.LUPstack.push(a.curLUP);
|
||||||
|
|
||||||
a.curLUP.lupoffset = len;
|
a.curLUP.lupoffset = len;
|
||||||
a.curLUP.lupct = eval_result & 0xFFFF; // evaluate here
|
a.curLUP.lupct = eval_value & 0xFFFF; // evaluate here
|
||||||
a.curLUP.luprunning++;
|
a.curLUP.luprunning++;
|
||||||
|
|
||||||
if ((x < 0) || (eval_result <= 0) || (eval_result > 0x8000))
|
if ((x < 0) || (eval_value <= 0) || (eval_value > 0x8000))
|
||||||
{
|
{
|
||||||
// merlin just ignores LUP if the value is out of range
|
// merlin just ignores LUP if the value is out of range
|
||||||
a.curLUP.lupct = 0;
|
a.curLUP.lupct = 0;
|
||||||
@ -226,6 +226,9 @@ int CLASS::doDATA(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
|
|
||||||
//printf("DFB TOK1 : |%s|\n", oper.c_str());
|
//printf("DFB TOK1 : |%s|\n", oper.c_str());
|
||||||
|
|
||||||
|
|
||||||
|
line.eval_result=0; // since this is an data p-op, clear the global 'bad operand' flag
|
||||||
|
|
||||||
Poco::StringTokenizer tok(oper, ",", Poco::StringTokenizer::TOK_TRIM |
|
Poco::StringTokenizer tok(oper, ",", Poco::StringTokenizer::TOK_TRIM |
|
||||||
Poco::StringTokenizer::TOK_IGNORE_EMPTY);
|
Poco::StringTokenizer::TOK_IGNORE_EMPTY);
|
||||||
|
|
||||||
@ -264,7 +267,7 @@ int CLASS::doDATA(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
|
|
||||||
//printf("DFB TOK : |%s|\n", expr.c_str());
|
//printf("DFB TOK : |%s|\n", expr.c_str());
|
||||||
|
|
||||||
int64_t eval_result = 0;
|
int64_t eval_value = 0;
|
||||||
uint8_t shift;
|
uint8_t shift;
|
||||||
int r;
|
int r;
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
@ -277,9 +280,9 @@ int CLASS::doDATA(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
expr = Poco::trim(expr);
|
expr = Poco::trim(expr);
|
||||||
}
|
}
|
||||||
shift = 0;
|
shift = 0;
|
||||||
eval_result = 0;
|
eval_value = 0;
|
||||||
//printf("DFB EVAL: |%s|\n", expr.c_str());
|
//printf("DFB EVAL: |%s|\n", expr.c_str());
|
||||||
r = eval.evaluate(expr, eval_result, shift);
|
r = eval.evaluate(expr, eval_value, shift);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
{
|
{
|
||||||
//printf("error %d\n",r);
|
//printf("error %d\n",r);
|
||||||
@ -288,17 +291,17 @@ int CLASS::doDATA(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
line.setError(errBadEvaluation);
|
line.setError(errBadEvaluation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (shift == '>')
|
|
||||||
{
|
|
||||||
eval_result = (eval_result) & 0xFF;
|
|
||||||
}
|
|
||||||
if (shift == '<')
|
if (shift == '<')
|
||||||
{
|
{
|
||||||
eval_result = (eval_result >> 8) & 0xFF;
|
eval_value = (eval_value) & 0xFF;
|
||||||
|
}
|
||||||
|
if (shift == '>')
|
||||||
|
{
|
||||||
|
eval_value = (eval_value >> 8) & 0xFF;
|
||||||
}
|
}
|
||||||
else if ((shift == '^') || (shift == '|'))
|
else if ((shift == '^') || (shift == '|'))
|
||||||
{
|
{
|
||||||
eval_result = (eval_result >> 16) & 0xFF;
|
eval_value = (eval_value >> 16) & 0xFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,7 +312,7 @@ int CLASS::doDATA(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
{
|
{
|
||||||
for (i = 0; i < wordsize; i++)
|
for (i = 0; i < wordsize; i++)
|
||||||
{
|
{
|
||||||
b = (eval_result >> (8 * i)) & 0xFF;
|
b = (eval_value >> (8 * i)) & 0xFF;
|
||||||
line.outbytes.push_back(b);
|
line.outbytes.push_back(b);
|
||||||
//printf("%02X\n",b);
|
//printf("%02X\n",b);
|
||||||
}
|
}
|
||||||
@ -319,7 +322,7 @@ int CLASS::doDATA(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
// big endian
|
// big endian
|
||||||
for (i = 0; i < wordsize; i++)
|
for (i = 0; i < wordsize; i++)
|
||||||
{
|
{
|
||||||
b = (eval_result >> ((wordsize - 1 - i) * 8)) & 0xFF;
|
b = (eval_value >> ((wordsize - 1 - i) * 8)) & 0xFF;
|
||||||
line.outbytes.push_back(b);
|
line.outbytes.push_back(b);
|
||||||
//printf("%02X\n",b);
|
//printf("%02X\n",b);
|
||||||
}
|
}
|
||||||
@ -341,7 +344,7 @@ int CLASS::doDS(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
{
|
{
|
||||||
line.setError(errForwardRef);
|
line.setError(errForwardRef);
|
||||||
}
|
}
|
||||||
else if ((v < 0) || ((a.PC.currentpc + v) >= 0x10000)) // no neg, or crossing bank bound
|
else if ((v < 0) || (((a.PC.currentpc&0xFFFF) + v) >= 0x10000)) // no neg, or crossing bank bound
|
||||||
{
|
{
|
||||||
line.setError(errOverflow);
|
line.setError(errOverflow);
|
||||||
}
|
}
|
||||||
@ -349,7 +352,7 @@ int CLASS::doDS(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
{
|
{
|
||||||
res = v;
|
res = v;
|
||||||
|
|
||||||
line.datafillbyte = line.eval_result & 0xFF;
|
line.datafillbyte = 0x00;
|
||||||
line.datafillct = v;
|
line.datafillct = v;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -468,6 +471,8 @@ int CLASS::doHEX(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
|
|
||||||
std::string os = Poco::trim(line.operand);
|
std::string os = Poco::trim(line.operand);
|
||||||
|
|
||||||
|
line.eval_result=0; // since this is an data p-op, clear the global 'bad operand' flag
|
||||||
|
|
||||||
uint32_t bytect = 0;
|
uint32_t bytect = 0;
|
||||||
uint8_t b = 0;
|
uint8_t b = 0;
|
||||||
uint8_t ct = 0;
|
uint8_t ct = 0;
|
||||||
@ -538,6 +543,7 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||||||
uint32_t ss = 0;
|
uint32_t ss = 0;
|
||||||
std::vector<uint8_t> bytes;
|
std::vector<uint8_t> bytes;
|
||||||
|
|
||||||
|
line.eval_result=0; // since this is an ASCII p-op, clear the global 'bad operand' flag
|
||||||
for ( uint32_t i = 0; i < os.length(); ++i )
|
for ( uint32_t i = 0; i < os.length(); ++i )
|
||||||
{
|
{
|
||||||
char c = os[i];
|
char c = os[i];
|
||||||
|
Loading…
Reference in New Issue
Block a user