Merge pull request #24 from lroathe/master

Fix warnings
This commit is contained in:
Lane Roathe 2019-12-03 08:46:31 -08:00 committed by GitHub
commit 5e09e0ca2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 1090 additions and 362 deletions

View File

@ -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

37
README
View File

@ -1,29 +1,38 @@
Merlin Compatible assembler/linker (and more) for linux
This project is FAR from complete...as I have just gotten it to compile all 256 65816 opcodes.
The program will read/compile linux based Merlin syntax files (.s), as well as original Merlin 8/16/16+ files in Merlin format
(high bit set), compressed spaces, and only a <CR> to end lines. I plan on adding a mode that will process and convert to linux style so
files can be converted for easy editing under linux.
Merlin32 is great, but there are aspects of it that I don't like (always outputting assembly status and creating .txt file listings, etc)
Update (11/19/2019) - All code generating opcodes/psuedo-ops complete.
Along time ago, in the mid 1980's I wrote a Merlin compatible assembler and programming shell (with the help of Lane Roathe) for the Apple //GS
Recently, Lane sent me the source code to that assembler. Unfortunately, because of some of the features we added to the assembler, it will not
compile under Merlin or Merlin32. (We actually used qasm to build qasm).
The program will read/compile linux based Merlin syntax files (.s), as well as original Merlin
8/16/16+ files in Merlin format
(high bit set), compressed spaces, and only a <CR> to end lines. I plan on adding a mode that
will process and convert to linux style so files can be converted for easy editing under linux.
This project will be a linux compatible version, that will compile/link the original source. However, due to speed and everything 'linux'
I doubt the original will be used much.
Merlin32 is great, but there are aspects of it that I don't like (always outputting assembly
status and creating .txt file listings, etc)
I also would like to interface with the CiderPress library to allow output from the assembler/linker to write files directly to Prodos
based .2MG (or other) images. That way, after a compile, the code under test can be immediately run from a GS emulator.
Along time ago, in the mid 1980's I wrote a Merlin compatible assembler and programming shell
(with the help of Lane Roathe) for the Apple //GS
Recently, Lane sent me the source code to that assembler. Unfortunately, because of some of the
features we added to the assembler, it will not compile under Merlin or Merlin32. (We actually used
qasm to build qasm).
This project will be a linux compatible version, that will compile/link the original source.
However, due to speed and everything 'linux' I doubt the original will be used much.
I also would like to interface with the CiderPress library to allow output from the assembler/linker
to write files directly to Prodos based .2MG (or other) images. That way, after a compile, the code
under test can be immediately run from a GS emulator.
This early version relies on the Poco Foundation libraries. You must have these installed.
Additionally, this repo relies on another repo here called 'libpal'. Both repositories must be cloned at the same level.
Additionally, this repo relies on another repo here called 'libpal'. Both repositories must
be cloned at the same level.
libpal does not have to be built. The 'qasm' compile will build all of those source files.
'cmake' is used to build the Makefiles. There is a generic Makefile in the base directory that does all of the 'cmake' stuff for you.
(in a 'build' directory)
'cmake' is used to build the Makefiles. There is a generic Makefile in the base directory that does
all of the 'cmake' stuff for you. (in a 'build' directory)
For example:
mkdir workdir

882
asm.cpp

File diff suppressed because it is too large Load Diff

119
asm.h
View File

