Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.         dZ80 configuration support
  3.  
  4.         dZ80 will attempt to load and use a file called dz80.ini in the current folder
  5.         Any settings in this file will override dZ80's defaults. Similarly, for the Windows version
  6.         of dZ80, any settings in the config file will override the settings set in the GUI.
  7. */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <assert.h>
  12. #include <string.h>
  13.  
  14. #include "dissz80p.h"
  15. #include "lualib.h"
  16. #include "lauxlib.h"
  17.  
  18. typedef struct CFGITEM_tag
  19.         {
  20.         char    *varName;
  21.         BYTE    type;
  22.         int             (*fnHandler)(void *pv, DISZ80 *d);
  23.         } CFGITEM;
  24.  
  25.  
  26. /* Local fn's */
  27. static int SetArea(lua_State *ls, BYTE type);
  28. static int ProcessConfig(lua_State *ls, DISZ80 *d);
  29. static int SetDisFlag(DISZ80 *d, void *pv, DWORD flag);
  30.  
  31. /* Configuration file Lua extensions */
  32. static int d_SetCodeRegion(lua_State *ls);
  33. static int d_SetDataRegion(lua_State *ls);
  34. static int d_Exist(lua_State *ls);
  35.  
  36. /* Config handlers */
  37. static int cfg_cpu(void *pv, DISZ80 *d);
  38. static int cfg_inputfile(void *pv, DISZ80 *d);
  39. static int cfg_outputfile(void *pv, DISZ80 *d);
  40. static int cfg_fileheader(void *pv, DISZ80 *d);
  41. static int cfg_filebase(void *pv, DISZ80 *d);
  42. static int cfg_start(void *pv, DISZ80 *d);
  43. static int cfg_end(void *pv, DISZ80 *d);
  44. static int cfg_quiet(void *pv, DISZ80 *d);
  45. static int cfg_labelledoutput(void *pv, DISZ80 *d);
  46. static int cfg_labelreference(void *pv, DISZ80 *d);
  47. static int cfg_addresscomumn(void *pv, DISZ80 *d);
  48. static int cfg_opcodecolumn(void *pv, DISZ80 *d);
  49. static int cfg_relativejumpcomment(void *pv, DISZ80 *d);
  50. static int cfg_uppercase(void *pv, DISZ80 *d);
  51. static int cfg_autoblanklines(void *pv, DISZ80 *d);
  52. static int cfg_radix(void *pv, DISZ80 *d);
  53. static int cfg_db(void *pv, DISZ80 *d);
  54. static int cfg_comment(void *pv, DISZ80 *d);
  55. static int cfg_numprefix(void *pv, DISZ80 *d);
  56. static int cfg_numsuffix(void *pv, DISZ80 *d);
  57. static int cfg_script(void *pv, DISZ80 *d);
  58. static int cfg_referencefile(void *pv, DISZ80 *d);
  59. static int cfg_inportreference(void *pv, DISZ80 *d);
  60. static int cfg_outportreference(void *pv, DISZ80 *d);
  61. static int cfg_addressreference(void *pv, DISZ80 *d);
  62. static int cfg_indirectaddressreference(void *pv, DISZ80 *d);
  63. static int cfg_limitreferences(void *pv, DISZ80 *d);
  64. static int cfg_opmapfile(void *pv, DISZ80 *d);
  65.  
  66. #define         CFG_BOOL                        1
  67. #define         CFG_STRING                      2
  68. #define         CFG_NUM16                       3
  69. #define         CFG_NUM32                       4
  70.  
  71. CFGITEM cfgTable[] =
  72. {
  73.         {"cpu",                                         CFG_STRING,     cfg_cpu},
  74.         {"inputfile",                           CFG_STRING,     cfg_inputfile},
  75.         {"outputfile",                          CFG_STRING,     cfg_outputfile},
  76.         {"fileheadersize",                      CFG_NUM32,      cfg_fileheader},
  77.         {"filebaseaddr",                        CFG_NUM32,      cfg_filebase},
  78.         {"disstart",                            CFG_NUM16,      cfg_start},
  79.         {"disend",                                      CFG_NUM16,      cfg_end},
  80.         {"quiet",                                       CFG_BOOL,       cfg_quiet},
  81.         {"labelledoutput",                      CFG_BOOL,       cfg_labelledoutput},
  82.         {"labelreference",                      CFG_BOOL,       cfg_labelreference},
  83.         {"addresscolumn",                       CFG_BOOL,       cfg_addresscomumn},
  84.         {"opcodecolumn",                        CFG_BOOL,       cfg_opcodecolumn},
  85.         {"relativejumpcomment",         CFG_BOOL,       cfg_relativejumpcomment},
  86.         {"uppercase",                           CFG_BOOL,       cfg_uppercase},
  87.         {"autoblanklines",                      CFG_BOOL,       cfg_autoblanklines},
  88.         {"radix",                                       CFG_NUM16,      cfg_radix},
  89.         {"db",                                          CFG_STRING,     cfg_db},
  90.         {"comment",                                     CFG_STRING,     cfg_comment},
  91.         {"numprefix",                           CFG_STRING, cfg_numprefix},
  92.         {"numsuffix",                           CFG_STRING, cfg_numsuffix},
  93.         {"script",                                      CFG_STRING, cfg_script},
  94.         {"referencefile",                       CFG_STRING, cfg_referencefile},
  95.         {"inportreference",                     CFG_BOOL,       cfg_inportreference},
  96.         {"outportreference",            CFG_BOOL,       cfg_outportreference},
  97.         {"addressreference",            CFG_BOOL,       cfg_addressreference},
  98.         {"indirectaddressreference",CFG_BOOL,   cfg_indirectaddressreference},
  99.         {"limitreferences",                     CFG_BOOL,       cfg_limitreferences},
  100.         {"opmapfile",                           CFG_STRING,     cfg_opmapfile},
  101.  
  102.         {NULL,                                          0,                      NULL}
  103. };
  104.  
  105.  
  106. int dZ80_LoadConfiguration(DISZ80 *d, char *pConfigFile)
  107. {
  108.         int                     err;
  109.         lua_State       *ls;
  110.         FILE            *f;
  111.         char            buf[_MAX_PATH];
  112.        
  113.         if (pConfigFile == NULL)
  114.                 pConfigFile = CONFIGFILENAME;
  115.  
  116. /* Clear any flags or parameter modified flags */
  117.         d->flagsModified = d->parametersModified = 0;
  118.  
  119.        
  120. /* If there's a configuration file here, set up Lua and let it process the file */
  121.         f = fopen(pConfigFile, "rt");
  122.         if (f != NULL)
  123.                 {
  124.                 fclose(f);
  125.  
  126.                 sprintf(buf, "Loading configuration file \"%s\"", pConfigFile);
  127.                 dZ80_ShowMsg(d, buf);
  128.  
  129.                 ls = lua_open(0);
  130.                 if (ls == NULL)
  131.                         return DERR_OUTOFMEM;
  132.  
  133.                 lua_baselibopen(ls);
  134.                 lua_strlibopen(ls);
  135.  
  136.                 lua_pushuserdata(ls, d);
  137.                 lua_setglobal(ls, "DISZ80STRUC");
  138.  
  139.                 lua_register(ls, LUA_ERRORMESSAGE, LuaErrorHandler);
  140.  
  141. /* Register the config functions */
  142.                 lua_register(ls, "d_SetCodeRegion",             d_SetCodeRegion);
  143.                 lua_register(ls, "d_SetDataRegion",             d_SetDataRegion);
  144.                 lua_register(ls, "d_Exist",                             d_Exist);
  145.  
  146. /* Register the general support functions */
  147.                 lua_register(ls, "hex",                                 d_FromHex);
  148.  
  149.                 err = lua_dofile(ls, pConfigFile);
  150.  
  151.                 if (!err)
  152.                         err = ProcessConfig(ls, d);
  153.  
  154.                 lua_close(ls);
  155.  
  156.                 if (err)
  157.                         return DERR_SCRIPTERROR;
  158.                 }
  159.  
  160.         return DERR_NONE;
  161. }
  162.  
  163.  
  164. static int ProcessConfig(lua_State *ls, DISZ80 *d)
  165. {
  166.         CFGITEM *c;
  167.         int             err, fnErr;
  168.         double  n;
  169.         char    buf[256];
  170.         union  {
  171.                 char    *s;
  172.                 BYTE    b;
  173.                 WORD    w;
  174.                 DWORD   dw;
  175.                 } args;
  176.        
  177.         err = DERR_NONE;
  178.         c = cfgTable;
  179.                
  180.         while (c->varName != NULL && err == DERR_NONE)
  181.                 {
  182.                 lua_getglobal(ls, c->varName);
  183.                 if (!lua_isnil(ls, -1))
  184.                         {
  185.                         switch(c->type)
  186.                                 {
  187.                                 case CFG_BOOL:
  188.                                         if (lua_isnumber(ls, -1))
  189.                                                 {
  190.                                                 n = lua_tonumber(ls, -1);
  191.                                                 args.b = (n != 0);
  192.                                                 }
  193.                                         else
  194.                                                 err = DERR_WRONGARGUMENTTYPE;
  195.                                         break;
  196.  
  197.                                 case CFG_STRING:
  198.                                         if (lua_isstring(ls, -1))
  199.                                                 args.s = (char *)lua_tostring(ls, -1);
  200.                                         else
  201.                                                 err = DERR_WRONGARGUMENTTYPE;
  202.                                         break;
  203.  
  204.                                 case CFG_NUM16:
  205.                                         if (lua_isnumber(ls, -1))
  206.                                                 {
  207.                                                 n = lua_tonumber(ls, -1);
  208.                                                 if (n >= 0 && n <= 65535)
  209.                                                         args.w = (WORD)(n);
  210.                                                 else
  211.                                                         err = DERR_WRONGARGUMENTTYPE;
  212.                                                 }
  213.                                         else
  214.                                                 err = DERR_WRONGARGUMENTTYPE;
  215.                                         break;
  216.  
  217.                                 case CFG_NUM32:
  218.                                         if (lua_isnumber(ls, -1))
  219.                                                 {
  220.                                                 n = lua_tonumber(ls, -1);
  221.                                                 args.dw = (DWORD)(n);
  222.                                                 }
  223.                                         else
  224.                                                 err = DERR_WRONGARGUMENTTYPE;
  225.                                         break;
  226.                                 }
  227.  
  228.                         if (err == DERR_NONE)
  229.                                 {
  230.                                 fnErr = c->fnHandler(&args, d);
  231.                                 if (fnErr)
  232.                                         err = DERR_SCRIPTERROR;
  233.                                 }
  234.  
  235.                         if (err != DERR_NONE)
  236.                                 {
  237.                                 sprintf(buf, "Error retrieving \"%s\" value from configuration file.\n", c->varName);
  238.                                 dZ80_Error(d, buf);
  239.                                 }
  240.                         }       /* if (!lua_isnil(ls, -1)) */
  241.  
  242.                 lua_pop(ls, 1);
  243.                 c++;
  244.                 }
  245.  
  246.         return err;
  247. }
  248.  
  249. static int SetDisFlag(DISZ80 *d, void *pv, DWORD flag)
  250. {
  251.         assert(d != NULL);
  252.  
  253.         d->flagsModified |= flag;
  254.  
  255.         if (*(BYTE *)pv)
  256.                 d->flags |= flag;
  257.         else
  258.                 d->flags &= ~flag;
  259.  
  260.         return 0;
  261. }
  262.  
  263. static int d_Exist(lua_State *ls)
  264. {
  265.         char    *pFileName;
  266.         double  n;
  267.         FILE    *f;
  268.        
  269.         n = 0;
  270.  
  271.         if (lua_isstring(ls, 1))
  272.                 {
  273.                 pFileName = (char *)lua_tostring(ls, 1);
  274.                 f = fopen(pFileName, "rb");
  275.                 if (f != NULL)
  276.                         {
  277.                         fclose(f);
  278.                         n = 1;
  279.                         }
  280.                 }
  281.                
  282.         lua_pushnumber(ls, n);
  283.         return 1;
  284. }
  285.  
  286.  
  287.  
  288. static int d_SetCodeRegion(lua_State *ls)
  289. {
  290.         return SetArea(ls, 1);
  291. }
  292.  
  293.  
  294. static int d_SetDataRegion(lua_State *ls)
  295. {
  296.         return SetArea(ls, 0);
  297. }
  298.  
  299. /*
  300.         SetArea
  301.  
  302.         Set (or reset) the appropriate opMap bits
  303. */
  304.  
  305. static int SetArea(lua_State *ls, BYTE type)
  306. {
  307.         DISZ80          *d;
  308.         DWORD           start, end;
  309.         BYTE            mask;
  310.        
  311.         d = GetD(ls);
  312.        
  313.         if (d->opMap != NULL)
  314.                 {
  315.                 d->parametersModified |= DPM_OPMAP;
  316.  
  317.                 start = luaL_check_long(ls, 1);
  318.                 end = start + luaL_check_long(ls, 2) - 1;
  319.                
  320.                 if (type)
  321.                         type = 0xff;
  322.                
  323.                 while(start <= end && start < Z80MEMSIZE)
  324.                         {
  325.                         mask = 1 << (start & 7);
  326.                         d->opMap[start/8] &= ~mask;
  327.                         d->opMap[start/8] |= (mask & type);
  328.                         start++;
  329.                         }
  330.                 }
  331.                
  332.         return 0;
  333.  
  334. }
  335.  
  336. /*
  337.         Configuration handlers
  338. */
  339.  
  340. static int cfg_cpu(void *pv, DISZ80 *d)
  341. {
  342.         char    i;
  343.         char    buf[16];
  344.  
  345.         dZ80_SafeStringCopy(buf, *(char **)pv, sizeof(buf));
  346.         dZ80_StringToUpper(buf);
  347.  
  348.         for(i=0; i < DCPU_TOTAL; i++)
  349.                 {
  350.                 if (!strcmp(buf, dZ80CpuTypeNames[i]))
  351.                         break;
  352.                 }
  353.  
  354.         if (i < DCPU_TOTAL)
  355.                 {
  356.                 d->cpuType = i;
  357.                 }
  358.         else
  359.                 {
  360.                 dZ80_Error(d, "Unknown CPU type");
  361.                 return 1;
  362.                 }
  363.                
  364.         d->parametersModified |= DPM_CPUTYPE;
  365.         return 0;
  366. }
  367.  
  368.  
  369. static int cfg_inputfile(void *pv, DISZ80 *d)
  370. {
  371.         dZ80_SafeStringCopy(d->srcFileName, *(char **)pv, sizeof(d->srcFileName));
  372.         return 0;
  373. }
  374.  
  375. static int cfg_outputfile(void *pv, DISZ80 *d)
  376. {
  377.         dZ80_SafeStringCopy(d->outFileName, *(char **)pv, sizeof(d->outFileName));
  378.         return 0;
  379. }
  380.  
  381. static int cfg_fileheader(void *pv, DISZ80 *d)
  382. {
  383.         d->fileHeaderSize = *(DWORD *)pv;
  384.         d->parametersModified |= DPM_HDRSIZE;
  385.         return 0;
  386. }
  387.  
  388. static int cfg_filebase(void *pv, DISZ80 *d)
  389. {
  390.         d->fileStartAddr = *(WORD *)pv;
  391.         d->parametersModified |= DPM_FILESTARTADDR;
  392.         return 0;
  393. }
  394.  
  395. static int cfg_start(void *pv, DISZ80 *d)
  396. {
  397.         d->start = *(WORD *)pv;
  398.         d->parametersModified |= DPM_STARTADDR;
  399.         return 0;
  400. }
  401.  
  402. static int cfg_end(void *pv, DISZ80 *d)
  403. {
  404.         d->end = *(WORD *)pv;
  405.         d->parametersModified |= DPM_ENDADDR;
  406.         return 0;
  407. }
  408.  
  409.  
  410. static int cfg_quiet(void *pv, DISZ80 *d)
  411. {
  412.         return SetDisFlag(d, pv, DISFLAG_QUIET);
  413. }
  414.  
  415.  
  416. static int cfg_labelledoutput(void *pv, DISZ80 *d)
  417. {
  418.         return SetDisFlag(d, pv, DISFLAG_LABELLED);    
  419. }
  420.  
  421. static int cfg_labelreference(void *pv, DISZ80 *d)
  422. {
  423.         return SetDisFlag(d, pv, DISFLAG_USELABELADDRS);
  424. }
  425.  
  426. static int cfg_addresscomumn(void *pv, DISZ80 *d)
  427. {
  428.         return SetDisFlag(d, pv, DISFLAG_ADDRDUMP);
  429. }
  430.  
  431. static int cfg_opcodecolumn(void *pv, DISZ80 *d)
  432. {
  433.         return SetDisFlag(d, pv, DISFLAG_OPCODEDUMP);
  434. }
  435.  
  436. static int cfg_relativejumpcomment(void *pv, DISZ80 *d)
  437. {
  438.         return SetDisFlag(d, pv, DISFLAG_RELCOMMENT);
  439. }
  440.  
  441. static int cfg_uppercase(void *pv, DISZ80 *d)
  442. {
  443.         return SetDisFlag(d, pv, DISFLAG_UPPER);
  444. }
  445.  
  446. static int cfg_autoblanklines(void *pv, DISZ80 *d)
  447. {
  448.         return SetDisFlag(d, pv, DISFLAG_LINECOMMANDS);
  449. }
  450.  
  451. static int cfg_radix(void *pv, DISZ80 *d)
  452. {
  453.         BYTE    r;
  454.  
  455.         r = *(BYTE *)pv;
  456.         switch(r)
  457.                 {
  458.                 case 8:
  459.                         r = DRADIX_OCTAL;
  460.                         break;
  461.  
  462.                 case 10:
  463.                         r = DRADIX_DECIMAL;
  464.                         break;
  465.  
  466.                 case 16:
  467.                         r = DRADIX_HEX;
  468.                         break;
  469.  
  470.                 default:
  471.                         return 1;
  472.                 }
  473.  
  474.         d->layoutRadix = r;
  475.         d->parametersModified |= DPM_RADIX;
  476.         return 0;
  477. }
  478.  
  479. static int cfg_db(void *pv, DISZ80 *d)
  480. {
  481.         dZ80_SafeStringCopy(d->layoutDefineByte, *(char **)pv, sizeof(d->layoutDefineByte));
  482.         return 0;
  483. }
  484.  
  485. static int cfg_comment(void *pv, DISZ80 *d)
  486. {
  487.         dZ80_SafeStringCopy(d->layoutComment, *(char **)pv, sizeof(d->layoutComment));
  488.         return 0;
  489. }
  490.  
  491. static int cfg_numprefix(void *pv, DISZ80 *d)
  492. {
  493.         dZ80_SafeStringCopy(d->layoutNumberPrefix, *(char **)pv, sizeof(d->layoutNumberPrefix));
  494.         d->parametersModified |= DPM_NUMPREFIX;
  495.         return  0;
  496. }
  497.  
  498. static int cfg_numsuffix(void *pv, DISZ80 *d)
  499. {
  500.         dZ80_SafeStringCopy(d->layoutNumberSuffix, *(char **)pv, sizeof(d->layoutNumberSuffix));
  501.         d->parametersModified |= DPM_NUMSUFFIX;
  502.         return 0;
  503. }
  504.  
  505. static int cfg_script(void *pv, DISZ80 *d)
  506. {
  507.         dZ80_SafeStringCopy(d->scriptFileName, *(char **)pv, sizeof(d->scriptFileName));
  508.         return 0;      
  509. }
  510.  
  511. static int cfg_referencefile(void *pv, DISZ80 *d)
  512. {
  513.         dZ80_SafeStringCopy(d->refFileName, *(char **)pv, sizeof(d->refFileName));
  514.         return 0;      
  515. }
  516.  
  517. static int cfg_inportreference(void *pv, DISZ80 *d)
  518. {
  519.         return SetDisFlag(d, pv, DISFLAG_REFINPORT);
  520. }
  521.  
  522. static int cfg_outportreference(void *pv, DISZ80 *d)
  523. {
  524.         return SetDisFlag(d, pv, DISFLAG_REFOUTPORT);
  525. }
  526.  
  527. static int cfg_addressreference(void *pv, DISZ80 *d)
  528. {
  529.         return SetDisFlag(d, pv, DISFLAG_REFADDR);
  530. }
  531.  
  532. static int cfg_indirectaddressreference(void *pv, DISZ80 *d)
  533. {
  534.         return SetDisFlag(d, pv, DISFLAG_REFINDIRECT);
  535. }
  536.  
  537. static int cfg_limitreferences(void *pv, DISZ80 *d)
  538. {
  539.         return SetDisFlag(d, pv, DISFLAG_REFLIMITRANGE);
  540. }
  541.  
  542. static int cfg_opmapfile(void *pv, DISZ80 *d)
  543. {
  544.         dZ80_SafeStringCopy(d->opMapFileName, *(char **)pv, sizeof(d->opMapFileName));
  545.         return 0;
  546. }
  547.  
  548.