mirror of
https://github.com/marketideas/qasm.git
synced 2024-06-02 08:41:27 +00:00
update to cmake system and error handling
This commit is contained in:
parent
0076a7dd68
commit
bded99e731
|
@ -12,16 +12,18 @@ set(SOURCE
|
|||
${PROJECT_ROOT}/asm.cpp
|
||||
${PROJECT_ROOT}/opcodes.cpp
|
||||
${PROJECT_ROOT}/eval.cpp
|
||||
${PROJECT_ROOT}/psuedo.cpp
|
||||
)
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
find_package(Poco REQUIRED Foundation Util XML JSON NetSSL)
|
||||
|
||||
include_directories(BEFORE
|
||||
${PROJECT_ROOT}
|
||||
${PROJECT_ROOT}/lib${LIBRARY_NAME}/include/${LIBRARY_NAME}
|
||||
${Poco_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
find_package(Poco REQUIRED NetSSL)
|
||||
|
||||
add_subdirectory(${PROJECT_ROOT}/lib${LIBRARY_NAME})
|
||||
|
||||
include(${PROJECT_ROOT}/lib${LIBRARY_NAME}/cmake/CMakeApp.txt)
|
||||
|
|
18
Makefile
18
Makefile
|
@ -1,5 +1,5 @@
|
|||
export CC=/usr/bin/clang
|
||||
export CXX=/usr/bin/clang++
|
||||
#export CC=/usr/bin/clang
|
||||
#export CXX=/usr/bin/clang++
|
||||
|
||||
|
||||
V?=
|
||||
|
@ -15,7 +15,7 @@ all:
|
|||
-cd ./build && cmake .. && $(MAKE) $S
|
||||
|
||||
distclean:
|
||||
rm -rf build app/build sgqlib/build
|
||||
rm -rf ./build
|
||||
|
||||
clean:
|
||||
-rm -rf ./build
|
||||
|
@ -26,18 +26,20 @@ depend:
|
|||
rebuild:
|
||||
-cd ./build && $(MAKE) rebuild_cache
|
||||
|
||||
lib:
|
||||
-cd ./build && $(MAKE) sgq
|
||||
|
||||
run:
|
||||
-cd ./build && $(MAKE) run
|
||||
|
||||
install:
|
||||
-cd ./build && cmake -P cmake_install.cmake
|
||||
|
||||
asm:
|
||||
reformat:
|
||||
qasm -r src/main.s
|
||||
|
||||
test1:
|
||||
qasm src/main.s
|
||||
#qasm src/testfile.s
|
||||
|
||||
test2:
|
||||
qasm src/testfile.s
|
||||
|
||||
|
||||
|
||||
|
|
271
asm.cpp
271
asm.cpp
|
@ -1,6 +1,7 @@
|
|||
#define ADD_ERROR_STRINGS
|
||||
#include "asm.h"
|
||||
#include "eval.h"
|
||||
#include "psuedo.h"
|
||||
|
||||
#define CLASS MerlinLine
|
||||
|
||||
|
@ -33,11 +34,6 @@ void CLASS::print(uint32_t lineno)
|
|||
l = 4;
|
||||
}
|
||||
|
||||
//if ((opflags&OP_STD)!=OP_STD)
|
||||
if ((opcodelower != "inc") && (opcodelower != "ldx") && (opcodelower != "stx"))
|
||||
{
|
||||
//return;
|
||||
}
|
||||
if (errorcode > 0)
|
||||
{
|
||||
if (errorcode >= errFatal)
|
||||
|
@ -54,7 +50,7 @@ void CLASS::print(uint32_t lineno)
|
|||
SetColor(CL_WHITE | CL_BOLD | BG_NORMAL);
|
||||
}
|
||||
bool empty = false;
|
||||
if ((lable == "") && (opcode == "") && (operand == ""))
|
||||
if ((printlable == "") && (opcode == "") && (operand == ""))
|
||||
{
|
||||
empty = true;
|
||||
}
|
||||
|
@ -80,7 +76,7 @@ void CLASS::print(uint32_t lineno)
|
|||
printf(" ");
|
||||
}
|
||||
|
||||
if ((getBool("asm.showmx", false)))
|
||||
if (showmx)
|
||||
{
|
||||
if (outbytect > 0)
|
||||
{
|
||||
|
@ -92,9 +88,9 @@ void CLASS::print(uint32_t lineno)
|
|||
}
|
||||
}
|
||||
|
||||
if (isDebug()>1)
|
||||
if (isDebug() > 1)
|
||||
{
|
||||
printf("%02X ", addressmode&0xFF);
|
||||
printf("%02X ", addressmode & 0xFF);
|
||||
}
|
||||
printf("%6d ", lineno + 1);
|
||||
|
||||
|
@ -104,10 +100,10 @@ void CLASS::print(uint32_t lineno)
|
|||
}
|
||||
else
|
||||
{
|
||||
printf("%-12s %-8s %-10s ", lable.c_str(), opcode.c_str(), operand.c_str());
|
||||
printf("%-12s %-8s %-10s ", printlable.c_str(), opcode.c_str(), operand.c_str());
|
||||
if (errorcode > 0)
|
||||
{
|
||||
printf(":[Error] %s %s", errStrings[errorcode].c_str(),errorText.c_str());
|
||||
printf(":[Error] %s %s", errStrings[errorcode].c_str(), errorText.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -126,6 +122,7 @@ void CLASS::clear()
|
|||
{
|
||||
syntax = SYNTAX_MERLIN;
|
||||
lable = "";
|
||||
printlable = "";
|
||||
opcode = "";
|
||||
opcodelower = "";
|
||||
operand = "";
|
||||
|
@ -154,6 +151,7 @@ void CLASS::set(std::string line)
|
|||
int state = 0;
|
||||
int l = line.length();
|
||||
int i = 0;
|
||||
int x;
|
||||
char c, delim;
|
||||
|
||||
clear();
|
||||
|
@ -278,6 +276,18 @@ void CLASS::set(std::string line)
|
|||
break;
|
||||
}
|
||||
}
|
||||
printlable = lable;
|
||||
x = lable.length();
|
||||
if (x > 1)
|
||||
{
|
||||
while ((x > 1) && (lable[x - 1] == ':'))
|
||||
{
|
||||
lable = lable.substr(0, x - 1);
|
||||
x--;
|
||||
}
|
||||
//printf("linelable: |%s|\n", lable.c_str());
|
||||
}
|
||||
|
||||
opcodelower = Poco::toLower(opcode);
|
||||
}
|
||||
|
||||
|
@ -286,6 +296,7 @@ void CLASS::set(std::string line)
|
|||
|
||||
CLASS::CLASS()
|
||||
{
|
||||
errorct = 0;
|
||||
}
|
||||
|
||||
CLASS::~CLASS()
|
||||
|
@ -427,18 +438,120 @@ int CLASS::processfile(std::string &p)
|
|||
}
|
||||
|
||||
#undef CLASS
|
||||
|
||||
#define CLASS T65816Asm
|
||||
|
||||
CLASS::CLASS()
|
||||
#define CLASS TMerlinConverter
|
||||
CLASS::CLASS() : TFileProcessor()
|
||||
{
|
||||
}
|
||||
CLASS::~CLASS()
|
||||
{
|
||||
}
|
||||
void CLASS::init(void)
|
||||
{
|
||||
std::string s;
|
||||
int ts,tabpos;
|
||||
lines.clear();
|
||||
|
||||
std::string tabstr=getConfig("reformat.tabs","8,16,32");
|
||||
tabstr=Poco::trim(tabstr);
|
||||
|
||||
memset(tabs, 0x00, sizeof(tabs));
|
||||
|
||||
Poco::StringTokenizer t(tabstr,",;",0);
|
||||
tabpos=0;
|
||||
for (auto itr=t.begin(); itr!=t.end(); ++itr)
|
||||
{
|
||||
s=Poco::trim(*itr);
|
||||
try
|
||||
{
|
||||
ts=Poco::NumberParser::parse(s);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
ts=0;
|
||||
}
|
||||
if ((ts>=0) && (ts<240))
|
||||
{
|
||||
tabs[tabpos++]=ts;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define OPHANDLER(ACB) std::bind(ACB, this, std::placeholders::_1, std::placeholders::_2)
|
||||
int CLASS::doline(int lineno, std::string line)
|
||||
{
|
||||
|
||||
MerlinLine l(line);
|
||||
lines.push_back(l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CLASS::process(void)
|
||||
{
|
||||
uint32_t len, t,pos;
|
||||
|
||||
uint32_t ct = lines.size();
|
||||
|
||||
for (uint32_t lineno = 0; lineno < ct; lineno++)
|
||||
{
|
||||
MerlinLine &line = lines[lineno];
|
||||
|
||||
pos=0;
|
||||
len = 0;
|
||||
|
||||
t = tabs[pos++];
|
||||
len = printf("%s ", line.printlable.c_str());
|
||||
while (len < t)
|
||||
{
|
||||
len += printf(" ");
|
||||
}
|
||||
|
||||
t = tabs[pos++];
|
||||
len = printf("%s ", line.opcode.c_str());
|
||||
while (len < t)
|
||||
{
|
||||
len += printf(" ");
|
||||
}
|
||||
|
||||
t = tabs[pos++];
|
||||
len = printf("%s ", line.operand.c_str());
|
||||
while (len < t)
|
||||
{
|
||||
len += printf(" ");
|
||||
}
|
||||
|
||||
t = tabs[pos++];
|
||||
len = printf("%s", line.comment.c_str());
|
||||
while (len < t)
|
||||
{
|
||||
len += printf(" ");
|
||||
}
|
||||
len+=printf("\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void CLASS::complete(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#undef CLASS
|
||||
#define CLASS T65816Asm
|
||||
|
||||
CLASS::CLASS() : TFileProcessor()
|
||||
{
|
||||
lines.clear();
|
||||
psuedoops = new TPsuedoOp();
|
||||
}
|
||||
|
||||
//#define OPHANDLER(ACB) std::bind(ACB, this, std::placeholders::_1, std::placeholders::_2)
|
||||
|
||||
CLASS::~CLASS()
|
||||
{
|
||||
if (psuedoops != NULL)
|
||||
{
|
||||
delete(psuedoops);
|
||||
psuedoops = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CLASS::pushopcode(std::string op, uint8_t opcode, uint16_t flags, TOpCallback cb)
|
||||
|
@ -456,23 +569,6 @@ void CLASS::pushopcode(std::string op, uint8_t opcode, uint16_t flags, TOpCallba
|
|||
opcodes.insert(p);
|
||||
}
|
||||
|
||||
|
||||
TSymbol *CLASS::findSymbol(std::string symname)
|
||||
{
|
||||
TSymbol *res = NULL;
|
||||
|
||||
//printf("finding: %s\n",symname.c_str());
|
||||
auto itr = symbols.find(Poco::toUpper(symname));
|
||||
if (itr != symbols.end())
|
||||
{
|
||||
//printf("Found: %s 0x%08X\n",itr->second.name.c_str(),itr->second.value);
|
||||
res = &itr->second;
|
||||
|
||||
return (res);
|
||||
}
|
||||
return (res);
|
||||
}
|
||||
|
||||
TSymbol *CLASS::addSymbol(std::string sym, uint32_t val, bool replace)
|
||||
{
|
||||
TSymbol *res = NULL;
|
||||
|
@ -492,6 +588,7 @@ TSymbol *CLASS::addSymbol(std::string sym, uint32_t val, bool replace)
|
|||
return (fnd);
|
||||
}
|
||||
|
||||
//printf("addSymbol |%s|\n",sym.c_str());
|
||||
TSymbol s;
|
||||
s.name = sym;
|
||||
s.opcode = 0;
|
||||
|
@ -506,6 +603,85 @@ TSymbol *CLASS::addSymbol(std::string sym, uint32_t val, bool replace)
|
|||
return (res);
|
||||
}
|
||||
|
||||
TSymbol *CLASS::findSymbol(std::string symname)
|
||||
{
|
||||
TSymbol *res = NULL;
|
||||
|
||||
//printf("finding: %s\n",symname.c_str());
|
||||
auto itr = symbols.find(Poco::toUpper(symname));
|
||||
if (itr != symbols.end())
|
||||
{
|
||||
//printf("Found: %s 0x%08X\n",itr->second.name.c_str(),itr->second.value);
|
||||
res = &itr->second;
|
||||
|
||||
return (res);
|
||||
}
|
||||
return (res);
|
||||
}
|
||||
|
||||
TSymbol *CLASS::addVariable(std::string sym, std::string val, bool replace)
|
||||
{
|
||||
TSymbol *res = NULL;
|
||||
TSymbol *fnd = NULL;
|
||||
|
||||
//printf("addvariable\n");
|
||||
fnd = findVariable(sym);
|
||||
|
||||
if ((fnd != NULL) && (!replace))
|
||||
{
|
||||
return (NULL); // it is a duplicate
|
||||
}
|
||||
|
||||
if (fnd != NULL)
|
||||
{
|
||||
//printf("replacing symbol: %s %08X\n",sym.c_str(),val);
|
||||
fnd->text = val;
|
||||
return (fnd);
|
||||
}
|
||||
|
||||
TSymbol s;
|
||||
s.name = sym;
|
||||
s.opcode = 0;
|
||||
s.namelc = Poco::toLower(sym);
|
||||
s.stype = 0;
|
||||
s.value = 0;
|
||||
s.text = val;
|
||||
s.used = false;
|
||||
s.cb = NULL;
|
||||
std::pair<std::string, TSymbol> p(Poco::toUpper(sym), s);
|
||||
variables.insert(p);
|
||||
res = findVariable(sym);
|
||||
return (res);
|
||||
}
|
||||
|
||||
TSymbol *CLASS::findVariable(std::string symname)
|
||||
{
|
||||
TSymbol *res = NULL;
|
||||
|
||||
//printf("finding: %s\n",symname.c_str());
|
||||
auto itr = variables.find(Poco::toUpper(symname));
|
||||
if (itr != variables.end())
|
||||
{
|
||||
//printf("Found: %s 0x%08X\n",itr->second.name.c_str(),itr->second.value);
|
||||
res = &itr->second;
|
||||
|
||||
return (res);
|
||||
}
|
||||
return (res);
|
||||
}
|
||||
|
||||
void CLASS::showVariables(void)
|
||||
{
|
||||
|
||||
printf("\nVariables:\n");
|
||||
|
||||
for (auto itr = variables.begin(); itr != variables.end(); ++itr)
|
||||
{
|
||||
printf("%-16s %s\n", itr->first.c_str(), itr->second.text.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// set alpha to true to print table sorted by name or
|
||||
// false to print by value;
|
||||
void CLASS::showSymbolTable(bool alpha)
|
||||
|
@ -618,7 +794,7 @@ const TaddrMode addrRegEx[] =
|
|||
{"", 0, ""}
|
||||
};
|
||||
|
||||
const std::string valExpression = "^([$%:-~][^\\],()]*)$";
|
||||
const std::string valExpression = "^([$%\\+\\-:-~][^\\],()]*)$";
|
||||
|
||||
// opcode check. emitted opcodes are compared against this
|
||||
// table, and if the XC status doesn't meet the requirements
|
||||
|
@ -666,6 +842,10 @@ void CLASS::initpass(void)
|
|||
|
||||
casesen = getBool("asm.casesen", true);
|
||||
listing = getBool("asm.lst", true);
|
||||
showmx = getBool("asm.showmx", false);
|
||||
trackrep = getBool("asm.trackrep", false);
|
||||
|
||||
|
||||
skiplist = false;
|
||||
|
||||
origin = 0x8000;
|
||||
|
@ -703,6 +883,7 @@ void CLASS::initpass(void)
|
|||
errorct = 0;
|
||||
passcomplete = false;
|
||||
|
||||
variables.clear(); // clear the variables for each pass
|
||||
savepath = "";
|
||||
}
|
||||
|
||||
|
@ -741,6 +922,7 @@ void CLASS::complete(void)
|
|||
{
|
||||
showSymbolTable(true);
|
||||
showSymbolTable(false);
|
||||
showVariables();
|
||||
}
|
||||
TFileProcessor::complete();
|
||||
}
|
||||
|
@ -758,7 +940,7 @@ int CLASS::evaluate(std::string expr, int64_t &value)
|
|||
res = eval.evaluate(expr, result);
|
||||
if (res != 0)
|
||||
{
|
||||
if (isDebug()>2)
|
||||
if (isDebug() > 2)
|
||||
{
|
||||
int c = SetColor(CL_RED);
|
||||
printf("eval Error=%d %08lX |%s|\n", res, result, eval.badsymbol.c_str());
|
||||
|
@ -919,20 +1101,31 @@ void CLASS::process(void)
|
|||
line->startpc = currentpc;
|
||||
line->linemx = mx;
|
||||
line->bytect = 0;
|
||||
line->showmx = showmx;
|
||||
|
||||
if ((line->lable != "") && (pass == 0))
|
||||
{
|
||||
std::string lable = Poco::trim(line->lable);
|
||||
TSymbol *sym = NULL;
|
||||
bool dupsym = false;
|
||||
c = line->lable[0];
|
||||
switch (c)
|
||||
{
|
||||
case ']':
|
||||
sym = addVariable(line->lable, "", true);
|
||||
if (sym == NULL) { dupsym = true; }
|
||||
break;
|
||||
case ':':
|
||||
break;
|
||||
default:
|
||||
addSymbol(line->lable, currentpc, false);
|
||||
sym = addSymbol(line->lable, currentpc, false);
|
||||
if (sym == NULL) { dupsym = true; }
|
||||
break;
|
||||
}
|
||||
if (dupsym)
|
||||
{
|
||||
line->setError(errDupSymbol);
|
||||
}
|
||||
}
|
||||
x = parseOperand(*line);
|
||||
if (x >= 0)
|
||||
|
@ -962,10 +1155,10 @@ void CLASS::process(void)
|
|||
|
||||
if (x > 0)
|
||||
{
|
||||
if (evalresult != 0)
|
||||
if ((evalresult != 0) && (pass > 0))
|
||||
{
|
||||
line->setError(errBadOperand);
|
||||
line->errorText=line->operand_expr;
|
||||
line->errorText = line->operand_expr;
|
||||
}
|
||||
line->bytect = x;
|
||||
currentpc += x;
|
||||
|
@ -1033,7 +1226,7 @@ int CLASS::doline(int lineno, std::string line)
|
|||
|
||||
#define CLASS T65816Link
|
||||
|
||||
CLASS::CLASS()
|
||||
CLASS::CLASS() : TFileProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
64
asm.h
64
asm.h
|
@ -41,11 +41,13 @@ enum asmErrors
|
|||
errForwardReference,
|
||||
errNoRedefinition,
|
||||
errBadOperand,
|
||||
errDupSymbol,
|
||||
errMAX
|
||||
};
|
||||
|
||||
#ifdef ADD_ERROR_STRINGS
|
||||
const std::string errStrings[errMAX+1] = {
|
||||
const std::string errStrings[errMAX + 1] =
|
||||
{
|
||||
"No Error",
|
||||
"Warning",
|
||||
"Unfinished Opcode",
|
||||
|
@ -59,6 +61,7 @@ const std::string errStrings[errMAX+1] = {
|
|||
"Forward Reference to symbol",
|
||||
"Unable to redefine symbol",
|
||||
"Unable to evaluate",
|
||||
"Duplicate Symbol",
|
||||
|
||||
""
|
||||
};
|
||||
|
@ -97,6 +100,7 @@ public:
|
|||
|
||||
uint8_t syntax;
|
||||
std::string lable;
|
||||
std::string printlable;
|
||||
std::string opcode;
|
||||
std::string opcodelower;
|
||||
std::string operand;
|
||||
|
@ -105,6 +109,7 @@ public:
|
|||
std::string comment;
|
||||
std::string addrtext;
|
||||
uint8_t linemx;
|
||||
bool showmx;
|
||||
uint32_t lineno;
|
||||
uint32_t flags;
|
||||
uint16_t opflags;
|
||||
|
@ -134,6 +139,7 @@ protected:
|
|||
uint8_t syntax;
|
||||
uint64_t starttime;
|
||||
public:
|
||||
uint32_t errorct;
|
||||
|
||||
TFileProcessor();
|
||||
virtual ~TFileProcessor();
|
||||
|
@ -145,6 +151,21 @@ public:
|
|||
virtual void errorOut(uint16_t code);
|
||||
};
|
||||
|
||||
class TMerlinConverter : public TFileProcessor
|
||||
{
|
||||
protected:
|
||||
uint8_t tabs[10];
|
||||
std::vector<MerlinLine> lines;
|
||||
|
||||
public:
|
||||
TMerlinConverter();
|
||||
virtual ~TMerlinConverter();
|
||||
virtual void init(void);
|
||||
virtual int doline(int lineno, std::string line);
|
||||
virtual void process(void);
|
||||
virtual void complete(void);
|
||||
};
|
||||
|
||||
class TSymbol;
|
||||
typedef int (*TOpCB)(MerlinLine &line, TSymbol &sym);
|
||||
typedef std::function<int (MerlinLine &line, TSymbol &sym)> TOpCallback;
|
||||
|
@ -154,6 +175,7 @@ class TSymbol
|
|||
public:
|
||||
std::string namelc;
|
||||
std::string name;
|
||||
std::string text;
|
||||
uint32_t value;
|
||||
uint16_t stype;
|
||||
uint8_t opcode;
|
||||
|
@ -163,33 +185,50 @@ public:
|
|||
|
||||
TSymbol()
|
||||
{
|
||||
used=false;
|
||||
locals.clear();
|
||||
clear();
|
||||
};
|
||||
void clear(void)
|
||||
{
|
||||
value = 0;
|
||||
used = false;
|
||||
text = "";
|
||||
name = "";
|
||||
namelc = "";
|
||||
stype = 0;
|
||||
opcode = 0;
|
||||
locals.clear();
|
||||
}
|
||||
};
|
||||
|
||||
class TPsuedoOp;
|
||||
|
||||
class T65816Asm : public TFileProcessor
|
||||
{
|
||||
protected:
|
||||
bool passcomplete;
|
||||
public:
|
||||
// options
|
||||
bool casesen;
|
||||
bool relocatable;
|
||||
bool listing;
|
||||
bool showmx;
|
||||
bool trackrep;
|
||||
uint8_t mx;
|
||||
uint8_t cpumode; // 0=6502, 1=65C02, 2=65816
|
||||
|
||||
bool passcomplete;
|
||||
bool relocatable;
|
||||
bool skiplist; // used if lst is on, but LST opcode turns it off
|
||||
uint32_t errorct;
|
||||
uint32_t totalbytes;
|
||||
uint32_t lineno;
|
||||
uint32_t origin;
|
||||
uint8_t mx;
|
||||
uint8_t cpumode; // 0=6502, 1=65C02, 2=65816
|
||||
std::string savepath;
|
||||
TSymbol *currentsym;
|
||||
std::vector<MerlinLine> lines;
|
||||
Poco::HashMap<std::string, TSymbol>opcodes;
|
||||
Poco::HashMap<std::string, TSymbol> macros;
|
||||
Poco::HashMap<std::string, TSymbol> symbols;
|
||||
public:
|
||||
Poco::HashMap<std::string, TSymbol> variables;
|
||||
|
||||
TPsuedoOp *psuedoops;
|
||||
|
||||
uint16_t pass;
|
||||
uint32_t currentpc;
|
||||
|
||||
|
@ -207,10 +246,13 @@ public:
|
|||
int callOpCode(std::string op, MerlinLine &line);
|
||||
TSymbol *findSymbol(std::string sym);
|
||||
TSymbol *addSymbol(std::string sym, uint32_t val, bool replace);
|
||||
TSymbol *findVariable(std::string sym);
|
||||
TSymbol *addVariable(std::string sym, std::string val, bool replace);
|
||||
|
||||
|
||||
void initpass(void);
|
||||
void showSymbolTable(bool alpha);
|
||||
|
||||
void showVariables(void);
|
||||
int evaluate(std::string expr, int64_t &value);
|
||||
|
||||
int parseOperand(MerlinLine &line);
|
||||
|
|
2
config.h
2
config.h
|
@ -3,6 +3,8 @@
|
|||
// define application options here
|
||||
#define PAL_APPCLASS TMyCustomApp
|
||||
|
||||
//#define NO_SIGNAL_HANDLING
|
||||
|
||||
//#define SERVERAPP
|
||||
#define ENABLE_SSL
|
||||
#define USE_LOGGER
|
||||
|
|
22
eval.cpp
22
eval.cpp
|
@ -369,7 +369,6 @@ int CLASS::parseNumber(std::string n, int64_t &val)
|
|||
bool valid = false;
|
||||
bool err = false;
|
||||
bool neg = false;
|
||||
int base = 10;
|
||||
int64_t tval = 0;
|
||||
val = 0;
|
||||
|
||||
|
@ -392,9 +391,16 @@ int CLASS::parseNumber(std::string n, int64_t &val)
|
|||
{
|
||||
state = 20;
|
||||
}
|
||||
else if ((c == '-') && (!valid))
|
||||
else if (c == '-')
|
||||
{
|
||||
neg = !neg;
|
||||
if (!valid)
|
||||
{
|
||||
neg = !neg;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = 99;
|
||||
}
|
||||
}
|
||||
else if (isdigit(c))
|
||||
{
|
||||
|
@ -411,6 +417,7 @@ int CLASS::parseNumber(std::string n, int64_t &val)
|
|||
case 1:
|
||||
if (isdigit(c))
|
||||
{
|
||||
valid = true;
|
||||
s += c;
|
||||
tval *= 10;
|
||||
tval += c - '0';
|
||||
|
@ -422,7 +429,6 @@ int CLASS::parseNumber(std::string n, int64_t &val)
|
|||
break;
|
||||
case 10:
|
||||
|
||||
base = 16;
|
||||
if ((c >= 'a') && (c <= 'f'))
|
||||
{
|
||||
c = c - 0x20; // make it uppercase
|
||||
|
@ -449,7 +455,6 @@ int CLASS::parseNumber(std::string n, int64_t &val)
|
|||
else { state = 99; }
|
||||
break;
|
||||
case 20:
|
||||
base = 2;
|
||||
if ((c >= '0') && (c <= '1'))
|
||||
{
|
||||
s += c;
|
||||
|
@ -468,8 +473,7 @@ int CLASS::parseNumber(std::string n, int64_t &val)
|
|||
break;
|
||||
|
||||
case 99:
|
||||
setError(Token::syntaxErr);
|
||||
|
||||
err = true;
|
||||
// if you get into this state there is an error
|
||||
break;
|
||||
}
|
||||
|
@ -480,9 +484,12 @@ int CLASS::parseNumber(std::string n, int64_t &val)
|
|||
setError(Token::overflowErr);
|
||||
}
|
||||
|
||||
//printf("parsenumber: |%s|\n",s.c_str());
|
||||
|
||||
if ((state == 99) || (err))
|
||||
{
|
||||
setError(Token::syntaxErr);
|
||||
valid = false;
|
||||
val = DEF_VAL;
|
||||
}
|
||||
|
||||
|
@ -493,6 +500,7 @@ int CLASS::parseNumber(std::string n, int64_t &val)
|
|||
tval = -tval;
|
||||
}
|
||||
val = tval;
|
||||
//printf("value=%08lX\n", val);
|
||||
res = 0;
|
||||
}
|
||||
return (res);
|
||||
|
|
91
opcodes.cpp
91
opcodes.cpp
|
@ -1,16 +1,8 @@
|
|||
#include "asm.h"
|
||||
#include "psuedo.h"
|
||||
|
||||
#define CLASS T65816Asm
|
||||
|
||||
enum
|
||||
{
|
||||
P_ORG = 1,
|
||||
P_LST,
|
||||
P_SAV,
|
||||
|
||||
P_MAX
|
||||
};
|
||||
|
||||
void CLASS::setOpcode(MerlinLine &line, uint8_t op)
|
||||
{
|
||||
if (pass > 0)
|
||||
|
@ -32,39 +24,9 @@ void CLASS::setOpcode(MerlinLine &line, uint8_t op)
|
|||
|
||||
int CLASS::doPSEUDO(MerlinLine &line, TSymbol &sym)
|
||||
{
|
||||
std::string s;
|
||||
int res = 0;
|
||||
switch (sym.opcode)
|
||||
{
|
||||
case P_ORG:
|
||||
currentpc = line.expr_value;
|
||||
break;
|
||||
case P_SAV:
|
||||
savepath = line.operand;
|
||||
break;
|
||||
case P_LST:
|
||||
if (pass > 0)
|
||||
{
|
||||
s = Poco::toUpper(Poco::trim(line.operand));
|
||||
//printf("lst %d |%s| %08X \n", line.lineno, s.c_str(),line.expr_value);
|
||||
if ((s == "") || (s == "ON") || (line.expr_value > 0))
|
||||
{
|
||||
//printf("ON\n");
|
||||
skiplist = true;
|
||||
listing = true;
|
||||
}
|
||||
else if ((s == "OFF") || (line.expr_value == 0))
|
||||
{
|
||||
//printf("OFF\n");
|
||||
skiplist = true;
|
||||
listing = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
line.setError(errUnimplemented);
|
||||
break;
|
||||
}
|
||||
int res;
|
||||
|
||||
res = psuedoops->ProcessOpcode(*this, line, sym);
|
||||
return (res);
|
||||
}
|
||||
|
||||
|
@ -106,12 +68,15 @@ int CLASS::doMX(MerlinLine &line, TSymbol &sym)
|
|||
int CLASS::doEQU(MerlinLine &line, TSymbol &sym)
|
||||
{
|
||||
int res = 0;
|
||||
if (pass == 0)
|
||||
TSymbol *s;
|
||||
if (line.lable.length() > 0)
|
||||
{
|
||||
res = -1;
|
||||
TSymbol *s;
|
||||
if (line.lable.length() > 0)
|
||||
//printf("EQU: |%s|\n",line.operand.c_str());
|
||||
bool isvar = (line.lable[0] == ']') ? true : false;
|
||||
|
||||
if ((pass == 0) && (!isvar))
|
||||
{
|
||||
res = -1;
|
||||
//printf("EQU: |%s| %08X\n", line.lable.c_str(), line.expr_value);
|
||||
s = addSymbol(line.lable, line.expr_value, true);
|
||||
if (s != NULL)
|
||||
|
@ -119,6 +84,15 @@ int CLASS::doEQU(MerlinLine &line, TSymbol &sym)
|
|||
res = 0;
|
||||
}
|
||||
}
|
||||
else if (isvar)
|
||||
{
|
||||
res = -1;
|
||||
s = addVariable(line.lable, line.operand, true);
|
||||
if (s != NULL)
|
||||
{
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (res);
|
||||
}
|
||||
|
@ -198,7 +172,7 @@ int CLASS::doMVN(MerlinLine &line, TSymbol &sym)
|
|||
{
|
||||
value = 0xFFFFFFFF;
|
||||
line.setError(errBadOperand);
|
||||
line.errorText=line.operand_expr2;
|
||||
line.errorText = line.operand_expr2;
|
||||
}
|
||||
|
||||
setOpcode(line, op);
|
||||
|
@ -307,6 +281,29 @@ int CLASS::doAddress(MerlinLine &line, TSymbol &sym)
|
|||
}
|
||||
line.outbytect = res;
|
||||
}
|
||||
// if these are REP or SEP, see if we need to track
|
||||
if ((trackrep) && ((sym.opcode == 0xC2) || (sym.opcode == 0xE2)))
|
||||
{
|
||||
if (cpumode >= MODE_65816)
|
||||
{
|
||||
//printf("trackrep: %02X\n",line.expr_value&0xFF);
|
||||
// SGQ - if evaluation has errors, this must cause an error here
|
||||
// because expr_value won't be valid during pass 0 and will screw
|
||||
// up MX
|
||||
uint8_t newmx=(line.expr_value&0x30)>>4;
|
||||
switch(sym.opcode)
|
||||
{
|
||||
case 0xC2: // REP
|
||||
mx&=~newmx;
|
||||
break;
|
||||
case 0xE2: // SEP
|
||||
mx|=newmx;
|
||||
break;
|
||||
}
|
||||
line.linemx=mx;
|
||||
}
|
||||
|
||||
}
|
||||
return (res);
|
||||
}
|
||||
|
||||
|
|
59
psuedo.cpp
Normal file
59
psuedo.cpp
Normal file
|
@ -0,0 +1,59 @@
|
|||
#include "psuedo.h"
|
||||
|
||||
#define CLASS TPsuedoOp
|
||||
|
||||
CLASS::CLASS()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CLASS::~CLASS()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int CLASS::doLST(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
||||
{
|
||||
std::string s;
|
||||
if (a.pass > 0)
|
||||
{
|
||||
s = Poco::toUpper(Poco::trim(line.operand));
|
||||
if ((s == "") || (s == "ON") || (line.expr_value > 0))
|
||||
{
|
||||
//printf("ON\n");
|
||||
a.skiplist = true;
|
||||
a.listing = true;
|
||||
}
|
||||
else if ((s == "OFF") || (line.expr_value == 0))
|
||||
{
|
||||
//printf("OFF\n");
|
||||
a.skiplist = true;
|
||||
a.listing = false;
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int CLASS::ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
switch (opinfo.opcode)
|
||||
{
|
||||
default:
|
||||
res = -1; // undefined p-op
|
||||
line.setError(errUnimplemented);
|
||||
|
||||
break;
|
||||
case P_ORG:
|
||||
a.currentpc = line.expr_value;
|
||||
break;
|
||||
case P_SAV:
|
||||
a.savepath = line.operand;
|
||||
break;
|
||||
case P_LST:
|
||||
res = doLST(a, line, opinfo);
|
||||
break;
|
||||
}
|
||||
return (res);
|
||||
}
|
26
psuedo.h
Normal file
26
psuedo.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
#include "asm.h"
|
||||
|
||||
#define CLASS TPsuedoOp
|
||||
|
||||
enum
|
||||
{
|
||||
P_ORG = 1,
|
||||
P_LST,
|
||||
P_SAV,
|
||||
|
||||
P_MAX
|
||||
};
|
||||
|
||||
class CLASS
|
||||
{
|
||||
public:
|
||||
CLASS();
|
||||
~CLASS();
|
||||
int ProcessOpcode(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);
|
||||
int doLST(T65816Asm &a, MerlinLine &line, TSymbol &opinfo);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#undef CLASS
|
69
qasm.cpp
69
qasm.cpp
|
@ -14,6 +14,9 @@ programOption PAL::appOptions[] =
|
|||
{
|
||||
{ "debug", "d", "enable debug info (repeat for more verbosity)", "", false, true},
|
||||
{ "config-file", "f", "load configuration data from a <file>", "file", false, false},
|
||||
{ "tomerlin", "m", "convert file to merlin format ", "", false, false},
|
||||
{ "reformat", "r", "convert to readable ascii", "", false, false},
|
||||
|
||||
{ "", "", "", "", false, false}
|
||||
};
|
||||
|
||||
|
@ -56,38 +59,56 @@ int CLASS::runCommandLineApp(void)
|
|||
|
||||
std::string e = toUpper(path.getExtension());
|
||||
|
||||
if (e == "S")
|
||||
{
|
||||
//logger().information("ASM: " + path.toString());
|
||||
int x = getInt("option.reformat", 0);
|
||||
|
||||
t = new T65816Asm();
|
||||
}
|
||||
if (e == "LNK")
|
||||
if (x != 0)
|
||||
{
|
||||
//logger().information("LNK: " + path.toString());
|
||||
t = new T65816Link();
|
||||
}
|
||||
if (t != NULL)
|
||||
{
|
||||
t->init();
|
||||
res=0;
|
||||
t = new TMerlinConverter();
|
||||
if (t != NULL)
|
||||
{
|
||||
|
||||
std::string f = path.toString();
|
||||
t->processfile(f);
|
||||
t->process();
|
||||
t->complete();
|
||||
delete t;
|
||||
t = NULL;
|
||||
t->init();
|
||||
std::string f = path.toString();
|
||||
t->processfile(f);
|
||||
t->process();
|
||||
t->complete();
|
||||
res = (t->errorct > 0) ? -1 : 0;
|
||||
|
||||
delete t;
|
||||
t = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("not supported type\n");
|
||||
if (e == "S")
|
||||
{
|
||||
//logger().information("ASM: " + path.toString());
|
||||
|
||||
t = new T65816Asm();
|
||||
}
|
||||
if (e == "LNK")
|
||||
{
|
||||
//logger().information("LNK: " + path.toString());
|
||||
t = new T65816Link();
|
||||
}
|
||||
if (t != NULL)
|
||||
{
|
||||
t->init();
|
||||
std::string f = path.toString();
|
||||
t->processfile(f);
|
||||
t->process();
|
||||
t->complete();
|
||||
res = (t->errorct > 0) ? -1 : 0;
|
||||
delete t;
|
||||
t = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("not supported type\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//logger().information(*it);
|
||||
res = 0;
|
||||
}
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
|
|
8
qasm.ini
8
qasm.ini
|
@ -4,7 +4,7 @@ logdir=/var/log/mylog
|
|||
logfile=mylog.log
|
||||
|
||||
[option]
|
||||
debug=2
|
||||
debug=1
|
||||
;must be an integer. Code can use this as a level
|
||||
|
||||
[application]
|
||||
|
@ -22,10 +22,14 @@ path5=
|
|||
casesen=true
|
||||
showmx=true
|
||||
lst=true
|
||||
# can be M6502, M65C02, M65816
|
||||
; can be M6502, M65C02, M65816
|
||||
cpu=M65816
|
||||
trackrep=false
|
||||
|
||||
[reformat]
|
||||
tabs=12; 16; 20
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -8,15 +8,16 @@ MXX = $00
|
|||
mx MXX
|
||||
org $4000
|
||||
|
||||
dp = $A5
|
||||
dp: = $A5
|
||||
expr = $0405
|
||||
lexpr = $010203
|
||||
immed = $123456
|
||||
neg equ -16
|
||||
|
||||
]var1 = v1234
|
||||
|
||||
;lst off
|
||||
start00
|
||||
start00:
|
||||
brk ;$00
|
||||
ora (dp,x)
|
||||
cop $BA
|
||||
|
@ -33,6 +34,7 @@ start00
|
|||
ora expr
|
||||
asl expr
|
||||
oral lexpr
|
||||
;end
|
||||
|
||||
start10
|
||||
bpl start10
|
||||
|
@ -313,3 +315,5 @@ down
|
|||
lst off
|
||||
|
||||
sav ./test.bin
|
||||
lst
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user