@ -8,8 +8,18 @@
#define MODE_65816 2
#define SYNTAX_MERLIN 0
#define SYNTAX_APW 1
#define SYNTAX_ORCA 2
#define SYNTAX_MERLIN32 0x01
#define SYNTAX_APW 0x02
#define SYNTAX_ORCA 0x04
#define SYNTAX_QASM (0x08 | SYNTAX_MERLIN32)
#define OPTION_ALLOW_A_OPERAND 0x0100
#define OPTION_ALLOW_LOCAL 0x0200
#define OPTION_ALLOW_COLON 0x0400
#define OPTION_FORCE_REPSEP 0x0800
#define OPTION_NO_REPSEP 0x1000
#define OPTION_CFG_REPSEP 0x2000
#define OPTION_M32_VARS 0x4000
#define FLAG_FORCELONG 0x01
#define FLAG_FORCEABS 0x02
@ -68,6 +78,7 @@ enum asmErrors
errBadLUPOperand,
errBadLabel,
errBadOperand,
errErrOpcode,
errMAX
};
@ -102,6 +113,7 @@ const std::string errStrings[errMAX + 1] =
"LUP value must be 0 < VAL <= $8000",
"Unknown label",
"Bad operand",
"Break",
""
};
@ -132,6 +144,7 @@ enum
syn_MAX
};
class TOriginSection
{
// SGQ - if you do something unusual here, be aware of copy constructor
@ -177,9 +190,11 @@ class MerlinLine
{
public:
uint8_t syntax;
uint32_t syntax;
std::string wholetext;
std::string lable;
std::string printlable;
std::string printoperand;
std::string opcode;
std::string opcodelower;
std::string operand;
@ -222,9 +237,11 @@ public:
class TFileProcessor
{
protected:
int win_columns;
int win_rows;
std::string initialdir;
std::vector<std::string> filenames;
uint8_t syntax;
uint32_t syntax;
uint64_t starttime;
uint8_t tabs[16];
@ -265,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;
@ -284,9 +302,10 @@ public:
{
clear();
}
void clear(void) {
doskip=false;
value=0;
void clear(void)
{
doskip = false;
value = 0;
}
uint32_t value;
bool doskip;
@ -301,7 +320,8 @@ class TSymbol
public:
std::string namelc;
std::string name;
std::string text;
//std::string text;
std::string var_text;
uint32_t value;
uint16_t stype;
uint8_t opcode;
@ -317,7 +337,8 @@ public:
{
value = 0;
used = false;
text = "";
//text = "";
var_text = "";
name = "";
namelc = "";
stype = 0;
@ -326,6 +347,50 @@ public:
}
};
//typedef Poco::HashMap<std::string, TSymbol> variable_t;
class TVariable
{
public:
uint32_t id;
Poco::HashMap<std::string, TSymbol> vars;
TVariable()
{
// SGQ - must fix this so it is guaranteed unique for each one
id=rand();
}
};
class TMacro
{
public:
std::string name;
std::string lcname;
TVariable variables;
std::vector<MerlinLine> lines;
uint32_t start, end, currentline, len;
uint32_t sourceline;
bool running;
TMacro()
{
clear();
}
void clear(void)
{
name = "";
lcname = "";
variables.vars.clear();
lines.clear();
sourceline = 0;
currentline = 0;
len = 0;
start = 0;
end = 0;
running = false;
}
};
class TPsuedoOp;
class T65816Asm : public TFileProcessor
@ -335,7 +400,6 @@ public:
bool casesen;
bool showmx;
bool trackrep;
bool merlincompat;
bool merlinerrors;
bool allowdup;
uint8_t mx;
@ -355,14 +419,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;
TVariable variables;
TOriginSection PC;
TLUPstruct curLUP;
TDOstruct curDO;
TMacro currentmacro;
TMacro expand_macro;
bool listing;
uint8_t truncdata; // for the TR opcode
@ -370,6 +436,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;
@ -387,19 +455,26 @@ 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, TVariable &vars);
TSymbol *addVariable(std::string sym, std::string val, TVariable &vars, bool replace);
void initpass(void);
void showSymbolTable(bool alpha);
void showVariables(void);
void showMacros(bool alpha);
void showVariables(TVariable &vars);
int evaluate(MerlinLine &line, std::string expr, int64_t &value);
int substituteVariables(MerlinLine & line);
int substituteVariables(MerlinLine & line, std::string &outop);
bool codeSkipped(void);
bool doOFF(void);
int parseOperand(MerlinLine &line);
int getAddrMode(MerlinLine &line);

View File

@ -14,6 +14,7 @@
//#define USE_JSON
//#define USE_XML
#define NO_TTY_SETUP
// help text
#define HELP_USAGE "<options> <list of files>"
#define HELP_PURPOSE "\nMerlin 16+ Compatible 65816 Development Tool"

View File

@ -15,6 +15,7 @@ std::ostream& operator<<(std::ostream& os, const Token& token)
CLASS::CLASS(T65816Asm &_asm) : assembler(_asm)
{
allowMX = false;
}
CLASS::~CLASS()
@ -232,20 +233,30 @@ std::deque<Token> CLASS::shuntingYard(const std::deque<Token>& tokens)
}
else
{
sym = assembler.findSymbol(token.str);
//printf("symbol find |%s| %p\n",token.str.c_str(),sym);
if (sym != NULL)
std::string tok = Poco::toUpper(token.str);
if ((tok == "MX") && (allowMX))
{
sym->used = true;
sprintf(buff, "$%X", sym->value);
token.str = buff;
//printf("MX EVAL\n");
sprintf(buff,"$%02X",assembler.mx&0x03);
token.str=buff;;
}
else
{
setError(Token::unknownSymbolErr);
badsymbol = token.str;
token.str = "0";
sym = assembler.findSymbol(token.str);
//printf("symbol find |%s| %p\n",token.str.c_str(),sym);
if (sym != NULL)
{
sym->used = true;
sprintf(buff, "$%X", sym->value);
token.str = buff;
}
else
{
setError(Token::unknownSymbolErr);
badsymbol = token.str;
token.str = "0";
}
}
}
queue.push_back(token);
@ -380,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];
@ -431,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++)
{
@ -665,7 +676,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 == ">")
{

1
eval.h
View File

@ -68,6 +68,7 @@ protected:
public:
CLASS(T65816Asm &_asm);
~CLASS();
bool allowMX;
std::string badsymbol;
std::deque<Token> shuntingYard(const std::deque<Token>& tokens);
std::deque<Token> exprToTokens(const std::string& expr);

40
merlintests.sh Executable file
View 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

View File

@ -94,7 +94,16 @@ int CLASS::doEQU(MerlinLine &line, TSymbol &sym)
else if (isvar)
{
res = -1;
s = addVariable(line.lable, line.operand, true);
#if 1
char buff[32];
sprintf(buff, "$%08X", line.expr_value);
std::string s1 = buff;
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, variables,true);
#endif
if (s != NULL)
{
res = 0;
@ -185,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;
}
@ -284,6 +298,19 @@ int CLASS::doAddress(MerlinLine &line, TSymbol &sym)
res = 1 + sym.stype;
if (pass > 0)
{
switch(line.expr_shift)
{
case '^':
line.expr_value=(line.expr_value>>16)&0xFFFF;
break;
case '<':
line.expr_value=(line.expr_value)&0xFF;
break;
case '>':
line.expr_value=(line.expr_value>>8)&0xFFFF;
break;
}
//line.setError(errIncomplete);
setOpcode(line, sym.opcode);
for (i = 0; i < (res - 1); i++)
@ -759,13 +786,13 @@ int CLASS::doBYTE(MerlinLine & line, TSymbol & sym)
{
lastcarry = false;
}
else if (sym.opcode==0xFB) // XCE
else if (sym.opcode == 0xFB) // XCE
{
if (trackrep)
{
if (lastcarry)
{
mx=0x03;
mx = 0x03;
}
}
}
@ -819,6 +846,7 @@ void CLASS::insertOpcodes(void)
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));
@ -849,7 +877,7 @@ void CLASS::insertOpcodes(void)
pushopcode("IF", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("FIN", P_DO, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("CHK", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ERR", 0x00, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ERR", P_ERR, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
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));
@ -858,9 +886,10 @@ 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(">>>", P_MAC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO));
pushopcode("ADC", 0x03, OP_STD | OP_A, OPHANDLER(&CLASS::doBase6502));

