mirror of https://github.com/marketideas/qasm.git
working on parameters and options
This commit is contained in:
parent
6e9eb6cfcc
commit
107598bb02
|
@ -5,8 +5,6 @@
|
|||
*.a
|
||||
*.so
|
||||
Finder.Data
|
||||
test.s
|
||||
disk_commands.txt
|
||||
.vscode/browse*
|
||||
.vscode/book*
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
// Resolved by CMake Tools:
|
||||
"program": "${command:cmake.launchTargetPath}",
|
||||
"args": [
|
||||
" -d -d -d",
|
||||
"${workspaceFolder}/test.s"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
set(CIDER "1")
|
||||
#set(CIDER "1")
|
||||
#set (CMAKE_C_COMPILER /usr/bin/clang)
|
||||
#set (CMAKE_CXX_COMPILER /usr/bin/clang++)
|
||||
|
||||
|
@ -45,6 +45,8 @@ set(SOURCE
|
|||
${PROJECT_ROOT}/psuedo.cpp
|
||||
${PROJECT_ROOT}/qoptions.cpp
|
||||
${PROJECT_ROOT}/cider.cpp
|
||||
${PROJECT_ROOT}/util.cpp
|
||||
|
||||
)
|
||||
|
||||
#find_package(OpenSSL REQUIRED)
|
||||
|
@ -67,7 +69,6 @@ include_directories(BEFORE
|
|||
set (CIDERLIBS "" )
|
||||
if ( ${CIDER} )
|
||||
add_definitions(-DCIDERPRESS)
|
||||
add_definitions(-DAPPVERSION=${APPVERSION})
|
||||
|
||||
include_directories(AFTER ${PROJECT_ROOT}/diskimg)
|
||||
add_subdirectory(${PROJECT_ROOT}/libhfs)
|
||||
|
@ -81,6 +82,8 @@ find_library(NUFX_LIB libnufx_static.a ${PROJECT_ROOT}/build )
|
|||
set (CIDERLIBS diskimg_static hfs_static nufx_static ${ZLIB_LIBRARIES})
|
||||
endif ( ${CIDER} )
|
||||
|
||||
add_definitions(-DAPPVERSION=${APPVERSION})
|
||||
|
||||
add_subdirectory(${PROJECT_ROOT}/libpal)
|
||||
|
||||
add_executable( ${PROJECT_NAME} ${SOURCE})
|
||||
|
|
7
Makefile
7
Makefile
|
@ -30,6 +30,12 @@ debug:
|
|||
-mkdir -p ./build
|
||||
-cd ./build && cmake -DCMAKE_BUILD_TYPE=DEBUG .. && $(MAKE) $S
|
||||
|
||||
cider:
|
||||
-rm -rf ./build
|
||||
-mkdir -p ./build
|
||||
-cd ./build && cmake -DCIDER=1 -DCMAKE_BUILD_TYPE=DEBUG .. && $(MAKE) $S
|
||||
|
||||
|
||||
distclean: clean
|
||||
-rm -rf ./qasmout
|
||||
-rm -rf ./m32out
|
||||
|
@ -38,7 +44,6 @@ distclean: clean
|
|||
clean:
|
||||
-rm -rf ./build *.2mg test.bin
|
||||
|
||||
|
||||
depend:
|
||||
-cd ./build && $(MAKE) depend
|
||||
|
||||
|
|
153
asm.cpp
153
asm.cpp
|
@ -11,12 +11,12 @@
|
|||
#define CLASS MerlinLine
|
||||
|
||||
|
||||
CLASS::CLASS()
|
||||
CLASS::CLASS(ConfigOptions &opt) //: options(opt)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
CLASS::CLASS(std::string line)
|
||||
CLASS::CLASS(std::string line, ConfigOptions &opt) //: options(opt)
|
||||
{
|
||||
clear();
|
||||
set(line);
|
||||
|
@ -28,13 +28,11 @@ void CLASS::setError(uint32_t ecode)
|
|||
errorcode = ecode;
|
||||
}
|
||||
|
||||
|
||||
void CLASS::print(uint32_t lineno)
|
||||
{
|
||||
uint32_t l, i, savpcol, pcol;
|
||||
bool commentprinted = false;
|
||||
static bool checked = false;
|
||||
static bool nc1 = false;
|
||||
bool nc = false;
|
||||
uint8_t commentcol = tabs[2];
|
||||
|
||||
uint32_t b = 4; // how many bytes show on the first line
|
||||
|
@ -66,27 +64,17 @@ void CLASS::print(uint32_t lineno)
|
|||
flags &= (~FLAG_NOLINEPRINT);
|
||||
}
|
||||
|
||||
if (flags & FLAG_NOLINEPRINT)
|
||||
bool np=(flags & FLAG_NOLINEPRINT);
|
||||
if (options->isQuiet())
|
||||
np=true;
|
||||
if (options->isList())
|
||||
np=false;
|
||||
|
||||
if (np)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!checked)
|
||||
{
|
||||
nc1 = getBool("option.nocolor", false);
|
||||
checked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
nc = nc1;
|
||||
}
|
||||
|
||||
//if ((!isatty(STDOUT_FILENO)) || (merlinerrors))
|
||||
if ((!isatty(STDOUT_FILENO)) || (0))
|
||||
{
|
||||
nc = true;
|
||||
}
|
||||
|
||||
if (!nc)
|
||||
if (options->useColor())
|
||||
{
|
||||
if (errorcode > 0)
|
||||
{
|
||||
|
@ -156,7 +144,9 @@ void CLASS::print(uint32_t lineno)
|
|||
|
||||
if (isDebug() > 1)
|
||||
{
|
||||
pcol += printf("%02X ", addressmode & 0xFF);
|
||||
//pcol += printf("%02X ", addressmode & 0xFF);
|
||||
pcol += printf(" %s ", addrtext.c_str());
|
||||
|
||||
}
|
||||
|
||||
savpcol = pcol; // this is how many bytes are in the side margin
|
||||
|
@ -250,7 +240,7 @@ void CLASS::print(uint32_t lineno)
|
|||
}
|
||||
//printf("\n");
|
||||
|
||||
if ((!nc) && (errorcode > 0))
|
||||
if ((options->useColor()) && (errorcode > 0))
|
||||
{
|
||||
SetColor(CL_NORMAL | BG_NORMAL);
|
||||
}
|
||||
|
@ -522,7 +512,8 @@ void CLASS::set(std::string line)
|
|||
if (x > 1)
|
||||
{
|
||||
// M32 syntax allows a colon after lable, and it is not part of the lable
|
||||
if ((syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32)
|
||||
//if ((syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32)
|
||||
if (options->isMerlin32())
|
||||
{
|
||||
while ((x > 1) && (lable[x - 1] == ':'))
|
||||
{
|
||||
|
@ -539,11 +530,11 @@ void CLASS::set(std::string line)
|
|||
#undef CLASS
|
||||
#define CLASS TFileProcessor
|
||||
|
||||
CLASS::CLASS()
|
||||
CLASS::CLASS(ConfigOptions &opt) : options(opt)
|
||||
{
|
||||
int x;
|
||||
errorct = 0;
|
||||
syntax=SYNTAX_QASM;
|
||||
//syntax=SYNTAX_QASM;
|
||||
|
||||
win_columns = -1;
|
||||
win_rows = -1;
|
||||
|
@ -562,9 +553,9 @@ CLASS::~CLASS()
|
|||
{
|
||||
}
|
||||
|
||||
void CLASS::setSyntax(uint32_t syn)
|
||||
void CLASS::setProduct(string product)
|
||||
{
|
||||
syntax=syn;
|
||||
options.setProduct(product);
|
||||
}
|
||||
|
||||
void CLASS::errorOut(uint16_t code)
|
||||
|
@ -581,7 +572,7 @@ void CLASS::init(void)
|
|||
starttime = GetTickCount();
|
||||
initialdir = Poco::Path::current();
|
||||
filecount = 0;
|
||||
syntax = SYNTAX_QASM;
|
||||
//syntax = SYNTAX_QASM;
|
||||
|
||||
//std::string tabstr = getConfig("reformat.tabs", "8,16,32");
|
||||
std::string tabstr = getConfig("reformat.tabs", "12,24,40,70");
|
||||
|
@ -620,7 +611,10 @@ void CLASS::complete(void)
|
|||
//cout << "Processing Time: " << n - starttime << "ms" << endl;
|
||||
uint64_t x = n - starttime;
|
||||
uint32_t x1 = x & 0xFFFFFFFF;
|
||||
printf("Elapsed time: %u ms\n", x1);
|
||||
if ((!getBool("option.quiet",false)) && (isDebug()>0))
|
||||
{
|
||||
printf("Elapsed time: %u ms\n", x1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -926,11 +920,13 @@ int CLASS::processfile(std::string p, std::string &newfilename)
|
|||
return (res);
|
||||
}
|
||||
|
||||
#if 1
|
||||
#undef CLASS
|
||||
#define CLASS TMerlinConverter
|
||||
CLASS::CLASS() : TFileProcessor()
|
||||
CLASS::CLASS(ConfigOptions &opt) : TFileProcessor(opt)
|
||||
{
|
||||
format_flags=CONVERT_TEST;
|
||||
//options=new ConfigOptions();
|
||||
}
|
||||
CLASS::~CLASS()
|
||||
{
|
||||
|
@ -946,7 +942,7 @@ int CLASS::doline(int lineno, std::string line)
|
|||
{
|
||||
UNUSED(lineno);
|
||||
|
||||
MerlinLine l(line);
|
||||
MerlinLine l(line, options);
|
||||
lines.push_back(l);
|
||||
return 0;
|
||||
}
|
||||
|
@ -969,7 +965,8 @@ void CLASS::process(void)
|
|||
|
||||
for (uint32_t lineno = 0; lineno < ct; lineno++)
|
||||
{
|
||||
MerlinLine &line = lines.at(lineno);
|
||||
MerlinLine line = lines.at(lineno);
|
||||
//printf("line: |%s|\n",line.wholetext.c_str());
|
||||
orval=0x00;
|
||||
if (flags&CONVERT_HIGH)
|
||||
{
|
||||
|
@ -1001,7 +998,14 @@ void CLASS::process(void)
|
|||
t = tabs[2];
|
||||
if (flags&CONVERT_COMPRESS)
|
||||
{
|
||||
len += sprintf(&buff[len+tlen]," ");
|
||||
if (flags&CONVERT_TABS)
|
||||
{
|
||||
len += sprintf(&buff[len+tlen],"\t\t\t\t");
|
||||
}
|
||||
else
|
||||
{
|
||||
len += sprintf(&buff[len+tlen]," ");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1022,7 +1026,14 @@ void CLASS::process(void)
|
|||
{
|
||||
if (flags&CONVERT_COMPRESS)
|
||||
{
|
||||
len += sprintf(&buff[len+tlen]," ");
|
||||
if (flags&CONVERT_TABS)
|
||||
{
|
||||
len += sprintf(&buff[len+tlen],"\t\t\t");
|
||||
}
|
||||
else
|
||||
{
|
||||
len += sprintf(&buff[len+tlen]," ");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1039,7 +1050,14 @@ void CLASS::process(void)
|
|||
{
|
||||
if (flags&CONVERT_COMPRESS)
|
||||
{
|
||||
len += sprintf(&buff[len+tlen]," ");
|
||||
if (flags&CONVERT_TABS)
|
||||
{
|
||||
len += sprintf(&buff[len+tlen],"\t\t\t");
|
||||
}
|
||||
else
|
||||
{
|
||||
len += sprintf(&buff[len+tlen]," ");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1056,7 +1074,14 @@ void CLASS::process(void)
|
|||
{
|
||||
if (flags&CONVERT_COMPRESS)
|
||||
{
|
||||
len += sprintf(&buff[len+tlen]," ");
|
||||
if (flags&CONVERT_TABS)
|
||||
{
|
||||
len += sprintf(&buff[len+tlen],"\t\t\t");
|
||||
}
|
||||
else
|
||||
{
|
||||
len += sprintf(&buff[len+tlen]," ");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1125,8 +1150,11 @@ void CLASS::process(void)
|
|||
buff[idx++]=c|orval;
|
||||
}
|
||||
}
|
||||
buff[idx]=0;
|
||||
fprintf(stdout,"%s",buff);
|
||||
#if 0
|
||||
FILE *f=NULL;
|
||||
//string outfile=
|
||||
|
||||
f=fopen("./aout.s","w+");
|
||||
if (f!=NULL)
|
||||
{
|
||||
|
@ -1138,18 +1166,20 @@ void CLASS::process(void)
|
|||
{
|
||||
printf("file error\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void CLASS::complete(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#undef CLASS
|
||||
#define CLASS T65816Asm
|
||||
|
||||
CLASS::CLASS() : TFileProcessor()
|
||||
CLASS::CLASS(ConfigOptions &opt) : TFileProcessor(opt)
|
||||
{
|
||||
lines.clear();
|
||||
psuedoops = new TPsuedoOp();
|
||||
|
@ -1588,7 +1618,8 @@ int CLASS::callOpCode(std::string op, MerlinLine &line)
|
|||
//line.expr_value = (line.expr_value >> 16) & 0xFFFF;
|
||||
break;
|
||||
case '|':
|
||||
if (syntax == SYNTAX_MERLIN)
|
||||
//if (syntax == SYNTAX_MERLIN)
|
||||
if (options.isMerlin())
|
||||
{
|
||||
line.setError(errBadLabel);
|
||||
line.expr_value = 0;
|
||||
|
@ -1790,6 +1821,7 @@ void CLASS::initpass(void)
|
|||
|
||||
|
||||
savepath = getConfig("option.objfile", "");
|
||||
//printf("savepath: %s\n",savepath.c_str());
|
||||
|
||||
lastcarry = false;
|
||||
relocatable = false;
|
||||
|
@ -1847,7 +1879,10 @@ void CLASS::complete(void)
|
|||
std::string currentdir = Poco::Path::current();
|
||||
|
||||
savepath = processFilename(savepath, currentdir, 0);
|
||||
printf("saving to file: %s\n", savepath.c_str());
|
||||
if (!options.isQuiet())
|
||||
{
|
||||
printf("saving to file: %s\n", savepath.c_str());
|
||||
}
|
||||
|
||||
std::ofstream f(savepath);
|
||||
|
||||
|
@ -1878,8 +1913,10 @@ void CLASS::complete(void)
|
|||
printf("\nErrors in assembly. Output not SAVED.\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n\nEnd qASM assembly, %d bytes, %u errors, %lu lines, %lu symbols.\n", PC.totalbytes, errorct, lines.size(), symbols.size());
|
||||
if ((!options.isQuiet()) || (options.isList()))
|
||||
{
|
||||
printf("\n\nEnd qASM assembly, %d bytes, %u errors, %lu lines, %lu symbols.\n", PC.totalbytes, errorct, lines.size(), symbols.size());
|
||||
}
|
||||
|
||||
TFileProcessor::complete();
|
||||
|
||||
|
@ -1909,10 +1946,17 @@ int CLASS::evaluate(MerlinLine &line, std::string expr, int64_t &value)
|
|||
{
|
||||
if (isDebug() > 2)
|
||||
{
|
||||
int c = SetColor(CL_RED);
|
||||
int c;
|
||||
if (options.useColor())
|
||||
{
|
||||
c = SetColor(CL_RED);
|
||||
}
|
||||
uint32_t rr = result & 0xFFFFFFFF;
|
||||
printf("eval Error=%d %08X |%s|\n", res, rr, eval.badsymbol.c_str());
|
||||
SetColor(c);
|
||||
if (options.useColor())
|
||||
{
|
||||
SetColor(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (res == 0)
|
||||
|
@ -2015,7 +2059,8 @@ int CLASS::getAddrMode(MerlinLine & line)
|
|||
// symbol is defined later, we will generate different
|
||||
// bytes on the next pass
|
||||
|
||||
if ((line.syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32)
|
||||
if (options.isMerlin32())
|
||||
//if ((line.syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32)
|
||||
{
|
||||
if (Poco::toUpper(oper) == "A") // check the whole operand, not just the expression
|
||||
{
|
||||
|
@ -2281,7 +2326,7 @@ void CLASS::process(void)
|
|||
int x;;
|
||||
char c;
|
||||
char buff[256];
|
||||
MerlinLine errLine;
|
||||
MerlinLine errLine(options);
|
||||
std::string op, realop, operand, ls;
|
||||
|
||||
pass = 0;
|
||||
|
@ -2351,7 +2396,7 @@ void CLASS::process(void)
|
|||
line.linemx = mx;
|
||||
line.bytect = 0;
|
||||
line.showmx = showmx;
|
||||
line.syntax = syntax;
|
||||
//line.syntax = syntax;
|
||||
line.merlinerrors = merlinerrors;
|
||||
|
||||
if ((line.lable != "") && (op != "mac"))
|
||||
|
@ -2476,7 +2521,7 @@ void CLASS::process(void)
|
|||
for (uint32_t lc = expand_macro.start; lc < expand_macro.end; lc++)
|
||||
{
|
||||
//printf("pushing %s\n", lines[lc].wholetext.c_str());
|
||||
MerlinLine nl(lines[lc].wholetext); // create a new clean line (without errors,data)
|
||||
MerlinLine nl(lines[lc].wholetext,options); // create a new clean line (without errors,data)
|
||||
expand_macro.lines.push_back(nl);
|
||||
}
|
||||
expand_macro.running = true;
|
||||
|
@ -2603,7 +2648,7 @@ int CLASS::doline(int lineno, std::string line)
|
|||
|
||||
UNUSED(lineno);
|
||||
|
||||
MerlinLine l(line);
|
||||
MerlinLine l(line,options);
|
||||
|
||||
op = Poco::toLower(l.opcode);
|
||||
if (op == "merlin")
|
||||
|
@ -2614,7 +2659,7 @@ int CLASS::doline(int lineno, std::string line)
|
|||
{
|
||||
syntax = SYNTAX_ORCA;
|
||||
}
|
||||
l.syntax = syntax;
|
||||
//l.syntax = syntax;
|
||||
lines.push_back(l);
|
||||
|
||||
if ((op == "use") || (op == "put"))
|
||||
|
@ -2653,7 +2698,7 @@ int CLASS::doline(int lineno, std::string line)
|
|||
|
||||
#define CLASS T65816Link
|
||||
|
||||
CLASS::CLASS() : TFileProcessor()
|
||||
CLASS::CLASS(ConfigOptions &opt) : TFileProcessor(opt)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
43
asm.h
43
asm.h
|
@ -5,27 +5,6 @@
|
|||
//
|
||||
#define OPHANDLER(ACB) std::bind(ACB, this, std::placeholders::_1, std::placeholders::_2)
|
||||
|
||||
#define MODE_6502 0
|
||||
#define MODE_65C02 1
|
||||
#define MODE_65816 2
|
||||
|
||||
#define SYNTAX_MERLIN 0x01
|
||||
#define SYNTAX_MERLIN32 0x02
|
||||
#define SYNTAX_APW 0x04
|
||||
#define SYNTAX_MPW 0x08
|
||||
#define SYNTAX_ORCA 0x10
|
||||
#define SYNTAX_CC65 0x20
|
||||
#define SYNTAX_LISA 0x40
|
||||
|
||||
#define SYNTAX_QASM (0x80 | SYNTAX_MERLIN)
|
||||
#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 OPTION_M16_PLUS 0x8000
|
||||
|
||||
#define FLAG_FORCELONG 0x01
|
||||
#define FLAG_FORCEABS 0x02
|
||||
|
@ -196,7 +175,8 @@ class MerlinLine
|
|||
{
|
||||
public:
|
||||
|
||||
uint32_t syntax;
|
||||
//uint32_t syntax;
|
||||
ConfigOptions *options;
|
||||
std::string wholetext;
|
||||
std::string lable;
|
||||
std::string printlable;
|
||||
|
@ -233,8 +213,8 @@ public:
|
|||
std::vector<uint8_t> outbytes;
|
||||
|
||||
public:
|
||||
MerlinLine();
|
||||
MerlinLine(std::string line);
|
||||
MerlinLine(ConfigOptions &opt);
|
||||
MerlinLine(std::string line, ConfigOptions &opt);
|
||||
void clear();
|
||||
void set(std::string line);
|
||||
void print(uint32_t lineno);
|
||||
|
@ -255,11 +235,12 @@ protected:
|
|||
uint32_t filecount; // how many files have been read in (because of included files from source
|
||||
|
||||
public:
|
||||
ConfigOptions &options;
|
||||
uint32_t errorct;
|
||||
std::string filename;
|
||||
uint32_t format_flags;
|
||||
|
||||
TFileProcessor();
|
||||
TFileProcessor(ConfigOptions &opt);
|
||||
virtual ~TFileProcessor();
|
||||
virtual std::string processFilename(std::string p, std::string currentdir, int level);
|
||||
virtual int processfile(std::string p, std::string &newfilename);
|
||||
|
@ -268,7 +249,7 @@ public:
|
|||
virtual void process(void);
|
||||
virtual void complete(void);
|
||||
virtual void errorOut(uint16_t code);
|
||||
virtual void setSyntax(uint32_t syn);
|
||||
virtual void setProduct(string product);
|
||||
};
|
||||
|
||||
|
||||
|
@ -277,6 +258,7 @@ public:
|
|||
#define CONVERT_CRLF 0x02
|
||||
#define CONVERT_COMPRESS 0x04
|
||||
#define CONVERT_HIGH 0x08
|
||||
#define CONVERT_TABS 0x10
|
||||
#define CONVERT_MERLIN (CONVERT_HIGH|CONVERT_COMPRESS)
|
||||
#define CONVERT_LINUX (CONVERT_LF)
|
||||
#define CONVERT_WINDOWS (CONVERT_CRLF)
|
||||
|
@ -284,19 +266,22 @@ public:
|
|||
#define CONVERT_MPW (CONVERT_NONE)
|
||||
#define CONVERT_TEST (CONVERT_COMPRESS|CONVERT_LF)
|
||||
|
||||
|
||||
#if 1
|
||||
class TMerlinConverter : public TFileProcessor
|
||||
{
|
||||
protected:
|
||||
std::vector<MerlinLine> lines;
|
||||
|
||||
public:
|
||||
TMerlinConverter();
|
||||
TMerlinConverter(ConfigOptions &opt);
|
||||
virtual ~TMerlinConverter();
|
||||
virtual void init(void);
|
||||
virtual int doline(int lineno, std::string line);
|
||||
virtual void process(void);
|
||||
virtual void complete(void);
|
||||
};
|
||||
#endif
|
||||
|
||||
class TLUPstruct
|
||||
{
|
||||
|
@ -466,7 +451,7 @@ public:
|
|||
|
||||
uint16_t pass;
|
||||
|
||||
T65816Asm();
|
||||
T65816Asm(ConfigOptions &opt);
|
||||
virtual ~T65816Asm();
|
||||
|
||||
virtual void init(void);
|
||||
|
@ -527,7 +512,7 @@ public:
|
|||
class T65816Link : public TFileProcessor
|
||||
{
|
||||
public:
|
||||
T65816Link();
|
||||
T65816Link(ConfigOptions &opt);
|
||||
virtual ~T65816Link();
|
||||
virtual void init(void);
|
||||
virtual int doline(int lineno, std::string line);
|
||||
|
|
2
cider.h
2
cider.h
|
@ -17,7 +17,7 @@ class CLASS : public TFileProcessor
|
|||
protected:
|
||||
std::vector<MerlinLine> lines;
|
||||
public:
|
||||
CLASS();
|
||||
CLASS(ConfigOptions &opt);
|
||||
virtual ~CLASS();
|
||||
int CreateVolume(string OSName, string VolName, uint64_t size, CIDER_VOLFORMAT format);
|
||||
int RunScript(string path);
|
||||
|
|
2
config.h
2
config.h
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define NO_TTY_SETUP
|
||||
// help text
|
||||
#define HELP_USAGE "<options> <list of files>"
|
||||
#define HELP_USAGE "<options> file1 <file2 file3 ...>"
|
||||
#define HELP_PURPOSE "\nMerlin 8/16(+)/32 Compatible 65816 Development Tool"
|
||||
|
||||
|
||||
|
|
|
@ -202,7 +202,8 @@ int CLASS::doMVN(MerlinLine &line, TSymbol &sym)
|
|||
setOpcode(line, op);
|
||||
// these bytes are the two bank registers
|
||||
|
||||
if (((line.syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32) && (v<256))
|
||||
if (options.isMerlin32() && (v<256))
|
||||
//if (((line.syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32) && (v<256))
|
||||
{
|
||||
// merlin32 uses the low byte of the two operands
|
||||
line.outbytes.push_back((v) & 0xFF);
|
||||
|
|
10
parms.json
10
parms.json
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"version": "1.1",
|
||||
"general": {
|
||||
"color_output": true,
|
||||
"nocolor": false,
|
||||
"prefix": [
|
||||
{
|
||||
"0": "${PWD}"
|
||||
|
@ -18,12 +18,12 @@
|
|||
]
|
||||
},
|
||||
"asm": {
|
||||
"syntax": "merlin16plus", //merlin8, merlin16, merlin16plus,merlin32
|
||||
"syntax": "merlin16plus",
|
||||
"cpu": "M6502",
|
||||
"startmx": 3,
|
||||
"listmode": "on",
|
||||
"casesend": true,
|
||||
"lst": false,
|
||||
"casesen": true,
|
||||
"start_lst": false,
|
||||
"showmx": true,
|
||||
"allowduplicate": true,
|
||||
"trackrep": false,
|
||||
|
@ -32,7 +32,7 @@
|
|||
"allowA": true,
|
||||
"allowLocal": true,
|
||||
"allowColon": true,
|
||||
"repsep": "force", //force,no,cfg
|
||||
"repsep": "force",
|
||||
"linebytes": 4,
|
||||
"line2bytes": 8
|
||||
},
|
||||
|
|
396
psuedo.cpp
396
psuedo.cpp
|
@ -179,31 +179,32 @@ int CLASS::doMAC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||
}
|
||||
else // it is EOM or <<<
|
||||
{
|
||||
while (a.macrostack.size() > 0)
|
||||
if (a.macrostack.size()>0)
|
||||
{
|
||||
a.currentmacro.end = line.lineno - 1;
|
||||
a.currentmacro.len = 0;
|
||||
if (a.currentmacro.end >= a.currentmacro.start)
|
||||
while (a.macrostack.size() > 0)
|
||||
{
|
||||
a.currentmacro.len = a.currentmacro.end - a.currentmacro.start;
|
||||
//printf("macro len=%d\n",a.currentmacro.len);
|
||||
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();
|
||||
}
|
||||
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)
|
||||
|
@ -351,27 +352,27 @@ int CLASS::doDATA(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||
const char *ptr = (const char *)op.c_str();
|
||||
switch (strhash(ptr) )
|
||||
{
|
||||
case strhash((const char *)"DA"):
|
||||
case strhash((const char *)"DW"):
|
||||
wordsize = 2;
|
||||
break;
|
||||
case strhash((const char *)"DDB"):
|
||||
wordsize = 2;
|
||||
endian = 1;
|
||||
break;
|
||||
case strhash((const char *)"DFB"):
|
||||
case strhash((const char *)"DB"):
|
||||
wordsize = 1;
|
||||
break;
|
||||
case strhash((const char *)"ADR"):
|
||||
wordsize = 3;
|
||||
break;
|
||||
case strhash((const char *)"ADRL"):
|
||||
wordsize = 4;
|
||||
break;
|
||||
default:
|
||||
wordsize = 0;
|
||||
break;
|
||||
case strhash((const char *)"DA"):
|
||||
case strhash((const char *)"DW"):
|
||||
wordsize = 2;
|
||||
break;
|
||||
case strhash((const char *)"DDB"):
|
||||
wordsize = 2;
|
||||
endian = 1;
|
||||
break;
|
||||
case strhash((const char *)"DFB"):
|
||||
case strhash((const char *)"DB"):
|
||||
wordsize = 1;
|
||||
break;
|
||||
case strhash((const char *)"ADR"):
|
||||
wordsize = 3;
|
||||
break;
|
||||
case strhash((const char *)"ADRL"):
|
||||
wordsize = 4;
|
||||
break;
|
||||
default:
|
||||
wordsize = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
for (auto itr = tok.begin(); itr != tok.end(); ++itr)
|
||||
|
@ -666,12 +667,12 @@ int CLASS::doHEX(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||
// Got a good char, append to hex string and see if we've got a byte
|
||||
switch (ct)
|
||||
{
|
||||
case 0:
|
||||
b = (hv << 4);
|
||||
break;
|
||||
case 1:
|
||||
b |= hv;
|
||||
break;
|
||||
case 0:
|
||||
b = (hv << 4);
|
||||
break;
|
||||
case 1:
|
||||
b |= hv;
|
||||
break;
|
||||
}
|
||||
ct = (ct + 1) & 0x01;
|
||||
if (!ct)
|
||||
|
@ -695,7 +696,8 @@ out:
|
|||
return bytect;
|
||||
}
|
||||
|
||||
static int usr_hash(std::string os) {
|
||||
static int usr_hash(std::string os)
|
||||
{
|
||||
int hash = 0;
|
||||
|
||||
os.resize(4, ' ');
|
||||
|
@ -704,7 +706,10 @@ static int usr_hash(std::string os) {
|
|||
hash = (os[0] & 0x1f) << 11;
|
||||
hash |= (os[1] & 0x1f) << 6;
|
||||
hash |= (os[2] & 0x1f) << 1;
|
||||
if (os[3] == 'L') hash |= 0x01;
|
||||
if (os[3] == 'L')
|
||||
{
|
||||
hash |= 0x01;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
@ -727,12 +732,14 @@ int CLASS::doUSR(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||
|
||||
char c = os.empty() ? 0 : os.front();
|
||||
|
||||
if (c == '$' && os.length() > 1) {
|
||||
if (c == '$' && os.length() > 1)
|
||||
{
|
||||
|
||||
for (uint32_t i = 1; i < os.length(); ++i)
|
||||
{
|
||||
char hv = hexVal(os[i]);
|
||||
if (hv < 0) {
|
||||
if (hv < 0)
|
||||
{
|
||||
line.setError(errIllegalCharOperand);
|
||||
bytect = 0;
|
||||
goto out;
|
||||
|
@ -741,18 +748,25 @@ int CLASS::doUSR(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||
hash |= hv;
|
||||
}
|
||||
|
||||
} else if ((c == '\'' || c == '\"') && os.front() == os.back() && os.length() == 6) {
|
||||
}
|
||||
else if ((c == '\'' || c == '\"') && os.front() == os.back() && os.length() == 6)
|
||||
{
|
||||
hash = usr_hash(os.substr(1, 4));
|
||||
} else if (os.length() > 0 && os.length() <= 4) {
|
||||
}
|
||||
else if (os.length() > 0 && os.length() <= 4)
|
||||
{
|
||||
hash = usr_hash(os);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("line.setError(errBadOperand);\n");
|
||||
line.setError(errBadOperand);
|
||||
bytect = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (a.pass > 0) {
|
||||
if (a.pass > 0)
|
||||
{
|
||||
line.outbytes.push_back(hash & 0xff);
|
||||
line.outbytes.push_back(hash >> 8);
|
||||
}
|
||||
|
@ -778,7 +792,7 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||
uint8_t ct = 0;
|
||||
uint8_t delimiter = 0;
|
||||
uint32_t ss = 0;
|
||||
uint32_t lastdelimidx = 0;
|
||||
uint32_t lastdelimidx = 0;
|
||||
|
||||
std::vector<uint8_t> bytes;
|
||||
|
||||
|
@ -809,7 +823,7 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||
}
|
||||
|
||||
bytes.push_back(c);
|
||||
lastdelimidx = (uint32_t)(bytes.size() - 1);
|
||||
lastdelimidx = (uint32_t)(bytes.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -847,12 +861,12 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||
// Got a hex char, append to hex string and see if we've got a byte
|
||||
switch (ct)
|
||||
{
|
||||
case 0:
|
||||
b = (hv << 4);
|
||||
break;
|
||||
case 1:
|
||||
b |= hv;
|
||||
break;
|
||||
case 0:
|
||||
b = (hv << 4);
|
||||
break;
|
||||
case 1:
|
||||
b |= hv;
|
||||
break;
|
||||
}
|
||||
ct = (ct + 1) & 0x01;
|
||||
if (!ct)
|
||||
|
@ -885,33 +899,33 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||
//printf("bytect=%d bytes.size()=%zu\n",bytect,bytes.size());
|
||||
switch (strhash(ptr) )
|
||||
{
|
||||
case strhash((const char *)"STRL"):
|
||||
addlen = 2;
|
||||
break;
|
||||
case strhash((const char *)"STR"):
|
||||
addlen = 1;
|
||||
break;
|
||||
case strhash((const char *)"REV"):
|
||||
reverse = true;
|
||||
break;
|
||||
case strhash((const char *)"FLS"):
|
||||
andval = (uint8_t)~0xC0;
|
||||
orval = (uint8_t)0x40;
|
||||
break;
|
||||
case strhash((const char *)"INV"):
|
||||
andval = (uint8_t)~0xC0;
|
||||
orval = 0x00;
|
||||
break;
|
||||
case strhash((const char *)"DCI"):
|
||||
dci = true;
|
||||
break;
|
||||
case strhash((const char *)"ASC"):
|
||||
break;
|
||||
default:
|
||||
line.setError(errBadOpcode);
|
||||
bytect = 0;
|
||||
addlen = 0;
|
||||
break;
|
||||
case strhash((const char *)"STRL"):
|
||||
addlen = 2;
|
||||
break;
|
||||
case strhash((const char *)"STR"):
|
||||
addlen = 1;
|
||||
break;
|
||||
case strhash((const char *)"REV"):
|
||||
reverse = true;
|
||||
break;
|
||||
case strhash((const char *)"FLS"):
|
||||
andval = (uint8_t)~0xC0;
|
||||
orval = (uint8_t)0x40;
|
||||
break;
|
||||
case strhash((const char *)"INV"):
|
||||
andval = (uint8_t)~0xC0;
|
||||
orval = 0x00;
|
||||
break;
|
||||
case strhash((const char *)"DCI"):
|
||||
dci = true;
|
||||
break;
|
||||
case strhash((const char *)"ASC"):
|
||||
break;
|
||||
default:
|
||||
line.setError(errBadOpcode);
|
||||
bytect = 0;
|
||||
addlen = 0;
|
||||
break;
|
||||
}
|
||||
if (a.pass > 0)
|
||||
{
|
||||
|
@ -930,7 +944,7 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||
b = bytes[i];
|
||||
}
|
||||
|
||||
b1 = b & 0x7F;
|
||||
b1 = b & 0x7F;
|
||||
if ((andval != 0xFF) || (orval != 0x00))
|
||||
{
|
||||
b = b1;
|
||||
|
@ -948,16 +962,16 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||
// 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
|
||||
// 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 >= '\'' )
|
||||
//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;
|
||||
}
|
||||
|
@ -982,108 +996,116 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
|||
int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
||||
{
|
||||
int res = 0;
|
||||
std::string s;
|
||||
std::string s,sp;
|
||||
|
||||
switch (opinfo.opcode)
|
||||
{
|
||||
default:
|
||||
res = -1; // undefined p-op
|
||||
line.setError(errUnimplemented);
|
||||
break;
|
||||
case P_DS:
|
||||
res = doDS(a, line, opinfo);
|
||||
break;
|
||||
case P_PUT:
|
||||
case P_USE:
|
||||
// both of these are handled by the input file processor, just allow them to be
|
||||
// processed with no errors here
|
||||
break;
|
||||
case P_DUM:
|
||||
case P_DEND:
|
||||
res = doDUM(a, line, opinfo);
|
||||
line.flags |= FLAG_FORCEADDRPRINT;
|
||||
default:
|
||||
res = -1; // undefined p-op
|
||||
line.setError(errUnimplemented);
|
||||
break;
|
||||
case P_DS:
|
||||
res = doDS(a, line, opinfo);
|
||||
break;
|
||||
case P_PUT:
|
||||
case P_USE:
|
||||
// both of these are handled by the input file processor, just allow them to be
|
||||
// processed with no errors here
|
||||
break;
|
||||
case P_DUM:
|
||||
case P_DEND:
|
||||
res = doDUM(a, line, opinfo);
|
||||
line.flags |= FLAG_FORCEADDRPRINT;
|
||||
|
||||
break;
|
||||
case P_ORG:
|
||||
if (line.operand_expr.length() > 0)
|
||||
{
|
||||
a.PC.orgsave = a.PC.currentpc;
|
||||
a.PC.currentpc = line.expr_value;
|
||||
line.startpc = line.expr_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
a.PC.currentpc = a.PC.orgsave;
|
||||
line.startpc = a.PC.orgsave;
|
||||
}
|
||||
break;
|
||||
case P_ORG:
|
||||
if (line.operand_expr.length() > 0)
|
||||
{
|
||||
a.PC.orgsave = a.PC.currentpc;
|
||||
a.PC.currentpc = line.expr_value;
|
||||
line.startpc = line.expr_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
// 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:
|
||||
line.flags |= FLAG_FORCEADDRPRINT;
|
||||
break;
|
||||
case P_SAV:
|
||||
sp = getConfig("option.objfile", "");
|
||||
if (sp=="")
|
||||
{
|
||||
a.savepath = a.processFilename(line.operand, Poco::Path::current(), 0);
|
||||
break;
|
||||
case P_CAS:
|
||||
s = Poco::toUpper(line.operand);
|
||||
if (s == "SE")
|
||||
}
|
||||
else // if they specified an output name on the command line, use it.
|
||||
{
|
||||
a.savepath = sp;
|
||||
}
|
||||
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))
|
||||
{
|
||||
a.casesen = true;
|
||||
line.setError(errErrOpcode);
|
||||
//a.passcomplete=true; // terminate assembly
|
||||
}
|
||||
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;
|
||||
case P_HEX:
|
||||
res = doHEX(a, line, opinfo);
|
||||
break;
|
||||
case P_DATA:
|
||||
res = doDATA(a, line, opinfo);
|
||||
break;
|
||||
case P_LUP:
|
||||
res = doLUP(a, line, opinfo);
|
||||
break;
|
||||
case P_DO:
|
||||
res = doDO(a, line, opinfo);
|
||||
break;
|
||||
case P_TR:
|
||||
res = doTR(a, line, opinfo);
|
||||
break;
|
||||
case P_ASC:
|
||||
res = doASC(a, line, opinfo);
|
||||
break;
|
||||
}
|
||||
res = 0;
|
||||
break;
|
||||
case P_LST:
|
||||
res = doLST(a, line, opinfo);
|
||||
break;
|
||||
case P_HEX:
|
||||
res = doHEX(a, line, opinfo);
|
||||
break;
|
||||
case P_DATA:
|
||||
res = doDATA(a, line, opinfo);
|
||||
break;
|
||||
case P_LUP:
|
||||
res = doLUP(a, line, opinfo);
|
||||
break;
|
||||
case P_DO:
|
||||
res = doDO(a, line, opinfo);
|
||||
break;
|
||||
case P_TR:
|
||||
res = doTR(a, line, opinfo);
|
||||
break;
|
||||
case P_ASC:
|
||||
res = doASC(a, line, opinfo);
|
||||
break;
|
||||
|
||||
case P_USR:
|
||||
res = doUSR(a, line, opinfo);
|
||||
break;
|
||||
case P_USR:
|
||||
res = doUSR(a, line, opinfo);
|
||||
break;
|
||||
|
||||
}
|
||||
return (res);
|
||||
|
|
88
qasm.cpp
88
qasm.cpp
|
@ -6,7 +6,6 @@
|
|||
|
||||
#define CLASS PAL_APPCLASS
|
||||
|
||||
|
||||
// return a pointer to the actual Application class
|
||||
PAL_BASEAPP *PAL::appFactory(void)
|
||||
{
|
||||
|
@ -21,8 +20,16 @@ programOption PAL::appOptions[] =
|
|||
#endif
|
||||
//{ "config", "f", "load configuration data from a <file>", "<file>", 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},
|
||||
{ "syntax", "s", "enforce syntax of other assembler [qasm, merlin, merlin32, ORCA, APW, MPW, CC65]", "<syntax>", false, false},
|
||||
{ "objfile", "o", "write output to <objfile>", "<objfile>", false, false},
|
||||
{ "instruction", "i", "force the CPU instruction set ('xc' ingored) [6502, 65C02, 65816]", "<cpu>", false, false},
|
||||
|
||||
{ "type", "t", "enforce syntax/features/bugs of other assembler [qasm, merlin8, merlin16, merlin16plus, merlin32, orca, apw, mpw, lisa, ca65]", "<type>", false, false},
|
||||
{ "quiet", "q", "print as little as possible, equivalent to lst off in the assembler ('lst' opcodes will be ignored)", "", false, true},
|
||||
{ "list", "l", "force assembly listing ('lst' opcodes will be ignored)", "", false, true},
|
||||
|
||||
{ "color", "c", "colorize the output", "", false, true},
|
||||
{ "parms", "p", "show the working parameters/options", "", false, true},
|
||||
|
||||
|
||||
|
||||
{ "", "", "", "", false, false}
|
||||
|
@ -75,62 +82,49 @@ int CLASS::runCommandLineApp(void)
|
|||
TFileProcessor *t = NULL;
|
||||
std::string line;
|
||||
std::string startdirectory;
|
||||
std::string appPath;
|
||||
std::string fname;
|
||||
uint32_t syntax;
|
||||
//uint32_t syntax;
|
||||
string product="";
|
||||
string syn;
|
||||
int res = -1;
|
||||
ConfigOptions options;
|
||||
|
||||
//Poco::Util::Application::instance().config()
|
||||
|
||||
utils=new QUtils();
|
||||
|
||||
//LOG_NOTE << "this is it!" << endl;
|
||||
|
||||
startdirectory = Poco::Path::current();
|
||||
|
||||
appPath=utils->getAppPath();
|
||||
if (commandargs.size() == 0)
|
||||
{
|
||||
displayHelp();
|
||||
return (res);
|
||||
}
|
||||
|
||||
options.ReadFile(startdirectory+"/parms.json");
|
||||
options.ReadFile(Poco::Path::config()+"/parms.json");
|
||||
options.ReadFile(appPath+"/parms.json");
|
||||
options.ReadFile(Poco::Path::configHome()+"/parms.json");
|
||||
options.ReadFile(Poco::Path::current()+"/parms.json");
|
||||
|
||||
string syn=options.GetString("assembler.syntax","QASM");
|
||||
syn="QASM";
|
||||
//syn=options.GetString("assembler.syntax","QASM");
|
||||
|
||||
string cmdsyn = Poco::toUpper(getConfig("option.syntax", ""));
|
||||
string cmdsyn = Poco::toUpper(getConfig("option.type", ""));
|
||||
if (cmdsyn!="")
|
||||
{
|
||||
syn=cmdsyn; // if they overrode the syntax on the command line, use it
|
||||
}
|
||||
|
||||
syn=Poco::toUpper(syn);
|
||||
syn=Poco::trim(syn);
|
||||
syntax=SYNTAX_QASM;
|
||||
if ((syn=="MERLIN") || (syn=="MERLIN16") || (syn=="MERLIN8") || (syn=="MERLIN16PLUS"))
|
||||
{
|
||||
syntax=SYNTAX_MERLIN;
|
||||
}
|
||||
else if (syn=="MERLIN32")
|
||||
{
|
||||
syntax=SYNTAX_MERLIN32;
|
||||
}
|
||||
else if (syn=="QASM")
|
||||
{
|
||||
syntax=SYNTAX_QASM;
|
||||
}
|
||||
else if (syn=="APW")
|
||||
{
|
||||
syntax=SYNTAX_APW;
|
||||
}
|
||||
else if (syn=="ORCA")
|
||||
{
|
||||
syntax=SYNTAX_ORCA;
|
||||
}
|
||||
else if (syn=="MPW")
|
||||
{
|
||||
syntax=SYNTAX_MPW;
|
||||
}
|
||||
else if (syn=="CC65")
|
||||
{
|
||||
syntax=SYNTAX_CC65;
|
||||
}
|
||||
product=Poco::trim(syn);
|
||||
|
||||
//printf("SYNTAX: |%s|\n",syn.c_str());
|
||||
if (isDebug()>0)
|
||||
{
|
||||
printf("SYNTAX: |%s|\n",syn.c_str());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -196,7 +190,7 @@ int CLASS::runCommandLineApp(void)
|
|||
{
|
||||
format_flags=CONVERT_TEST;
|
||||
}
|
||||
|
||||
options.format_flags=format_flags;
|
||||
cmd=toks[0];
|
||||
}
|
||||
}
|
||||
|
@ -205,13 +199,14 @@ int CLASS::runCommandLineApp(void)
|
|||
if (cmd == "FORMAT")
|
||||
{
|
||||
res = 0;
|
||||
t = new TMerlinConverter();
|
||||
t = new TMerlinConverter(options);
|
||||
//t=NULL;
|
||||
if (t != NULL)
|
||||
{
|
||||
try
|
||||
{
|
||||
t->init();
|
||||
t->setSyntax(syntax);
|
||||
t->setProduct(product);
|
||||
t->format_flags=format_flags;
|
||||
|
||||
std::string f = path.toString();
|
||||
|
@ -239,13 +234,14 @@ int CLASS::runCommandLineApp(void)
|
|||
else if (cmd == "ASM")
|
||||
{
|
||||
int x;
|
||||
t = new T65816Asm();
|
||||
t = new T65816Asm(options);
|
||||
if (t != NULL)
|
||||
{
|
||||
try
|
||||
{
|
||||
t->init();
|
||||
t->setSyntax(syntax);
|
||||
t->setProduct(product);
|
||||
|
||||
|
||||
std::string f = path.toString();
|
||||
t->filename = f;
|
||||
|
@ -275,13 +271,13 @@ int CLASS::runCommandLineApp(void)
|
|||
else if (cmd == "SCRIPT")
|
||||
{
|
||||
res = 0;
|
||||
t = new CiderPress();
|
||||
t = new CiderPress(options);
|
||||
if (t!=NULL)
|
||||
{
|
||||
try
|
||||
{
|
||||
t->init();
|
||||
t->setSyntax(syntax);
|
||||
t->setProduct(product);
|
||||
|
||||
std::string f = path.toString();
|
||||
t->filename = f;
|
||||
|
|
6
qasm.h
6
qasm.h
|
@ -5,6 +5,7 @@
|
|||
#include <pallogger.h>
|
||||
#include <eventtask.h>
|
||||
#include <baseapp.h>
|
||||
#include "app.h"
|
||||
#include "qoptions.h"
|
||||
#include "util.h"
|
||||
//#include <httpserver.h>
|
||||
|
@ -27,7 +28,10 @@ protected:
|
|||
virtual void displayVersion();
|
||||
|
||||
public:
|
||||
QOptions options;
|
||||
QOptions options;
|
||||
|
||||
};
|
||||
|
||||
extern PAL_LOGGER logger;
|
||||
|
||||
#undef CLASS
|
||||
|
|
|
@ -9,6 +9,7 @@ CLASS::CLASS()
|
|||
jsonin="";
|
||||
jsonobj=NULL;
|
||||
parser.reset();
|
||||
parser.setAllowComments(true);
|
||||
}
|
||||
|
||||
int CLASS::ReadFile(string path)
|
||||
|
@ -17,6 +18,8 @@ int CLASS::ReadFile(string path)
|
|||
|
||||
Poco::FileInputStream fs(path);
|
||||
Poco::StreamCopier::copyToString(fs,jsonin);
|
||||
parser.reset();
|
||||
parser.setAllowComments(true);
|
||||
jsonobj=parser.parse(jsonin);
|
||||
|
||||
config.load(path);
|
||||
|
|
229
qoptions.h
229
qoptions.h
|
@ -1,12 +1,237 @@
|
|||
#pragma once
|
||||
#include "app.h"
|
||||
#include "qasm.h"
|
||||
|
||||
#define MAX_PREFIX 32
|
||||
|
||||
#define MODE_6502 0
|
||||
#define MODE_65C02 1
|
||||
#define MODE_65816 2
|
||||
|
||||
#define SYNTAX_MERLIN 0x01
|
||||
#define SYNTAX_MERLIN32 0x02
|
||||
#define SYNTAX_APW 0x04
|
||||
#define SYNTAX_MPW 0x08
|
||||
#define SYNTAX_ORCA 0x10
|
||||
#define SYNTAX_CC65 0x20
|
||||
#define SYNTAX_LISA 0x40
|
||||
#define SYNTAX_QASM (0x80 | SYNTAX_MERLIN)
|
||||
|
||||
#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 OPTION_M16_PLUS 0x8000
|
||||
|
||||
|
||||
#undef CLASS
|
||||
#define CLASS ConfigOptions
|
||||
class CLASS
|
||||
{
|
||||
protected:
|
||||
vector<shared_ptr<JSONConfiguration>> configs;
|
||||
|
||||
public:
|
||||
Poco::JSON::Parser parser;
|
||||
string jsonin;
|
||||
Dynamic::Var jsonobj=NULL;
|
||||
uint16_t format_flags;
|
||||
|
||||
uint16_t cpu_mode;
|
||||
string product;
|
||||
uint16_t productlevel;
|
||||
string prefixes[MAX_PREFIX];
|
||||
|
||||
uint8_t start_mx;
|
||||
bool start_listmode;
|
||||
bool listmode;
|
||||
|
||||
bool casesen;
|
||||
bool showmx;
|
||||
bool allowDuplicate;
|
||||
bool trackrep;
|
||||
bool merlinerrors;
|
||||
bool m32vars;
|
||||
bool allowA;
|
||||
bool allowLocal;
|
||||
bool allowColon;
|
||||
bool oldevaluation;
|
||||
int16_t linebytes;
|
||||
int16_t overflowbytes;
|
||||
|
||||
//Poco::Util::LayeredConfiguration config;
|
||||
|
||||
bool usecolor;
|
||||
|
||||
CLASS()
|
||||
{
|
||||
setDefaults();
|
||||
setProduct("QASM");
|
||||
}
|
||||
~CLASS()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
//configs.clear();
|
||||
}
|
||||
|
||||
bool useColor(void)
|
||||
{
|
||||
bool res=false;
|
||||
if (getBool("option.color",false))
|
||||
{
|
||||
res=true;
|
||||
}
|
||||
if ((!isatty(STDOUT_FILENO)) || (0))
|
||||
{
|
||||
res=false;
|
||||
}
|
||||
|
||||
return(res);
|
||||
}
|
||||
bool isQuiet(void)
|
||||
{
|
||||
bool res;
|
||||
res=getBool("option.quiet",false);
|
||||
if (isDebug()>0)
|
||||
{
|
||||
res=false;
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
bool isList(void)
|
||||
{
|
||||
bool res;
|
||||
res=getBool("option.list",false);
|
||||
return(res);
|
||||
}
|
||||
|
||||
int ReadFile(string path)
|
||||
{
|
||||
int ret=-1;
|
||||
Poco::Util::JSONConfiguration *jc;
|
||||
|
||||
Poco::Path pp(path);
|
||||
//pp=pp.expand();
|
||||
Poco::File pf(pp);
|
||||
if (isDebug()>1)
|
||||
{
|
||||
printf("parmsfile: %s\n",pp.toString().c_str());
|
||||
}
|
||||
if ((pf.exists()) && (pf.canRead()) && ((pf.isFile()) || (pf.isLink())))
|
||||
{
|
||||
//printf("OK: %s\n",pp.toString().c_str());
|
||||
|
||||
jc=new Poco::Util::JSONConfiguration();
|
||||
//Poco::FileInputStream fs(path);
|
||||
//Poco::StreamCopier::copyToString(fs,jsonin);
|
||||
//parser.reset();
|
||||
//parser.setAllowComments(true);
|
||||
//jsonobj=parser.parse(jsonin);
|
||||
if (jc!=NULL)
|
||||
{
|
||||
bool success=false;
|
||||
try
|
||||
{
|
||||
jc->load(pp.toString());
|
||||
success=true;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
success=false;
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
//configs.push_back(shared_ptr<JSONConfiguration>(jc));
|
||||
ret=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("unable to load/parts file: %s\n",pp.toString().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
void printCurrentOptions(void)
|
||||
{
|
||||
printf("Current Options:");
|
||||
printf(" product: %s\n",product.c_str());
|
||||
//printf(" start_mx: \%%02d\n",start_mx);
|
||||
}
|
||||
|
||||
bool isMerlin32(void)
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool isMerlin(void)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
void setDefaults(void)
|
||||
{
|
||||
cpu_mode=MODE_6502;
|
||||
product="QASM";
|
||||
productlevel=0;
|
||||
for (int i=0; i<MAX_PREFIX; i++)
|
||||
{
|
||||
prefixes[i]="";
|
||||
}
|
||||
start_mx=0x03;
|
||||
start_listmode=true;
|
||||
listmode=start_listmode;
|
||||
casesen=true;
|
||||
showmx=true;
|
||||
allowDuplicate=false;
|
||||
trackrep=false;
|
||||
merlinerrors=true;
|
||||
m32vars=false;
|
||||
|
||||
allowA=true;
|
||||
allowLocal=false;
|
||||
allowColon=false;
|
||||
oldevaluation=true;
|
||||
linebytes=4;
|
||||
overflowbytes=6;
|
||||
usecolor=true;
|
||||
}
|
||||
|
||||
void setProduct(string productName)
|
||||
{
|
||||
string old=productName;
|
||||
string pn=Poco::toUpper(productName);
|
||||
if (old!=pn)
|
||||
{
|
||||
printf("setting product options to %s\n",pn.c_str());
|
||||
productName=pn;
|
||||
if (pn=="QASM")
|
||||
{
|
||||
setQASM();
|
||||
}
|
||||
}
|
||||
}
|
||||
void setQASM()
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#undef CLASS
|
||||
#define CLASS QOptions
|
||||
|
||||
class CLASS
|
||||
{
|
||||
public:
|
||||
Poco::Util::JSONConfiguration config;
|
||||
Poco::Util::JSONConfiguration config;
|
||||
Poco::JSON::Parser parser;
|
||||
string jsonin;
|
||||
Dynamic::Var jsonobj=NULL;
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
product QASM
|
||||
nolist
|
||||
asm test.s -o test.o
|
||||
asm test1.s -o test1.o
|
||||
asm test2.s -o test2.o
|
||||
link test.o test1.o test2.o
|
||||
volume TESTASM test.2mg 800K prodos .2mg
|
||||
copyto TESTASM test.o :SOURCE: 0x06 0x2000
|
||||
copyto TESTASM test.s :SOURCE: 0x04 0x0000 FORMAT-MERLIN
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
* [QASM] SYNTAX MERLIN16
|
||||
* [QASM] Filetype $06
|
||||
* [QASM] AuxType $2000
|
||||
* [QASM] Volume TESTASM test.2mg 800K prodos 2mg
|
||||
* [QASM] save TESTASM :SOURCE:${FILE}.bin
|
||||
|
||||
|
||||
xc off
|
||||
xc
|
||||
xc
|
||||
;lst OFF
|
||||
ZP equ $00
|
||||
org $2000
|
||||
ora ($00)
|
||||
lda ($00)
|
||||
bit: $FFFE,X
|
||||
ror: $FFFE,X
|
||||
ora #ZP
|
||||
begin
|
||||
;]m equ *
|
||||
; lda begin
|
||||
; lda ]m
|
||||
lst on
|
||||
;end
|
||||
|
||||
_mymac mac
|
||||
]mac1 lda ]mac1
|
||||
ldal ]1
|
||||
ldal ]2
|
||||
eom
|
||||
|
||||
_ascmac mac
|
||||
asc ]1,]2,8D
|
||||
eom
|
||||
lst off
|
||||
;var 'one';'two';'three'
|
||||
justlable ;line with just a lable
|
||||
start
|
||||
another lda #$00 ;line with everything
|
||||
lda #$00 ;line with opcode, operand comment
|
||||
nop ;line with just opcode
|
||||
_mymac *;1
|
||||
_mymac *;2
|
||||
_ascmac 'hello';'there'
|
||||
|
||||
lup 2
|
||||
]m equ *
|
||||
nop
|
||||
lda ]m
|
||||
bra ]m
|
||||
--^
|
||||
]1 nop
|
||||
nop
|
||||
lst
|
||||
bra ]1
|
||||
|
||||
;typ $06
|
||||
sav 0/test.bin
|
||||
lst off
|
32
util.cpp
32
util.cpp
|
@ -1,12 +1,38 @@
|
|||
#include <util.h>
|
||||
#define UTIL_CPP
|
||||
#include <app.h>
|
||||
|
||||
bool isMerlin32(void)
|
||||
#undef CLASS
|
||||
#define CLASS QUtils
|
||||
|
||||
CLASS::CLASS() : appInstance(Poco::Util::Application::instance())
|
||||
{
|
||||
}
|
||||
|
||||
bool CLASS::isMerlin32(void)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
bool isMerlin816(void)
|
||||
bool CLASS::isMerlin816(void)
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
|
||||
string CLASS::getAppPath()
|
||||
{
|
||||
char buff[PATH_MAX+1];
|
||||
char *x;
|
||||
|
||||
string res="";
|
||||
res=appInstance.commandPath();
|
||||
x=realpath(res.c_str(),buff);
|
||||
if (x!=NULL)
|
||||
{
|
||||
res=buff;
|
||||
}
|
||||
else
|
||||
res="";
|
||||
return(res);
|
||||
}
|
||||
|
||||
|
||||
|
|
20
util.h
20
util.h
|
@ -1,5 +1,19 @@
|
|||
#pragma once
|
||||
#include <app.h>
|
||||
#include <palPoco.h>
|
||||
|
||||
bool isMerlin32(void);
|
||||
bool isMerlin816(void);
|
||||
class QUtils
|
||||
{
|
||||
protected:
|
||||
Poco::Util::Application &appInstance;
|
||||
public:
|
||||
QUtils();
|
||||
bool isMerlin32(void);
|
||||
bool isMerlin816(void);
|
||||
string getAppPath();
|
||||
};
|
||||
|
||||
#ifdef UTIL_CPP
|
||||
QUtils *utils=NULL;
|
||||
#else
|
||||
extern QUtils *utils;
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue