summaryrefslogtreecommitdiffstatshomepage
path: root/src/tools
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2009-08-22 23:31:02 +0000
committer Aaron Giles <aaron@aarongiles.com>2009-08-22 23:31:02 +0000
commit2128210d76dd2a6c6786cbe543af21dc0689df45 (patch)
treeb3a1a6163012dda9fb52d63afe39819dbdb14415 /src/tools
parent31d85e814f61ecff374dc9cf6ecb3678ddb3b5d4 (diff)
Ok, disassembler is implemented with basic functionality.
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/unidasm.c268
1 files changed, 234 insertions, 34 deletions
diff --git a/src/tools/unidasm.c b/src/tools/unidasm.c
index b3a0d8a57e0..89308577900 100644
--- a/src/tools/unidasm.c
+++ b/src/tools/unidasm.c
@@ -10,6 +10,52 @@
***************************************************************************/
#include "cpuintrf.h"
+#include <ctype.h>
+
+
+enum _display_type
+{
+ _8bit,
+ _8bitx,
+ _16be,
+ _16le,
+ _24be,
+ _24le,
+ _32be,
+ _32le,
+ _40be,
+ _40le,
+ _48be,
+ _48le,
+ _56be,
+ _56le,
+ _64be,
+ _64le
+};
+typedef enum _display_type display_type;
+
+
+typedef struct _dasm_table_entry dasm_table_entry;
+struct _dasm_table_entry
+{
+ const char * name;
+ display_type display;
+ INT8 pcshift;
+ cpu_disassemble_func func;
+};
+
+
+typedef struct _options options;
+struct _options
+{
+ const char * filename;
+ offs_t basepc;
+ UINT8 norawbytes;
+ UINT8 lower;
+ UINT8 upper;
+ const dasm_table_entry *dasm;
+};
+
CPU_DISASSEMBLE( adsp21xx );
CPU_DISASSEMBLE( alpha8201 );
@@ -129,31 +175,6 @@ CPU_DISASSEMBLE( z8000 );
CPU_DISASSEMBLE( z80 );
-enum _display_type
-{
- _8bit,
- _16be,
- _16le,
- _24be,
- _24le,
- _32be,
- _32le,
- _64be,
- _64le
-};
-typedef enum _display_type display_type;
-
-
-typedef struct _dasm_table_entry dasm_table_entry;
-struct _dasm_table_entry
-{
- const char * name;
- display_type display;
- INT8 pcshift;
- cpu_disassemble_func func;
-};
-
-
static const dasm_table_entry dasm_table[] =
{
{ "adsp21xx", _24le, -2, CPU_DISASSEMBLE_NAME(adsp21xx) },
@@ -302,18 +323,197 @@ void CLIB_DECL mame_printf_debug(const char *format, ...)
}
-int main(int argc, char *argv[])
+int parse_options(int argc, char *argv[], options *opts)
{
- char buffer[1024];
- UINT8 oprom[10] = { 0x12, 0x34, 0x56, 0x78 };
- offs_t basepc = 0;
- int index;
+ int pending_base = FALSE;
+ int pending_arch = FALSE;
+ int arg;
-//const device_config *device, char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram
- for (index = 0; index < ARRAY_LENGTH(dasm_table); index++)
+ memset(opts, 0, sizeof(*opts));
+
+ // loop through arguments
+ for (arg = 1; arg < argc; arg++)
{
- int result = (*dasm_table[index].func)(NULL, buffer, basepc, oprom, oprom);
- printf("%10s: (%d) %s\n", dasm_table[index].name, result & DASMFLAG_LENGTHMASK, buffer);
+ char *curarg = argv[arg];
+
+ // is it a switch?
+ if (curarg[0] == '-')
+ {
+ if (pending_base || pending_arch)
+ goto usage;
+
+ if (tolower(curarg[1]) == 'a')
+ pending_arch = TRUE;
+ else if (tolower(curarg[1]) == 'b')
+ pending_base = TRUE;
+ else if (tolower(curarg[1]) == 'l')
+ opts->lower = TRUE;
+ else if (tolower(curarg[1]) == 'n')
+ opts->norawbytes = TRUE;
+ else if (tolower(curarg[1]) == 'u')
+ opts->upper = TRUE;
+ else
+ goto usage;
+ }
+
+ // base PC
+ else if (pending_base)
+ {
+ if (curarg[0] == '0' && curarg[1] == 'x')
+ sscanf(&curarg[2], "%x", &opts->basepc);
+ else if (curarg[0] == '$')
+ sscanf(&curarg[1], "%x", &opts->basepc);
+ else
+ sscanf(&curarg[0], "%x", &opts->basepc);
+ pending_base = FALSE;
+ }
+
+ // architecture
+ else if (pending_arch)
+ {
+ int curarch;
+ for (curarch = 0; curarch < ARRAY_LENGTH(dasm_table); curarch++)
+ if (core_stricmp(curarg, dasm_table[curarch].name) == 0)
+ break;
+ if (curarch == ARRAY_LENGTH(dasm_table))
+ goto usage;
+ opts->dasm = &dasm_table[curarch];
+ pending_arch = FALSE;
+ }
+
+ // filename
+ else if (opts->filename == NULL)
+ opts->filename = curarg;
+
+ // fail
+ else
+ goto usage;
}
+
+ // if no file or no architecture, fail
+ if (opts->filename == NULL || opts->dasm == NULL)
+ goto usage;
+ return 0;
+
+usage:
+ printf("Usage: %s <filename> -arch <architecture> [-basepc <pc>] [-norawbytes] [-upper] [-lower]\n", argv[0]);
+ return 1;
+};
+
+
+int main(int argc, char *argv[])
+{
+ file_error filerr;
+ int displayendian;
+ int displaychunk;
+ UINT32 curbyte;
+ UINT32 length;
+ int maxchunks;
+ UINT32 curpc;
+ options opts;
+ int numbytes;
+ void *data;
+ char *p;
+
+ // parse options first
+ if (parse_options(argc, argv, &opts))
+ return 1;
+
+ // load the file
+ filerr = core_fload(opts.filename, &data, &length);
+ if (filerr != FILERR_NONE)
+ {
+ fprintf(stderr, "Error opening file '%s'\n", opts.filename);
+ return 1;
+ }
+
+ // precompute parameters
+ displaychunk = (opts.dasm->display / 2) + 1;
+ displayendian = opts.dasm->display % 2;
+ switch (displaychunk)
+ {
+ case 1: maxchunks = 6; break;
+ case 2: maxchunks = 3; break;
+ default: maxchunks = 1; break;
+ }
+
+ // run it
+ curpc = opts.basepc;
+ for (curbyte = 0; curbyte < length; curbyte += numbytes)
+ {
+ UINT8 *oprom = (UINT8 *)data + curbyte;
+ char buffer[1024];
+ UINT32 pcdelta;
+ int numchunks;
+
+ // disassemble
+ pcdelta = (*opts.dasm->func)(NULL, buffer, curpc, oprom, oprom) & DASMFLAG_LENGTHMASK;
+ if (opts.dasm->pcshift < 0)
+ numbytes = pcdelta << -opts.dasm->pcshift;
+ else
+ numbytes = pcdelta >> opts.dasm->pcshift;
+
+ // round to the nearest display chunk
+ numbytes = ((numbytes + displaychunk - 1) / displaychunk) * displaychunk;
+ if (numbytes == 0)
+ numbytes = displaychunk;
+ numchunks = numbytes / displaychunk;
+
+ // output the address
+ printf("%08X: ", curpc);
+
+ // output the raw bytes
+ if (!opts.norawbytes)
+ {
+ int firstchunks = (numchunks < maxchunks) ? numchunks : maxchunks;
+ int chunknum, bytenum;
+ for (chunknum = 0; chunknum < firstchunks; chunknum++)
+ {
+ for (bytenum = 0; bytenum < displaychunk; bytenum++)
+ printf("%02X", oprom[displayendian ? (displaychunk - 1 - bytenum) : bytenum]);
+ printf(" ");
+ oprom += displaychunk;
+ }
+ for ( ; chunknum < maxchunks; chunknum++)
+ printf("%*s ", displaychunk * 2, "");
+ printf(" ");
+ }
+
+ // output the disassembly
+ if (opts.lower)
+ {
+ for (p = buffer; *p != 0; p++)
+ *p = tolower(*p);
+ } else if (opts.upper)
+ {
+ for (p = buffer; *p != 0; p++)
+ *p = toupper(*p);
+ }
+ printf("%s\n", buffer);
+
+ // output additional raw bytes
+ if (!opts.norawbytes && numchunks > maxchunks)
+ {
+ for (numchunks -= maxchunks; numchunks > 0; numchunks -= maxchunks)
+ {
+ int firstchunks = (numchunks < maxchunks) ? numchunks : maxchunks;
+ int chunknum, bytenum;
+ printf(" ");
+ for (chunknum = 0; chunknum < firstchunks; chunknum++)
+ {
+ for (bytenum = 0; bytenum < displaychunk; bytenum++)
+ printf("%02X", oprom[displayendian ? (displaychunk - 1 - bytenum) : bytenum]);
+ printf(" ");
+ oprom += displaychunk;
+ }
+ printf("\n");
+ }
+ }
+
+ // advance
+ curpc += pcdelta;
+ curbyte += numbytes;
+ }
+
return 0;
}