View File

@ -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);
}
@ -36,6 +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
int64_t eval_value = 0;
uint8_t shift;
@ -130,6 +131,88 @@ 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.expand_macrostack.size() > 0)
{
line.flags |= FLAG_NOLINEPRINT;
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.casesen)
{
a.currentmacro.name = Poco::toUpper(a.currentmacro.name);
}
if (a.pass == 0)
{
}
else
{
// don't need to do anything on pass > 0
}
//printf("macro stack size=%zu\n",a.macrostack.size());
}
else if (op == ">>>")
{
// don't do anything here, let the macro call handler stuff do ths (asm.cpp)
}
else // it is EOM or <<<
{
while (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;
//printf("macro len=%d\n",a.currentmacro.len);
}
a.currentmacro.running = false;
std::pair<std::string, TMacro> p(a.currentmacro.name, a.currentmacro);
//printf("macro insert %s\n",a.currentmacro.name.c_str());
a.macros.insert(p);
a.currentmacro = a.macrostack.top();
a.macrostack.pop();
}
#if 0
else
{
err = errUnexpectedOp;
goto out;
}
#endif
}
out:
if (err)
{
line.setError(err);
}
return (res);
}
int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
{
UNUSED(opinfo);
@ -157,7 +240,14 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
a.LUPstack.push(a.curLUP);
a.curLUP.lupoffset = len;
if (a.expand_macrostack.size() > 0)
{
a.curLUP.lupoffset = a.expand_macro.currentline;
}
else
{
a.curLUP.lupoffset = len;
}
a.curLUP.lupct = eval_value & 0xFFFF; // evaluate here
a.curLUP.luprunning++;
@ -180,6 +270,8 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
if (a.curLUP.luprunning > 0)
{
lidx = line.lineno - 1;
len = lidx - a.curLUP.lupoffset - 1;
@ -188,7 +280,14 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
a.curLUP.lupct--;
if (a.curLUP.lupct != 0)
{
a.lineno = a.curLUP.lupoffset;
if (a.expand_macrostack.size() > 0)
{
a.expand_macro.currentline = a.curLUP.lupoffset;
}
else
{
a.lineno = a.curLUP.lupoffset;
}
goto out;
}
}
@ -215,7 +314,6 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
//err = errUnexpectedOp;
}
}
out:
if (err > 0)
{
@ -340,6 +438,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 +452,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 +518,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);
@ -810,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)
{
@ -843,11 +944,49 @@ int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
a.PC.currentpc = a.PC.orgsave;
line.startpc = a.PC.orgsave;
}
#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)
{
// so clear the bank word in all variables
a.PC.orgsave &= 0xFFFF;
a.PC.currentpc &= 0xFFFF;
line.startpc &= 0xFFFF;
}
#endif
line.flags |= FLAG_FORCEADDRPRINT;
break;
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;
case P_ERR:
if (a.pass > 0)
{
if ((line.expr_value != 0) || (line.eval_result < 0))
{
line.setError(errErrOpcode);
//a.passcomplete=true; // terminate assembly
}
}
res = 0;
break;
case P_LST:
res = doLST(a, line, opinfo);
break;

View File

@ -19,6 +19,9 @@ enum
P_DO,
P_TR,
P_ASC,
P_ERR,
P_MAC,
P_CAS,
P_MAX
};
@ -40,6 +43,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

View File

@ -18,9 +18,11 @@ programOption PAL::appOptions[] =
#ifdef DEBUG
{ "debug", "d", "enable debug info (repeat for more verbosity)", "", false, true},
#endif
//{ "config", "f", "load configuration data from a <file>", " <file>", false, false},
{ "exec", "x", "execute a command [asm, link, reformat] default=asm", " <command>", false, false},
{ "objfile", "o", "write output to file", " <file>", false, false},
//{ "config", "f", "load configuration data from a <file>", "<file>", false, false},
{ "exec", "x", "execute a command [asm, link, reformat] default=asm", "<command>", false, false},
{ "objfile", "o", "write output to file", "<file>", false, false},
{ "syntax", "s", "enforce syntax of other assembler [merlin16, merlin32]", "<syntax>", false, false},
{ "", "", "", "", false, false}
};

View File

@ -4,9 +4,10 @@ logdir=/var/log/mylog
logfile=mylog.log
[option]
debug=1
;==debug must be an integer. Code can use this as a level
;debug=0
nocolor=false
;debug must be an integer. Code can use this as a level
;syntax=merlin32
[application]
timezone=America/Los_Angeles
@ -28,13 +29,11 @@ lst=true
cpu=M65816
trackrep=true
allowduplicate=true
merlinerrors=false
merlincompatible=true
merlinerrors=true
symcolumns=3
[reformat]
tabs=12; 18; 30
;tabs=0;0;0
tabs=12;18;30

