#pragma once #include "qasm.h" using namespace Poco; #define ENV_QASM "QASM_BASE" #define MAX_PREFIX 32 #define MODE_6502 0 #define MODE_65C02 1 #define MODE_65816 2 #define SYNTAX_MERLIN 0x01 #define SYNTAX_MERLIN16 0x02 #define SYNTAX_MERLIN16PLUS 0x04 #define SYNTAX_MERLIN32 0x08 #define SYNTAX_APW 0x10 #define SYNTAX_MPW 0x20 #define SYNTAX_ORCA 0x40 #define SYNTAX_CC65 0x80 #define SYNTAX_LISA 0x100 #define SYNTAX_QASM (0x200 | 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 enum { syn_err = -1, // error - not recognized syn_none = 0, // should never be returned 0 syn_implied, // no operand 1 syn_s, // expr,s 2 syn_sy, // (expr,s),y 3 syn_imm, // #expr 4 syn_diix, // (expr,x) 5 syn_diiy, // (expr),y 6 syn_di, // (expr) 7 syn_iyl, // [expr],y 8 syn_dil, // [expr] 9 syn_absx, // expr,x 10 syn_absy, // expr,y 11 syn_bm, // block move 12 syn_abs, // expr 13 syn_MAX }; class myLayeredConfiguration : public Poco::Util::LayeredConfiguration { public: myLayeredConfiguration() : Poco::Util::LayeredConfiguration() {}; ~myLayeredConfiguration() {}; }; #undef CLASS #define CLASS ConfigOptions class CLASS { protected: //vector> configs; vector valid_files; public: //Poco::JSON::Parser parser; //string jsonin; //Dynamic::Var jsonobj=NULL; uint16_t format_flags; uint16_t cpu_mode; string language; uint16_t langlevel; 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; myLayeredConfiguration *config=NULL; bool usecolor; CLASS() { language=""; setEnvironment(); clear(); setDefaults(); setLanguage("QASM",true); setCurrent(); } ~CLASS() { clear(); } void clear() { if (config!=NULL) { delete config; config=NULL; } config=new myLayeredConfiguration(); valid_files.clear(); } bool useColor(void) { bool res=false; if (PAL::getBool("option.color",false)) { res=true; } if ((!isatty(STDOUT_FILENO)) || (0)) { res=false; } return(res); } bool isQuiet(void) { bool res; res=PAL::getBool("option.quiet",false); if (isDebug()>0) { res=false; } return(res); } bool isList(void) { bool res; res=PAL::getBool("option.list",false); //printf("list: %d\n",res); return(res); } int printDefaults(string lang) { int res=-1; string s; int i; string l=Poco::toUpper(lang); if (l=="") { l=Poco::toUpper(language); } if (l!="") { setLanguage(l,false); setCurrent(); printf("Defaults for language (%s)\n",language.c_str()); printf("\t\tLanguage:\t\t\t%s\n",language.c_str()); printf("\t\tlanguageLevel:\t\t\t%d\n",langlevel); s=""; switch(cpu_mode) { case 0: s="M6502"; break; case 1: s="M65C02"; break; case 2: s="M65816"; break; } printf("\t\tcpu_mode:\t\t\t%s\n",s.c_str()); printf("\t\tstart_mx:\t\t\t%%%d%d\n",start_mx&0x02?1:0,start_mx&0x01?1:0); //printf("\t\tstart_mx:\t\t\t%d\n",start_mx); printf("\t\tPrefixes:\n"); for (i=0; i0) { printf("\t\t\t%2d:\t%s\n",i,prefixes[i].c_str()); } } printf("\n"); for (unsigned long ii=0; ii0) { printf("\t\tSettings files read: \t%s\n",valid_files[ii].c_str()); } } //uint16_t format_flags; //bool start_listmode; //bool listmode; } return(res); } string getAppPath() { char buff[PATH_MAX+1]; char *x; string res=""; res=Poco::Util::Application::instance().commandPath(); x=realpath(res.c_str(),buff); if (x!=NULL) { res=buff; } else { res=""; } return(res); } int ReadFile(string path, bool backtrack) { //int levels=0; bool done=false; int ret=-1; unsigned long ii; Poco::Util::JSONConfiguration *jc; while(!done) { Poco::Path pp(path); //pp=pp.absolute(Poco::Path("/")); pp=pp.absolute(); std::string basename=pp.getFileName(); Poco::File pf(pp); if (isDebug()>1) { //pf. printf(" %d parmsfile: %s ",backtrack,pf.path().c_str()); } if ((pf.exists()) && (pf.canRead()) && ((pf.isFile()) || (pf.isLink()))) { if (isDebug()>1) { printf("...found!\n"); } //printf("OK: %s\n",pp.toString().c_str()); done=false; for (ii=0; iiload(pp.toString()); success=true; } catch(...) { success=false; } if (success) { //configs.push_back(shared_ptr(jc)); config->add(jc); valid_files.push_back(pp.toString()); ret=0; } else { delete jc; jc=NULL; printf("...unable to load/parts file: %s\n",pp.toString().c_str()); } } } } else { if (isDebug()>1) { printf("...not found\n"); } } if (!backtrack) { done=true; } if (!done) { //string ss=pp.current(); string ss=pp.toString(); pp=pp.popDirectory(); string ss1=pp.toString(); //printf("|%s| |%s|\n",ss.c_str(),ss1.c_str()); //assert(0); path=ss1; pp=Path(path); if (path=="/") { done=true; } //path=path+"/"+basename; } } return(ret); } bool isMerlin32(void) { bool res=false; if (language=="MERLIN32") { res=true; } return(res); } bool isMerlin(void) { bool res=false; if (language=="MERLIN") { res=true; } return(res); } bool isNative(void) // use this as we are running in 'native/qasm' mode so we can add special options { bool res=false; if (language=="QASM") { res=true; } return(res); } bool isMerlinCompat() { bool res=false; string s=language; if (s=="QASM") { return(true); } bool b=s.find("MERLIN"); // any of the merlin varieties if (b) { res=true; return(res); } return(res); } bool isMerlin16(void) { bool res=false; if (language=="MERLIN16") { res=true; } return(res); } bool isMerlin16plus(void) { bool res=false; if (language=="MERLIN16PLUS") { res=true; } return(res); } void setEnvironment() { string s=""; //s=Poco::Environment::get("QASM"); if (!Poco::Environment::has(ENV_QASM)) { s=Poco::Util::Application::instance().commandPath(); Poco::Path pp(getAppPath()); pp=pp.absolute(Poco::Path()); //pp=pp.absolute(Poco::Path("/")); s=pp.toString(); //printf("program: %s\n",s.c_str()); Poco::Environment::set(ENV_QASM,s); } } string formatPath(string p) { string res=p; string s; Poco::Path pp(p); s=pp.expand(pp.toString()); // replace environment variable references pp=Poco::Path(s); if (s!="") { Poco::StringTokenizer toks(s,"/"); if (toks.count()>0) { uint32_t n; bool success=false; try { n=Poco::NumberParser::parseUnsigned(toks[0]); if (ngetBool(name); //Dynamic::Var jresult=GetObject(name); //if (!jresult.isEmpty()) //{ // if (jresult.isArray()) // { // } // else if (jresult.isBoolean()) // { // res=jresult; // } //} } catch(...) { res=def; } return(res); } string GetString(string name, string def) { string res=def; try { res=config->getString(name); } catch(...) { res=def; } return(res); } int32_t GetInteger(string name, int32_t def) { int32_t res=def; #if 0 std::vector keys; config->keys(keys); for (unsigned int i=0; igetInt(name); } catch(...) { res=def; //throw; } return(res); } string addrModeEnglish(int mode) { string res=""; switch(mode) { case syn_err: res="error"; break; case syn_none: res=""; break; case syn_implied: res="impl"; break; case syn_s: res="dp,s"; break; case syn_sy: res="(dp,s),y"; break; case syn_imm: res="#imme"; break; case syn_diix: res="(dp,x)"; break; case syn_diiy: res="(dp),y"; break; case syn_di: res="(dp)"; break; case syn_iyl: res="[expr],y"; break; case syn_dil: res="[expr]"; break; case syn_absx: res="abs,x"; break; case syn_absy: res="abs,y"; break; case syn_bm: res="blkmv"; break; case syn_abs: res="abs"; break; default: res="unknown"; break; } return(res); } }; #undef CLASS