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
|
*.a
|
||||||
*.so
|
*.so
|
||||||
Finder.Data
|
Finder.Data
|
||||||
test.s
|
|
||||||
disk_commands.txt
|
|
||||||
.vscode/browse*
|
.vscode/browse*
|
||||||
.vscode/book*
|
.vscode/book*
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
// Resolved by CMake Tools:
|
// Resolved by CMake Tools:
|
||||||
"program": "${command:cmake.launchTargetPath}",
|
"program": "${command:cmake.launchTargetPath}",
|
||||||
"args": [
|
"args": [
|
||||||
|
" -d -d -d",
|
||||||
"${workspaceFolder}/test.s"
|
"${workspaceFolder}/test.s"
|
||||||
],
|
],
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
set(CIDER "1")
|
#set(CIDER "1")
|
||||||
#set (CMAKE_C_COMPILER /usr/bin/clang)
|
#set (CMAKE_C_COMPILER /usr/bin/clang)
|
||||||
#set (CMAKE_CXX_COMPILER /usr/bin/clang++)
|
#set (CMAKE_CXX_COMPILER /usr/bin/clang++)
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ set(SOURCE
|
||||||
${PROJECT_ROOT}/psuedo.cpp
|
${PROJECT_ROOT}/psuedo.cpp
|
||||||
${PROJECT_ROOT}/qoptions.cpp
|
${PROJECT_ROOT}/qoptions.cpp
|
||||||
${PROJECT_ROOT}/cider.cpp
|
${PROJECT_ROOT}/cider.cpp
|
||||||
|
${PROJECT_ROOT}/util.cpp
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
#find_package(OpenSSL REQUIRED)
|
#find_package(OpenSSL REQUIRED)
|
||||||
|
@ -67,7 +69,6 @@ include_directories(BEFORE
|
||||||
set (CIDERLIBS "" )
|
set (CIDERLIBS "" )
|
||||||
if ( ${CIDER} )
|
if ( ${CIDER} )
|
||||||
add_definitions(-DCIDERPRESS)
|
add_definitions(-DCIDERPRESS)
|
||||||
add_definitions(-DAPPVERSION=${APPVERSION})
|
|
||||||
|
|
||||||
include_directories(AFTER ${PROJECT_ROOT}/diskimg)
|
include_directories(AFTER ${PROJECT_ROOT}/diskimg)
|
||||||
add_subdirectory(${PROJECT_ROOT}/libhfs)
|
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})
|
set (CIDERLIBS diskimg_static hfs_static nufx_static ${ZLIB_LIBRARIES})
|
||||||
endif ( ${CIDER} )
|
endif ( ${CIDER} )
|
||||||
|
|
||||||
|
add_definitions(-DAPPVERSION=${APPVERSION})
|
||||||
|
|
||||||
add_subdirectory(${PROJECT_ROOT}/libpal)
|
add_subdirectory(${PROJECT_ROOT}/libpal)
|
||||||
|
|
||||||
add_executable( ${PROJECT_NAME} ${SOURCE})
|
add_executable( ${PROJECT_NAME} ${SOURCE})
|
||||||
|
|
7
Makefile
7
Makefile
|
@ -30,6 +30,12 @@ debug:
|
||||||
-mkdir -p ./build
|
-mkdir -p ./build
|
||||||
-cd ./build && cmake -DCMAKE_BUILD_TYPE=DEBUG .. && $(MAKE) $S
|
-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
|
distclean: clean
|
||||||
-rm -rf ./qasmout
|
-rm -rf ./qasmout
|
||||||
-rm -rf ./m32out
|
-rm -rf ./m32out
|
||||||
|
@ -38,7 +44,6 @@ distclean: clean
|
||||||
clean:
|
clean:
|
||||||
-rm -rf ./build *.2mg test.bin
|
-rm -rf ./build *.2mg test.bin
|
||||||
|
|
||||||
|
|
||||||
depend:
|
depend:
|
||||||
-cd ./build && $(MAKE) depend
|
-cd ./build && $(MAKE) depend
|
||||||
|
|
||||||
|
|
153
asm.cpp
153
asm.cpp
|
@ -11,12 +11,12 @@
|
||||||
#define CLASS MerlinLine
|
#define CLASS MerlinLine
|
||||||
|
|
||||||
|
|
||||||
CLASS::CLASS()
|
CLASS::CLASS(ConfigOptions &opt) //: options(opt)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
CLASS::CLASS(std::string line)
|
CLASS::CLASS(std::string line, ConfigOptions &opt) //: options(opt)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
set(line);
|
set(line);
|
||||||
|
@ -28,13 +28,11 @@ void CLASS::setError(uint32_t ecode)
|
||||||
errorcode = ecode;
|
errorcode = ecode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CLASS::print(uint32_t lineno)
|
void CLASS::print(uint32_t lineno)
|
||||||
{
|
{
|
||||||
uint32_t l, i, savpcol, pcol;
|
uint32_t l, i, savpcol, pcol;
|
||||||
bool commentprinted = false;
|
bool commentprinted = false;
|
||||||
static bool checked = false;
|
|
||||||
static bool nc1 = false;
|
|
||||||
bool nc = false;
|
|
||||||
uint8_t commentcol = tabs[2];
|
uint8_t commentcol = tabs[2];
|
||||||
|
|
||||||
uint32_t b = 4; // how many bytes show on the first line
|
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);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (!checked)
|
if (options->useColor())
|
||||||
{
|
|
||||||
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 (errorcode > 0)
|
if (errorcode > 0)
|
||||||
{
|
{
|
||||||
|
@ -156,7 +144,9 @@ void CLASS::print(uint32_t lineno)
|
||||||
|
|
||||||
if (isDebug() > 1)
|
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
|
savpcol = pcol; // this is how many bytes are in the side margin
|
||||||
|
@ -250,7 +240,7 @@ void CLASS::print(uint32_t lineno)
|
||||||
}
|
}
|
||||||
//printf("\n");
|
//printf("\n");
|
||||||
|
|
||||||
if ((!nc) && (errorcode > 0))
|
if ((options->useColor()) && (errorcode > 0))
|
||||||
{
|
{
|
||||||
SetColor(CL_NORMAL | BG_NORMAL);
|
SetColor(CL_NORMAL | BG_NORMAL);
|
||||||
}
|
}
|
||||||
|
@ -522,7 +512,8 @@ void CLASS::set(std::string line)
|
||||||
if (x > 1)
|
if (x > 1)
|
||||||
{
|
{
|
||||||
// M32 syntax allows a colon after lable, and it is not part of the lable
|
// 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] == ':'))
|
while ((x > 1) && (lable[x - 1] == ':'))
|
||||||
{
|
{
|
||||||
|
@ -539,11 +530,11 @@ void CLASS::set(std::string line)
|
||||||
#undef CLASS
|
#undef CLASS
|
||||||
#define CLASS TFileProcessor
|
#define CLASS TFileProcessor
|
||||||
|
|
||||||
CLASS::CLASS()
|
CLASS::CLASS(ConfigOptions &opt) : options(opt)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
errorct = 0;
|
errorct = 0;
|
||||||
syntax=SYNTAX_QASM;
|
//syntax=SYNTAX_QASM;
|
||||||
|
|
||||||
win_columns = -1;
|
win_columns = -1;
|
||||||
win_rows = -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)
|
void CLASS::errorOut(uint16_t code)
|
||||||
|
@ -581,7 +572,7 @@ void CLASS::init(void)
|
||||||
starttime = GetTickCount();
|
starttime = GetTickCount();
|
||||||
initialdir = Poco::Path::current();
|
initialdir = Poco::Path::current();
|
||||||
filecount = 0;
|
filecount = 0;
|
||||||
syntax = SYNTAX_QASM;
|
//syntax = SYNTAX_QASM;
|
||||||
|
|
||||||
//std::string tabstr = getConfig("reformat.tabs", "8,16,32");
|
//std::string tabstr = getConfig("reformat.tabs", "8,16,32");
|
||||||
std::string tabstr = getConfig("reformat.tabs", "12,24,40,70");
|
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;
|
//cout << "Processing Time: " << n - starttime << "ms" << endl;
|
||||||
uint64_t x = n - starttime;
|
uint64_t x = n - starttime;
|
||||||
uint32_t x1 = x & 0xFFFFFFFF;
|
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);
|
return (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
#undef CLASS
|
#undef CLASS
|
||||||
#define CLASS TMerlinConverter
|
#define CLASS TMerlinConverter
|
||||||
CLASS::CLASS() : TFileProcessor()
|
CLASS::CLASS(ConfigOptions &opt) : TFileProcessor(opt)
|
||||||
{
|
{
|
||||||
format_flags=CONVERT_TEST;
|
format_flags=CONVERT_TEST;
|
||||||
|
//options=new ConfigOptions();
|
||||||
}
|
}
|
||||||
CLASS::~CLASS()
|
CLASS::~CLASS()
|
||||||
{
|
{
|
||||||
|
@ -946,7 +942,7 @@ int CLASS::doline(int lineno, std::string line)
|
||||||
{
|
{
|
||||||
UNUSED(lineno);
|
UNUSED(lineno);
|
||||||
|
|
||||||
MerlinLine l(line);
|
MerlinLine l(line, options);
|
||||||
lines.push_back(l);
|
lines.push_back(l);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -969,7 +965,8 @@ void CLASS::process(void)
|
||||||
|
|
||||||
for (uint32_t lineno = 0; lineno < ct; lineno++)
|
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;
|
orval=0x00;
|
||||||
if (flags&CONVERT_HIGH)
|
if (flags&CONVERT_HIGH)
|
||||||
{
|
{
|
||||||
|
@ -1001,7 +998,14 @@ void CLASS::process(void)
|
||||||
t = tabs[2];
|
t = tabs[2];
|
||||||
if (flags&CONVERT_COMPRESS)
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -1022,7 +1026,14 @@ void CLASS::process(void)
|
||||||
{
|
{
|
||||||
if (flags&CONVERT_COMPRESS)
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -1039,7 +1050,14 @@ void CLASS::process(void)
|
||||||
{
|
{
|
||||||
if (flags&CONVERT_COMPRESS)
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -1056,7 +1074,14 @@ void CLASS::process(void)
|
||||||
{
|
{
|
||||||
if (flags&CONVERT_COMPRESS)
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -1125,8 +1150,11 @@ void CLASS::process(void)
|
||||||
buff[idx++]=c|orval;
|
buff[idx++]=c|orval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
buff[idx]=0;
|
||||||
|
fprintf(stdout,"%s",buff);
|
||||||
|
#if 0
|
||||||
FILE *f=NULL;
|
FILE *f=NULL;
|
||||||
//string outfile=
|
|
||||||
f=fopen("./aout.s","w+");
|
f=fopen("./aout.s","w+");
|
||||||
if (f!=NULL)
|
if (f!=NULL)
|
||||||
{
|
{
|
||||||
|
@ -1138,18 +1166,20 @@ void CLASS::process(void)
|
||||||
{
|
{
|
||||||
printf("file error\n");
|
printf("file error\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLASS::complete(void)
|
void CLASS::complete(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#undef CLASS
|
#undef CLASS
|
||||||
#define CLASS T65816Asm
|
#define CLASS T65816Asm
|
||||||
|
|
||||||
CLASS::CLASS() : TFileProcessor()
|
CLASS::CLASS(ConfigOptions &opt) : TFileProcessor(opt)
|
||||||
{
|
{
|
||||||
lines.clear();
|
lines.clear();
|
||||||
psuedoops = new TPsuedoOp();
|
psuedoops = new TPsuedoOp();
|
||||||
|
@ -1588,7 +1618,8 @@ int CLASS::callOpCode(std::string op, MerlinLine &line)
|
||||||
//line.expr_value = (line.expr_value >> 16) & 0xFFFF;
|
//line.expr_value = (line.expr_value >> 16) & 0xFFFF;
|
||||||
break;
|
break;
|
||||||
case '|':
|
case '|':
|
||||||
if (syntax == SYNTAX_MERLIN)
|
//if (syntax == SYNTAX_MERLIN)
|
||||||
|
if (options.isMerlin())
|
||||||
{
|
{
|
||||||
line.setError(errBadLabel);
|
line.setError(errBadLabel);
|
||||||
line.expr_value = 0;
|
line.expr_value = 0;
|
||||||
|
@ -1790,6 +1821,7 @@ void CLASS::initpass(void)
|
||||||
|
|
||||||
|
|
||||||
savepath = getConfig("option.objfile", "");
|
savepath = getConfig("option.objfile", "");
|
||||||
|
//printf("savepath: %s\n",savepath.c_str());
|
||||||
|
|
||||||
lastcarry = false;
|
lastcarry = false;
|
||||||
relocatable = false;
|
relocatable = false;
|
||||||
|
@ -1847,7 +1879,10 @@ void CLASS::complete(void)
|
||||||
std::string currentdir = Poco::Path::current();
|
std::string currentdir = Poco::Path::current();
|
||||||
|
|
||||||
savepath = processFilename(savepath, currentdir, 0);
|
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);
|
std::ofstream f(savepath);
|
||||||
|
|
||||||
|
@ -1878,8 +1913,10 @@ void CLASS::complete(void)
|
||||||
printf("\nErrors in assembly. Output not SAVED.\n\n");
|
printf("\nErrors in assembly. Output not SAVED.\n\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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());
|
{
|
||||||
|
printf("\n\nEnd qASM assembly, %d bytes, %u errors, %lu lines, %lu symbols.\n", PC.totalbytes, errorct, lines.size(), symbols.size());
|
||||||
|
}
|
||||||
|
|
||||||
TFileProcessor::complete();
|
TFileProcessor::complete();
|
||||||
|
|
||||||
|
@ -1909,10 +1946,17 @@ int CLASS::evaluate(MerlinLine &line, std::string expr, int64_t &value)
|
||||||
{
|
{
|
||||||
if (isDebug() > 2)
|
if (isDebug() > 2)
|
||||||
{
|
{
|
||||||
int c = SetColor(CL_RED);
|
int c;
|
||||||
|
if (options.useColor())
|
||||||
|
{
|
||||||
|
c = SetColor(CL_RED);
|
||||||
|
}
|
||||||
uint32_t rr = result & 0xFFFFFFFF;
|
uint32_t rr = result & 0xFFFFFFFF;
|
||||||
printf("eval Error=%d %08X |%s|\n", res, rr, eval.badsymbol.c_str());
|
printf("eval Error=%d %08X |%s|\n", res, rr, eval.badsymbol.c_str());
|
||||||
SetColor(c);
|
if (options.useColor())
|
||||||
|
{
|
||||||
|
SetColor(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (res == 0)
|
if (res == 0)
|
||||||
|
@ -2015,7 +2059,8 @@ int CLASS::getAddrMode(MerlinLine & line)
|
||||||
// symbol is defined later, we will generate different
|
// symbol is defined later, we will generate different
|
||||||
// bytes on the next pass
|
// 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
|
if (Poco::toUpper(oper) == "A") // check the whole operand, not just the expression
|
||||||
{
|
{
|
||||||
|
@ -2281,7 +2326,7 @@ void CLASS::process(void)
|
||||||
int x;;
|
int x;;
|
||||||
char c;
|
char c;
|
||||||
char buff[256];
|
char buff[256];
|
||||||
MerlinLine errLine;
|
MerlinLine errLine(options);
|
||||||
std::string op, realop, operand, ls;
|
std::string op, realop, operand, ls;
|
||||||
|
|
||||||
pass = 0;
|
pass = 0;
|
||||||
|
@ -2351,7 +2396,7 @@ void CLASS::process(void)
|
||||||
line.linemx = mx;
|
line.linemx = mx;
|
||||||
line.bytect = 0;
|
line.bytect = 0;
|
||||||
line.showmx = showmx;
|
line.showmx = showmx;
|
||||||
line.syntax = syntax;
|
//line.syntax = syntax;
|
||||||
line.merlinerrors = merlinerrors;
|
line.merlinerrors = merlinerrors;
|
||||||
|
|
||||||
if ((line.lable != "") && (op != "mac"))
|
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++)
|
for (uint32_t lc = expand_macro.start; lc < expand_macro.end; lc++)
|
||||||
{
|
{
|
||||||
//printf("pushing %s\n", lines[lc].wholetext.c_str());
|
//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.lines.push_back(nl);
|
||||||
}
|
}
|
||||||
expand_macro.running = true;
|
expand_macro.running = true;
|
||||||
|
@ -2603,7 +2648,7 @@ int CLASS::doline(int lineno, std::string line)
|
||||||
|
|
||||||
UNUSED(lineno);
|
UNUSED(lineno);
|
||||||
|
|
||||||
MerlinLine l(line);
|
MerlinLine l(line,options);
|
||||||
|
|
||||||
op = Poco::toLower(l.opcode);
|
op = Poco::toLower(l.opcode);
|
||||||
if (op == "merlin")
|
if (op == "merlin")
|
||||||
|
@ -2614,7 +2659,7 @@ int CLASS::doline(int lineno, std::string line)
|
||||||
{
|
{
|
||||||
syntax = SYNTAX_ORCA;
|
syntax = SYNTAX_ORCA;
|
||||||
}
|
}
|
||||||
l.syntax = syntax;
|
//l.syntax = syntax;
|
||||||
lines.push_back(l);
|
lines.push_back(l);
|
||||||
|
|
||||||
if ((op == "use") || (op == "put"))
|
if ((op == "use") || (op == "put"))
|
||||||
|
@ -2653,7 +2698,7 @@ int CLASS::doline(int lineno, std::string line)
|
||||||
|
|
||||||
#define CLASS T65816Link
|
#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 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_FORCELONG 0x01
|
||||||
#define FLAG_FORCEABS 0x02
|
#define FLAG_FORCEABS 0x02
|
||||||
|
@ -196,7 +175,8 @@ class MerlinLine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
uint32_t syntax;
|
//uint32_t syntax;
|
||||||
|
ConfigOptions *options;
|
||||||
std::string wholetext;
|
std::string wholetext;
|
||||||
std::string lable;
|
std::string lable;
|
||||||
std::string printlable;
|
std::string printlable;
|
||||||
|
@ -233,8 +213,8 @@ public:
|
||||||
std::vector<uint8_t> outbytes;
|
std::vector<uint8_t> outbytes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MerlinLine();
|
MerlinLine(ConfigOptions &opt);
|
||||||
MerlinLine(std::string line);
|
MerlinLine(std::string line, ConfigOptions &opt);
|
||||||
void clear();
|
void clear();
|
||||||
void set(std::string line);
|
void set(std::string line);
|
||||||
void print(uint32_t lineno);
|
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
|
uint32_t filecount; // how many files have been read in (because of included files from source
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
ConfigOptions &options;
|
||||||
uint32_t errorct;
|
uint32_t errorct;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
uint32_t format_flags;
|
uint32_t format_flags;
|
||||||
|
|
||||||
TFileProcessor();
|
TFileProcessor(ConfigOptions &opt);
|
||||||
virtual ~TFileProcessor();
|
virtual ~TFileProcessor();
|
||||||
virtual std::string processFilename(std::string p, std::string currentdir, int level);
|
virtual std::string processFilename(std::string p, std::string currentdir, int level);
|
||||||
virtual int processfile(std::string p, std::string &newfilename);
|
virtual int processfile(std::string p, std::string &newfilename);
|
||||||
|
@ -268,7 +249,7 @@ public:
|
||||||
virtual void process(void);
|
virtual void process(void);
|
||||||
virtual void complete(void);
|
virtual void complete(void);
|
||||||
virtual void errorOut(uint16_t code);
|
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_CRLF 0x02
|
||||||
#define CONVERT_COMPRESS 0x04
|
#define CONVERT_COMPRESS 0x04
|
||||||
#define CONVERT_HIGH 0x08
|
#define CONVERT_HIGH 0x08
|
||||||
|
#define CONVERT_TABS 0x10
|
||||||
#define CONVERT_MERLIN (CONVERT_HIGH|CONVERT_COMPRESS)
|
#define CONVERT_MERLIN (CONVERT_HIGH|CONVERT_COMPRESS)
|
||||||
#define CONVERT_LINUX (CONVERT_LF)
|
#define CONVERT_LINUX (CONVERT_LF)
|
||||||
#define CONVERT_WINDOWS (CONVERT_CRLF)
|
#define CONVERT_WINDOWS (CONVERT_CRLF)
|
||||||
|
@ -284,19 +266,22 @@ public:
|
||||||
#define CONVERT_MPW (CONVERT_NONE)
|
#define CONVERT_MPW (CONVERT_NONE)
|
||||||
#define CONVERT_TEST (CONVERT_COMPRESS|CONVERT_LF)
|
#define CONVERT_TEST (CONVERT_COMPRESS|CONVERT_LF)
|
||||||
|
|
||||||
|
|
||||||
|
#if 1
|
||||||
class TMerlinConverter : public TFileProcessor
|
class TMerlinConverter : public TFileProcessor
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
std::vector<MerlinLine> lines;
|
std::vector<MerlinLine> lines;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TMerlinConverter();
|
TMerlinConverter(ConfigOptions &opt);
|
||||||
virtual ~TMerlinConverter();
|
virtual ~TMerlinConverter();
|
||||||
virtual void init(void);
|
virtual void init(void);
|
||||||
virtual int doline(int lineno, std::string line);
|
virtual int doline(int lineno, std::string line);
|
||||||
virtual void process(void);
|
virtual void process(void);
|
||||||
virtual void complete(void);
|
virtual void complete(void);
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
class TLUPstruct
|
class TLUPstruct
|
||||||
{
|
{
|
||||||
|
@ -466,7 +451,7 @@ public:
|
||||||
|
|
||||||
uint16_t pass;
|
uint16_t pass;
|
||||||
|
|
||||||
T65816Asm();
|
T65816Asm(ConfigOptions &opt);
|
||||||
virtual ~T65816Asm();
|
virtual ~T65816Asm();
|
||||||
|
|
||||||
virtual void init(void);
|
virtual void init(void);
|
||||||
|
@ -527,7 +512,7 @@ public:
|
||||||
class T65816Link : public TFileProcessor
|
class T65816Link : public TFileProcessor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
T65816Link();
|
T65816Link(ConfigOptions &opt);
|
||||||
virtual ~T65816Link();
|
virtual ~T65816Link();
|
||||||
virtual void init(void);
|
virtual void init(void);
|
||||||
virtual int doline(int lineno, std::string line);
|
virtual int doline(int lineno, std::string line);
|
||||||
|
|
2
cider.h
2
cider.h
|
@ -17,7 +17,7 @@ class CLASS : public TFileProcessor
|
||||||
protected:
|
protected:
|
||||||
std::vector<MerlinLine> lines;
|
std::vector<MerlinLine> lines;
|
||||||
public:
|
public:
|
||||||
CLASS();
|
CLASS(ConfigOptions &opt);
|
||||||
virtual ~CLASS();
|
virtual ~CLASS();
|
||||||
int CreateVolume(string OSName, string VolName, uint64_t size, CIDER_VOLFORMAT format);
|
int CreateVolume(string OSName, string VolName, uint64_t size, CIDER_VOLFORMAT format);
|
||||||
int RunScript(string path);
|
int RunScript(string path);
|
||||||
|
|
2
config.h
2
config.h
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
#define NO_TTY_SETUP
|
#define NO_TTY_SETUP
|
||||||
// help text
|
// 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"
|
#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);
|
setOpcode(line, op);
|
||||||
// these bytes are the two bank registers
|
// 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
|
// merlin32 uses the low byte of the two operands
|
||||||
line.outbytes.push_back((v) & 0xFF);
|
line.outbytes.push_back((v) & 0xFF);
|
||||||
|
|
10
parms.json
10
parms.json
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"version": "1.1",
|
"version": "1.1",
|
||||||
"general": {
|
"general": {
|
||||||
"color_output": true,
|
"nocolor": false,
|
||||||
"prefix": [
|
"prefix": [
|
||||||
{
|
{
|
||||||
"0": "${PWD}"
|
"0": "${PWD}"
|
||||||
|
@ -18,12 +18,12 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"asm": {
|
"asm": {
|
||||||
"syntax": "merlin16plus", //merlin8, merlin16, merlin16plus,merlin32
|
"syntax": "merlin16plus",
|
||||||
"cpu": "M6502",
|
"cpu": "M6502",
|
||||||
"startmx": 3,
|
"startmx": 3,
|
||||||
"listmode": "on",
|
"listmode": "on",
|
||||||
"casesend": true,
|
"casesen": true,
|
||||||
"lst": false,
|
"start_lst": false,
|
||||||
"showmx": true,
|
"showmx": true,
|
||||||
"allowduplicate": true,
|
"allowduplicate": true,
|
||||||
"trackrep": false,
|
"trackrep": false,
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
"allowA": true,
|
"allowA": true,
|
||||||
"allowLocal": true,
|
"allowLocal": true,
|
||||||
"allowColon": true,
|
"allowColon": true,
|
||||||
"repsep": "force", //force,no,cfg
|
"repsep": "force",
|
||||||
"linebytes": 4,
|
"linebytes": 4,
|
||||||
"line2bytes": 8
|
"line2bytes": 8
|
||||||
},
|
},
|
||||||
|
|
406
psuedo.cpp
406
psuedo.cpp
|
@ -179,31 +179,32 @@ int CLASS::doMAC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
||||||
}
|
}
|
||||||
else // it is EOM or <<<
|
else // it is EOM or <<<
|
||||||
{
|
{
|
||||||
while (a.macrostack.size() > 0)
|
if (a.macrostack.size()>0)
|
||||||
{
|
{
|
||||||
a.currentmacro.end = line.lineno - 1;
|
while (a.macrostack.size() > 0)
|
||||||
a.currentmacro.len = 0;
|
|
||||||
if (a.currentmacro.end >= a.currentmacro.start)
|
|
||||||
{
|
{
|
||||||
a.currentmacro.len = a.currentmacro.end - a.currentmacro.start;
|
a.currentmacro.end = line.lineno - 1;
|
||||||
//printf("macro len=%d\n",a.currentmacro.len);
|
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
|
else
|
||||||
{
|
{
|
||||||
err = errUnexpectedOp;
|
err = errUnexpectedOp;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -351,27 +352,27 @@ int CLASS::doDATA(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
||||||
const char *ptr = (const char *)op.c_str();
|
const char *ptr = (const char *)op.c_str();
|
||||||
switch (strhash(ptr) )
|
switch (strhash(ptr) )
|
||||||
{
|
{
|
||||||
case strhash((const char *)"DA"):
|
case strhash((const char *)"DA"):
|
||||||
case strhash((const char *)"DW"):
|
case strhash((const char *)"DW"):
|
||||||
wordsize = 2;
|
wordsize = 2;
|
||||||
break;
|
break;
|
||||||
case strhash((const char *)"DDB"):
|
case strhash((const char *)"DDB"):
|
||||||
wordsize = 2;
|
wordsize = 2;
|
||||||
endian = 1;
|
endian = 1;
|
||||||
break;
|
break;
|
||||||
case strhash((const char *)"DFB"):
|
case strhash((const char *)"DFB"):
|
||||||
case strhash((const char *)"DB"):
|
case strhash((const char *)"DB"):
|
||||||
wordsize = 1;
|
wordsize = 1;
|
||||||
break;
|
break;
|
||||||
case strhash((const char *)"ADR"):
|
case strhash((const char *)"ADR"):
|
||||||
wordsize = 3;
|
wordsize = 3;
|
||||||
break;
|
break;
|
||||||
case strhash((const char *)"ADRL"):
|
case strhash((const char *)"ADRL"):
|
||||||
wordsize = 4;
|
wordsize = 4;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
wordsize = 0;
|
wordsize = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto itr = tok.begin(); itr != tok.end(); ++itr)
|
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
|
// Got a good char, append to hex string and see if we've got a byte
|
||||||
switch (ct)
|
switch (ct)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
b = (hv << 4);
|
b = (hv << 4);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
b |= hv;
|
b |= hv;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ct = (ct + 1) & 0x01;
|
ct = (ct + 1) & 0x01;
|
||||||
if (!ct)
|
if (!ct)
|
||||||
|
@ -695,7 +696,8 @@ out:
|
||||||
return bytect;
|
return bytect;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usr_hash(std::string os) {
|
static int usr_hash(std::string os)
|
||||||
|
{
|
||||||
int hash = 0;
|
int hash = 0;
|
||||||
|
|
||||||
os.resize(4, ' ');
|
os.resize(4, ' ');
|
||||||
|
@ -704,7 +706,10 @@ static int usr_hash(std::string os) {
|
||||||
hash = (os[0] & 0x1f) << 11;
|
hash = (os[0] & 0x1f) << 11;
|
||||||
hash |= (os[1] & 0x1f) << 6;
|
hash |= (os[1] & 0x1f) << 6;
|
||||||
hash |= (os[2] & 0x1f) << 1;
|
hash |= (os[2] & 0x1f) << 1;
|
||||||
if (os[3] == 'L') hash |= 0x01;
|
if (os[3] == 'L')
|
||||||
|
{
|
||||||
|
hash |= 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -727,34 +732,43 @@ int CLASS::doUSR(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
||||||
|
|
||||||
char c = os.empty() ? 0 : os.front();
|
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)
|
for (uint32_t i = 1; i < os.length(); ++i)
|
||||||
{
|
{
|
||||||
char hv = hexVal(os[i]);
|
char hv = hexVal(os[i]);
|
||||||
if (hv < 0) {
|
if (hv < 0)
|
||||||
|
{
|
||||||
line.setError(errIllegalCharOperand);
|
line.setError(errIllegalCharOperand);
|
||||||
bytect = 0;
|
bytect = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
hash <<= 4;
|
hash <<= 4;
|
||||||
hash |= hv;
|
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));
|
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);
|
hash = usr_hash(os);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
printf("line.setError(errBadOperand);\n");
|
printf("line.setError(errBadOperand);\n");
|
||||||
line.setError(errBadOperand);
|
line.setError(errBadOperand);
|
||||||
bytect = 0;
|
bytect = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a.pass > 0) {
|
if (a.pass > 0)
|
||||||
line.outbytes.push_back(hash & 0xff);
|
{
|
||||||
line.outbytes.push_back(hash >> 8);
|
line.outbytes.push_back(hash & 0xff);
|
||||||
|
line.outbytes.push_back(hash >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -778,7 +792,7 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
||||||
uint8_t ct = 0;
|
uint8_t ct = 0;
|
||||||
uint8_t delimiter = 0;
|
uint8_t delimiter = 0;
|
||||||
uint32_t ss = 0;
|
uint32_t ss = 0;
|
||||||
uint32_t lastdelimidx = 0;
|
uint32_t lastdelimidx = 0;
|
||||||
|
|
||||||
std::vector<uint8_t> bytes;
|
std::vector<uint8_t> bytes;
|
||||||
|
|
||||||
|
@ -809,7 +823,7 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes.push_back(c);
|
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
|
// Got a hex char, append to hex string and see if we've got a byte
|
||||||
switch (ct)
|
switch (ct)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
b = (hv << 4);
|
b = (hv << 4);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
b |= hv;
|
b |= hv;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ct = (ct + 1) & 0x01;
|
ct = (ct + 1) & 0x01;
|
||||||
if (!ct)
|
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());
|
//printf("bytect=%d bytes.size()=%zu\n",bytect,bytes.size());
|
||||||
switch (strhash(ptr) )
|
switch (strhash(ptr) )
|
||||||
{
|
{
|
||||||
case strhash((const char *)"STRL"):
|
case strhash((const char *)"STRL"):
|
||||||
addlen = 2;
|
addlen = 2;
|
||||||
break;
|
break;
|
||||||
case strhash((const char *)"STR"):
|
case strhash((const char *)"STR"):
|
||||||
addlen = 1;
|
addlen = 1;
|
||||||
break;
|
break;
|
||||||
case strhash((const char *)"REV"):
|
case strhash((const char *)"REV"):
|
||||||
reverse = true;
|
reverse = true;
|
||||||
break;
|
break;
|
||||||
case strhash((const char *)"FLS"):
|
case strhash((const char *)"FLS"):
|
||||||
andval = (uint8_t)~0xC0;
|
andval = (uint8_t)~0xC0;
|
||||||
orval = (uint8_t)0x40;
|
orval = (uint8_t)0x40;
|
||||||
break;
|
break;
|
||||||
case strhash((const char *)"INV"):
|
case strhash((const char *)"INV"):
|
||||||
andval = (uint8_t)~0xC0;
|
andval = (uint8_t)~0xC0;
|
||||||
orval = 0x00;
|
orval = 0x00;
|
||||||
break;
|
break;
|
||||||
case strhash((const char *)"DCI"):
|
case strhash((const char *)"DCI"):
|
||||||
dci = true;
|
dci = true;
|
||||||
break;
|
break;
|
||||||
case strhash((const char *)"ASC"):
|
case strhash((const char *)"ASC"):
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
line.setError(errBadOpcode);
|
line.setError(errBadOpcode);
|
||||||
bytect = 0;
|
bytect = 0;
|
||||||
addlen = 0;
|
addlen = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (a.pass > 0)
|
if (a.pass > 0)
|
||||||
{
|
{
|
||||||
|
@ -930,7 +944,7 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
||||||
b = bytes[i];
|
b = bytes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
b1 = b & 0x7F;
|
b1 = b & 0x7F;
|
||||||
if ((andval != 0xFF) || (orval != 0x00))
|
if ((andval != 0xFF) || (orval != 0x00))
|
||||||
{
|
{
|
||||||
b = b1;
|
b = b1;
|
||||||
|
@ -947,17 +961,17 @@ int CLASS::doASC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
||||||
// SGQ BUG - Merlin16+ does it like Merlin32 and now does the last
|
// SGQ BUG - Merlin16+ does it like Merlin32 and now does the last
|
||||||
// byte not the way merlin816 and earlier do it documented below.
|
// byte not the way merlin816 and earlier do it documented below.
|
||||||
// use OPTION_M16_PLUS when implemented.
|
// use OPTION_M16_PLUS when implemented.
|
||||||
|
|
||||||
//lr - Merlin only toggles the high bit of string chars, not hex values
|
//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
|
// 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
|
// The DCI instruction is documented to work like this on page 108
|
||||||
// (regardless of how this effects the desired lda, (bpl/bmi) functionality)
|
// (regardless of how this effects the desired lda, (bpl/bmi) functionality)
|
||||||
//
|
//
|
||||||
// I am now checking the delimiter character to determine hi/lo toggle (reversed)
|
// 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'.
|
// and am tracking the index to the last delimited character put into 'bytes'.
|
||||||
// This produces the same results as Merlin 16+ in my testing.
|
// This produces the same results as Merlin 16+ in my testing.
|
||||||
if ( firstdelim >= '\'' )
|
if ( firstdelim >= '\'' )
|
||||||
{
|
{
|
||||||
b |= 0x80;
|
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 CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
std::string s;
|
std::string s,sp;
|
||||||
|
|
||||||
switch (opinfo.opcode)
|
switch (opinfo.opcode)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
res = -1; // undefined p-op
|
res = -1; // undefined p-op
|
||||||
line.setError(errUnimplemented);
|
line.setError(errUnimplemented);
|
||||||
break;
|
break;
|
||||||
case P_DS:
|
case P_DS:
|
||||||
res = doDS(a, line, opinfo);
|
res = doDS(a, line, opinfo);
|
||||||
break;
|
break;
|
||||||
case P_PUT:
|
case P_PUT:
|
||||||
case P_USE:
|
case P_USE:
|
||||||
// both of these are handled by the input file processor, just allow them to be
|
// both of these are handled by the input file processor, just allow them to be
|
||||||
// processed with no errors here
|
// processed with no errors here
|
||||||
break;
|
break;
|
||||||
case P_DUM:
|
case P_DUM:
|
||||||
case P_DEND:
|
case P_DEND:
|
||||||
res = doDUM(a, line, opinfo);
|
res = doDUM(a, line, opinfo);
|
||||||
line.flags |= FLAG_FORCEADDRPRINT;
|
line.flags |= FLAG_FORCEADDRPRINT;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case P_ORG:
|
case P_ORG:
|
||||||
if (line.operand_expr.length() > 0)
|
if (line.operand_expr.length() > 0)
|
||||||
{
|
{
|
||||||
a.PC.orgsave = a.PC.currentpc;
|
a.PC.orgsave = a.PC.currentpc;
|
||||||
a.PC.currentpc = line.expr_value;
|
a.PC.currentpc = line.expr_value;
|
||||||
line.startpc = line.expr_value;
|
line.startpc = line.expr_value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
a.PC.currentpc = a.PC.orgsave;
|
a.PC.currentpc = a.PC.orgsave;
|
||||||
line.startpc = a.PC.orgsave;
|
line.startpc = a.PC.orgsave;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Merlin32 seems to have a bug where ORG seems like it can only be 16 bits
|
// Merlin32 seems to have a bug where ORG seems like it can only be 16 bits
|
||||||
if ((line.syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32)
|
if ((line.syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32)
|
||||||
{
|
{
|
||||||
// so clear the bank word in all variables
|
// so clear the bank word in all variables
|
||||||
a.PC.orgsave &= 0xFFFF;
|
a.PC.orgsave &= 0xFFFF;
|
||||||
a.PC.currentpc &= 0xFFFF;
|
a.PC.currentpc &= 0xFFFF;
|
||||||
line.startpc &= 0xFFFF;
|
line.startpc &= 0xFFFF;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
line.flags |= FLAG_FORCEADDRPRINT;
|
line.flags |= FLAG_FORCEADDRPRINT;
|
||||||
break;
|
break;
|
||||||
case P_SAV:
|
case P_SAV:
|
||||||
|
sp = getConfig("option.objfile", "");
|
||||||
|
if (sp=="")
|
||||||
|
{
|
||||||
a.savepath = a.processFilename(line.operand, Poco::Path::current(), 0);
|
a.savepath = a.processFilename(line.operand, Poco::Path::current(), 0);
|
||||||
break;
|
}
|
||||||
case P_CAS:
|
else // if they specified an output name on the command line, use it.
|
||||||
s = Poco::toUpper(line.operand);
|
{
|
||||||
if (s == "SE")
|
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")
|
}
|
||||||
{
|
res = 0;
|
||||||
a.casesen=false;
|
break;
|
||||||
}
|
case P_LST:
|
||||||
res = 0;
|
res = doLST(a, line, opinfo);
|
||||||
break;
|
break;
|
||||||
case P_MAC:
|
case P_HEX:
|
||||||
res = doMAC(a, line, opinfo);
|
res = doHEX(a, line, opinfo);
|
||||||
break;
|
break;
|
||||||
case P_ERR:
|
case P_DATA:
|
||||||
if (a.pass > 0)
|
res = doDATA(a, line, opinfo);
|
||||||
{
|
break;
|
||||||
if ((line.expr_value != 0) || (line.eval_result < 0))
|
case P_LUP:
|
||||||
{
|
res = doLUP(a, line, opinfo);
|
||||||
line.setError(errErrOpcode);
|
break;
|
||||||
//a.passcomplete=true; // terminate assembly
|
case P_DO:
|
||||||
}
|
res = doDO(a, line, opinfo);
|
||||||
}
|
break;
|
||||||
res = 0;
|
case P_TR:
|
||||||
break;
|
res = doTR(a, line, opinfo);
|
||||||
case P_LST:
|
break;
|
||||||
res = doLST(a, line, opinfo);
|
case P_ASC:
|
||||||
break;
|
res = doASC(a, line, opinfo);
|
||||||
case P_HEX:
|
break;
|
||||||
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:
|
case P_USR:
|
||||||
res = doUSR(a, line, opinfo);
|
res = doUSR(a, line, opinfo);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
return (res);
|
return (res);
|
||||||
|
|
88
qasm.cpp
88
qasm.cpp
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#define CLASS PAL_APPCLASS
|
#define CLASS PAL_APPCLASS
|
||||||
|
|
||||||
|
|
||||||
// return a pointer to the actual Application class
|
// return a pointer to the actual Application class
|
||||||
PAL_BASEAPP *PAL::appFactory(void)
|
PAL_BASEAPP *PAL::appFactory(void)
|
||||||
{
|
{
|
||||||
|
@ -21,8 +20,16 @@ programOption PAL::appOptions[] =
|
||||||
#endif
|
#endif
|
||||||
//{ "config", "f", "load configuration data from a <file>", "<file>", false, false},
|
//{ "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},
|
{ "exec", "x", "execute a command [asm, link, format, script] default=asm", "<command>", false, false},
|
||||||
{ "objfile", "o", "write output to file", "<file>", false, false},
|
{ "objfile", "o", "write output to <objfile>", "<objfile>", false, false},
|
||||||
{ "syntax", "s", "enforce syntax of other assembler [qasm, merlin, merlin32, ORCA, APW, MPW, CC65]", "<syntax>", 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}
|
{ "", "", "", "", false, false}
|
||||||
|
@ -75,62 +82,49 @@ int CLASS::runCommandLineApp(void)
|
||||||
TFileProcessor *t = NULL;
|
TFileProcessor *t = NULL;
|
||||||
std::string line;
|
std::string line;
|
||||||
std::string startdirectory;
|
std::string startdirectory;
|
||||||
|
std::string appPath;
|
||||||
std::string fname;
|
std::string fname;
|
||||||
uint32_t syntax;
|
//uint32_t syntax;
|
||||||
|
string product="";
|
||||||
|
string syn;
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
ConfigOptions options;
|
||||||
|
|
||||||
|
//Poco::Util::Application::instance().config()
|
||||||
|
|
||||||
|
utils=new QUtils();
|
||||||
|
|
||||||
|
//LOG_NOTE << "this is it!" << endl;
|
||||||
|
|
||||||
startdirectory = Poco::Path::current();
|
startdirectory = Poco::Path::current();
|
||||||
|
appPath=utils->getAppPath();
|
||||||
if (commandargs.size() == 0)
|
if (commandargs.size() == 0)
|
||||||
{
|
{
|
||||||
displayHelp();
|
displayHelp();
|
||||||
return (res);
|
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!="")
|
if (cmdsyn!="")
|
||||||
{
|
{
|
||||||
syn=cmdsyn; // if they overrode the syntax on the command line, use it
|
syn=cmdsyn; // if they overrode the syntax on the command line, use it
|
||||||
}
|
}
|
||||||
|
|
||||||
syn=Poco::toUpper(syn);
|
syn=Poco::toUpper(syn);
|
||||||
syn=Poco::trim(syn);
|
product=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;
|
|
||||||
}
|
|
||||||
|
|
||||||
//printf("SYNTAX: |%s|\n",syn.c_str());
|
if (isDebug()>0)
|
||||||
|
{
|
||||||
|
printf("SYNTAX: |%s|\n",syn.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -196,7 +190,7 @@ int CLASS::runCommandLineApp(void)
|
||||||
{
|
{
|
||||||
format_flags=CONVERT_TEST;
|
format_flags=CONVERT_TEST;
|
||||||
}
|
}
|
||||||
|
options.format_flags=format_flags;
|
||||||
cmd=toks[0];
|
cmd=toks[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,13 +199,14 @@ int CLASS::runCommandLineApp(void)
|
||||||
if (cmd == "FORMAT")
|
if (cmd == "FORMAT")
|
||||||
{
|
{
|
||||||
res = 0;
|
res = 0;
|
||||||
t = new TMerlinConverter();
|
t = new TMerlinConverter(options);
|
||||||
|
//t=NULL;
|
||||||
if (t != NULL)
|
if (t != NULL)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
t->init();
|
t->init();
|
||||||
t->setSyntax(syntax);
|
t->setProduct(product);
|
||||||
t->format_flags=format_flags;
|
t->format_flags=format_flags;
|
||||||
|
|
||||||
std::string f = path.toString();
|
std::string f = path.toString();
|
||||||
|
@ -239,13 +234,14 @@ int CLASS::runCommandLineApp(void)
|
||||||
else if (cmd == "ASM")
|
else if (cmd == "ASM")
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
t = new T65816Asm();
|
t = new T65816Asm(options);
|
||||||
if (t != NULL)
|
if (t != NULL)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
t->init();
|
t->init();
|
||||||
t->setSyntax(syntax);
|
t->setProduct(product);
|
||||||
|
|
||||||
|
|
||||||
std::string f = path.toString();
|
std::string f = path.toString();
|
||||||
t->filename = f;
|
t->filename = f;
|
||||||
|
@ -275,13 +271,13 @@ int CLASS::runCommandLineApp(void)
|
||||||
else if (cmd == "SCRIPT")
|
else if (cmd == "SCRIPT")
|
||||||
{
|
{
|
||||||
res = 0;
|
res = 0;
|
||||||
t = new CiderPress();
|
t = new CiderPress(options);
|
||||||
if (t!=NULL)
|
if (t!=NULL)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
t->init();
|
t->init();
|
||||||
t->setSyntax(syntax);
|
t->setProduct(product);
|
||||||
|
|
||||||
std::string f = path.toString();
|
std::string f = path.toString();
|
||||||
t->filename = f;
|
t->filename = f;
|
||||||
|
|
6
qasm.h
6
qasm.h
|
@ -5,6 +5,7 @@
|
||||||
#include <pallogger.h>
|
#include <pallogger.h>
|
||||||
#include <eventtask.h>
|
#include <eventtask.h>
|
||||||
#include <baseapp.h>
|
#include <baseapp.h>
|
||||||
|
#include "app.h"
|
||||||
#include "qoptions.h"
|
#include "qoptions.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
//#include <httpserver.h>
|
//#include <httpserver.h>
|
||||||
|
@ -27,7 +28,10 @@ protected:
|
||||||
virtual void displayVersion();
|
virtual void displayVersion();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QOptions options;
|
QOptions options;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern PAL_LOGGER logger;
|
||||||
|
|
||||||
#undef CLASS
|
#undef CLASS
|
||||||
|
|
|
@ -9,6 +9,7 @@ CLASS::CLASS()
|
||||||
jsonin="";
|
jsonin="";
|
||||||
jsonobj=NULL;
|
jsonobj=NULL;
|
||||||
parser.reset();
|
parser.reset();
|
||||||
|
parser.setAllowComments(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CLASS::ReadFile(string path)
|
int CLASS::ReadFile(string path)
|
||||||
|
@ -17,6 +18,8 @@ int CLASS::ReadFile(string path)
|
||||||
|
|
||||||
Poco::FileInputStream fs(path);
|
Poco::FileInputStream fs(path);
|
||||||
Poco::StreamCopier::copyToString(fs,jsonin);
|
Poco::StreamCopier::copyToString(fs,jsonin);
|
||||||
|
parser.reset();
|
||||||
|
parser.setAllowComments(true);
|
||||||
jsonobj=parser.parse(jsonin);
|
jsonobj=parser.parse(jsonin);
|
||||||
|
|
||||||
config.load(path);
|
config.load(path);
|
||||||
|
|
229
qoptions.h
229
qoptions.h
|
@ -1,12 +1,237 @@
|
||||||
#pragma once
|
#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
|
#define CLASS QOptions
|
||||||
|
|
||||||
class CLASS
|
class CLASS
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Poco::Util::JSONConfiguration config;
|
Poco::Util::JSONConfiguration config;
|
||||||
Poco::JSON::Parser parser;
|
Poco::JSON::Parser parser;
|
||||||
string jsonin;
|
string jsonin;
|
||||||
Dynamic::Var jsonobj=NULL;
|
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);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isMerlin816(void)
|
bool CLASS::isMerlin816(void)
|
||||||
{
|
{
|
||||||
return(true);
|
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
|
#pragma once
|
||||||
#include <app.h>
|
#include <palPoco.h>
|
||||||
|
|
||||||
bool isMerlin32(void);
|
class QUtils
|
||||||
bool isMerlin816(void);
|
{
|
||||||
|
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