Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.                 dZ80 - Z80 Disassembler v2.0
  3.  
  4.                 Written by Mark Incley, 1st November, 1996 (v1.0)
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <malloc.h>
  10. #include <stdlib.h>
  11.  
  12. #include "types.h"
  13. #include "dissz80.h"
  14. #include "dz80.h"
  15.  
  16. char    reqLayoutNumberPrefix[D_CUSTOMSTRING_MAXLEN], reqLayoutNumberSuffix[D_CUSTOMSTRING_MAXLEN];
  17. int     disRadix, showVersion;
  18.  
  19. static  DWORD bytesLoaded;
  20. static void ProgressUpdate(DISZ80 *d);
  21.  
  22. /* Not a great big table at the moment :) */
  23.  
  24. DISFILE FileExtList[]=
  25. {
  26.         {"sna", 27, 16384},     /* .SNA - Spectrum Snapshots */
  27.         {NULL, 0, 0}
  28. };
  29.  
  30.  
  31. int main(int argc, char* argv[])
  32. {
  33.         char            buf[256];
  34.         int                     err, startArgc;
  35.         DISZ80          *d;
  36.  
  37.         sprintf(buf, "dZ80 %s, Copyright 1996-2002 by Mark Incley.\n", dZ80_GetVersionString());
  38.         PrintToConsole(buf);
  39.  
  40.         d = malloc(sizeof(DISZ80));
  41.         if (d == NULL)
  42.                 {
  43.                 PrintToErrOut("Couldn't allocate DISZ80 structure");
  44.                 exit(1);
  45.                 }
  46.  
  47. /* Set up our DISZ80 structure */
  48.         memset(d, 0, sizeof(DISZ80));
  49.  
  50.         d->fnOutputMessage      = PrintToConsole;
  51.         d->fnErrorMessage       = PrintToErrOut;
  52.         d->fnProgressCallback = ProgressUpdate;
  53.  
  54.         d->cpuType              = DCPU_Z80;
  55.         d->flags                = DISFLAG_OPCODEDUMP | DISFLAG_ADDRDUMP | DISFLAG_USELABELADDRS;
  56.         dZ80_SetDefaultOptions(d);
  57.        
  58.         showVersion             = FALSE;
  59.         d->start                = 0;
  60.         d->end                  = 65535;
  61.         disRadix                = DRADIX_DEFAULT;
  62.  
  63. /* Allocate the opcode map so that the config.file may modify it */
  64.         dZ80_AllocateOpMap(d);
  65.  
  66. /* Have we passed the special case switch? */
  67.         startArgc = 1;
  68.         if (argc > 1)
  69.                 {
  70.                 if (!strcmp(argv[1], OMITCONFIGSWITCH))
  71.                         startArgc++;
  72.                 }
  73.  
  74. /* Load the config file dZ80.ini */
  75.         if (startArgc == 1)
  76.                 {
  77.                 err = dZ80_LoadConfiguration(d, NULL);
  78.                 if (err != DERR_NONE && err != DERR_SCRIPTING_NA)
  79.                         {
  80.                         sprintf(buf, "Error loading %s: %s", CONFIGFILENAME, dZ80_GetErrorText(err));
  81.                         PrintToConsole(buf);
  82.                         exit(1);
  83.                         }
  84.                 }
  85.  
  86. /* Parse the command line, overriding any config file settings */
  87.         if (ParseCmdLine(d, startArgc, argc, argv))
  88.                 exit(1);
  89.  
  90.         if (showVersion)
  91.                 {
  92.                 ShowVersionInfo();
  93.                 exit(0);
  94.                 }
  95.  
  96.         if (d->srcFileName[0] == 0)
  97.                 {
  98.                 ShowUsage();
  99.                 exit(0);
  100.                 }
  101.  
  102. /*
  103.         Note if we've specified a radix, we set it and then separately copy the prefix and suffixes
  104.         across, as they will have been clobbered by dZ80_SetRadix
  105. */     
  106.         if (d->layoutRadix != disRadix)
  107.                 dZ80_SetRadix(d, disRadix);
  108.  
  109.         if (d->parametersModified & DPM_NUMPREFIX)
  110.                 strcpy(d->layoutNumberPrefix, reqLayoutNumberPrefix);
  111.  
  112.         if (d->parametersModified & DPM_NUMSUFFIX)
  113.                 strcpy(d->layoutNumberSuffix, reqLayoutNumberSuffix);
  114.  
  115.         ScanFilenameForPresets(d);
  116.         ParseFilenames(d);
  117.  
  118.         err = dZ80_LoadZ80File(d, &bytesLoaded);
  119.         if (err)
  120.                 exit(err);
  121.  
  122.         if (bytesLoaded == 0)
  123.                 {
  124.                 dZ80_Error(d, "Cannot load a zero byte file.\n");
  125.                 exit(1);
  126.                 }
  127.  
  128. /* Make sure we've got sensible start and end addresses */
  129.         if (d->start < d->fileStartAddr)
  130.                 {
  131.                 if (!(d->parametersModified & DPM_STARTADDR))
  132.                         d->start = d->fileStartAddr;
  133.                 }
  134.  
  135.         if (d->end > (d->fileStartAddr + bytesLoaded))
  136.                 {
  137.                 if (!(d->parametersModified & DPM_ENDADDR))
  138.                         d->end = d->fileStartAddr + (WORD)(bytesLoaded - 1);
  139.                 }
  140.        
  141. /* ...and do the biz */
  142.         dZ80_Disassemble(d);
  143.  
  144.         free(d->mem0Start);
  145.         free(d);
  146.  
  147.         exit(0);
  148. }
  149.  
  150.  
  151. void ParseFilenames(DISZ80 *d)
  152. {
  153.         char    *extPtr;
  154.  
  155. /* If specified a reference filename, don't interfere */
  156.         if (d->refFileName[0])
  157.                 return;
  158.  
  159. /* Are we going to need a reference filename ? */
  160.         if (d->flags & DISFLAG_ANYREF)
  161.                 {
  162.                 strcpy(d->refFileName, d->srcFileName);
  163.  
  164. /* Hardly, foolproof, but this will replace any extension with .REF */
  165.                 extPtr = (char *)strrchr(d->refFileName, '.');
  166.  
  167. /* If there is a period, make sure it isn't a terminating one */
  168.                 if (extPtr != NULL)
  169.                         {
  170.                         if (*extPtr+1)
  171.                                 {
  172.                                 strcpy(extPtr+1, "ref");
  173.                                 return;
  174.                                 }
  175.                         }
  176.                 else
  177.                         {
  178.                         strcat(d->refFileName, ".ref");
  179.                         }
  180.                 }
  181.  
  182.         return;
  183. }
  184.  
  185.  
  186. void ScanFilenameForPresets(DISZ80 *d)
  187. {
  188.         char    *extPtr;
  189.         char    fileExt[16], buf[128];
  190.         int     i;
  191.  
  192.         extPtr = strrchr(d->srcFileName, '.');
  193.         if (extPtr == NULL)
  194.                 return;                                                 /* No extension, so no presets. */
  195.  
  196.         strcpy(fileExt, (extPtr)+1);
  197.         dZ80_StringToLower(fileExt);            /* Make lower case */
  198.  
  199.         for (i=0; ; i++)
  200.                 {
  201.                 if (FileExtList[i].Extension == 0)
  202.                         return;
  203.  
  204.                 if (!strcmp(fileExt, FileExtList[i].Extension) )
  205.                         {
  206.                         if (!(d->flags & DISFLAG_QUIET))
  207.                                 {
  208.                                 sprintf(buf, "Using presets for .%s file extension.\n", fileExt);
  209.                                 PrintToConsole(buf);
  210.                                 }
  211.  
  212.                         d->fileHeaderSize = FileExtList[i].FileHeaderSize;
  213.                         d->fileStartAddr = FileExtList[i].BaseOffset;
  214.                         return;
  215.                         }
  216.                 }
  217. }
  218.  
  219.  
  220. void PrintToErrOut(char *Str)
  221. {
  222.         fwrite(Str, 1, strlen(Str), stderr);
  223.         fwrite("\n", 1, 1, stderr);
  224.         return;
  225. }
  226.  
  227. void PrintToConsole(char *Str)
  228. {
  229.         printf("%s\n", Str);
  230.         return;
  231. }
  232.  
  233.  
  234. /*
  235.         This function is frequently called by the disassembler module to allow its progress
  236.         to be displayed. It's used by the Windows version of dZ80 to implement a progress bar.
  237. */
  238.  
  239. static void ProgressUpdate(DISZ80 *d)
  240. {
  241.         return;
  242. }
  243.  
  244.  
  245. void ShowVersionInfo(void)
  246. {
  247.         char    buf[256];
  248.  
  249.         sprintf(buf, "dZ80 core %s, %s", dZ80_GetVersionString(), LUA_VERSION);
  250.         PrintToConsole(buf);
  251.         return;
  252. }
  253.  
  254.  
  255. void ShowUsage(void)
  256. {
  257.         char    buf[256];
  258.  
  259.         sprintf(buf,
  260.            "Disassembles a Z80 binary file.                        E-mail: %s\n", DZ80_EMAIL);
  261.         PrintToConsole(buf);
  262.         PrintToConsole("DZ80 [!] [switches] infile [outfile]\n"
  263.            "\n"
  264.            "  !         Prevents dZ80 from automatically loading the configuration file.\n"
  265.            "  -h=nn     Skips past the first nn bytes of the input file.\n"
  266.            "  -m=nn     Specifies whereabouts in Z80 memory the file starts.\n"
  267.            "  -s=nn     Specifies the address to start disassembling from.\n"
  268.            "  -e=nn     Specifies the ending disassembly address.\n"
  269.            "  -r=file   Specify the name for the reference file. Used with -xa -xn -xo -xi.\n"
  270.            "  -xi       Create reference of input ports.\n"
  271.            "  -xo       Create reference of output ports.\n"
  272.            "  -xa       Create reference of addresses.\n"
  273.            "  -xn       Create reference of indirect addresses.\n"
  274.            "  -k=script Use the specified script file.\n"
  275.            "  -l            Create a labelled (assembleable) output file.\n"
  276.            "  -z=cpu    Set the CPU type to Z80GB, Z80 (default) or Z180.\n"
  277.            );
  278.  
  279.         sprintf(buf,
  280.            "Note that this is only a partial list of switches. You can use the %s\n"
  281.            "configuration file to control dz80. Please read the dz80.txt file for details.", CONFIGFILENAME);
  282.         PrintToConsole(buf);
  283.  
  284.         return;
  285. }
  286.  
  287.