View File

@ -1,6 +1,6 @@
#!/bin/bash
OUTDIR=./testout
OUTDIR=./qasmout
TMPFILE=/tmp/qasm_out.txt
rm -f $TMPFILE
@ -27,7 +27,9 @@ for S in $SRC ; do
BASE=${S/.S/}
BASE=${BASE/.s/}
./qasm -o 0/$OUTDIR/$S1 ./testdata/$S >> $TMPFILE
#./qasm -o 0/$OUTDIR/$S1 ./testdata/$S
./qasm --syntax merlin32 -o 0/$OUTDIR/$S1 ./testdata/$S >> $TMPFILE
R=?$
#echo $S " " $S1
@ -38,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=" "

View File

@ -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

View File

@ -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
View 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

View File

@ -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
@ -307,7 +307,7 @@ myQuit
sbc ^$012345
sbc |$012345
asll $1234
;asll $1234
lda <$fff0+24 ;zp
lda >$fff0+24 ;ABS (lo word)
@ -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
@ -411,8 +409,8 @@ L00BC bit L00BC
asc 02,15,?123456?
asc 02,15,>123456>
asc 02,15,<123456<
asc 02,15,5,"123456"
asc 02,15,"123456
asc 02,15,05,"123456"
asc 02,15,"123456"
asc 0215"1234"1502
dci 8D,'Hello',8D,'there',8D
@ -425,7 +423,7 @@ lup_start:
--^
lst off
;lst off
//]XCODEEND ; Keep this at the end and put your code above this
;lst off

View File

@ -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

View File

@ -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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,2 +0,0 @@
,ę,˘˙ę
ę,˘˙ę  V$©˘"  ( V$©3˘D : =ę­V$ E` V$©U˘f`<60><EFBFBD>©™`

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,11 +1,12 @@
(0) 2019-11-17 - BRK does not detect a lable that can't be evaluated
(0) 2019-11-17 - ASCII parsing in both eval and for ASC type commands
(0) 2019-11-17 - IF processing for character compare mode
(0) 2019-11-17 -
(0) 2019-11-17 -
(0) 2019-11-17 -
(0) 2019-11-17 -
(0) 2019-11-17 -
(0) 2019-11-17 - Note (syntax): Merlin doesn't allow local labels without a previous global
(0) 2019-11-17 - Note (syntax): Merlin doesn't allow local colons after label which is ignored
(0) 2019-11-17 - Note (syntax): Merlin doesn't allow for 'rep/sep/xce' tracking
(0) 2019-11-17 - Bug (evaluation routine puts ascii bytes in reverse order (#"AB")
(0) 2019-11-17 - want to wrap comments based on current terminal width, and don't if printing to non-terminal
(0) 2019-11-17 - syntax options - check OPTION bits, not syntax type (OPTION_ALLOW_LOCAL)
(0) 2019-11-17 -
(0) 2019-11-17 -
(0) 2019-11-17 -