mirror of
https://github.com/holub/mame
synced 2025-05-19 20:29:09 +03:00
Ok, disassembler is implemented with basic functionality.
This commit is contained in:
parent
31d85e814f
commit
2128210d76
@ -10,6 +10,52 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "cpuintrf.h"
|
#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( adsp21xx );
|
||||||
CPU_DISASSEMBLE( alpha8201 );
|
CPU_DISASSEMBLE( alpha8201 );
|
||||||
@ -129,31 +175,6 @@ CPU_DISASSEMBLE( z8000 );
|
|||||||
CPU_DISASSEMBLE( z80 );
|
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[] =
|
static const dasm_table_entry dasm_table[] =
|
||||||
{
|
{
|
||||||
{ "adsp21xx", _24le, -2, CPU_DISASSEMBLE_NAME(adsp21xx) },
|
{ "adsp21xx", _24le, -2, CPU_DISASSEMBLE_NAME(adsp21xx) },
|
||||||
@ -302,18 +323,197 @@ void CLIB_DECL mame_printf_debug(const char *format, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int parse_options(int argc, char *argv[], options *opts)
|
||||||
|
{
|
||||||
|
int pending_base = FALSE;
|
||||||
|
int pending_arch = FALSE;
|
||||||
|
int arg;
|
||||||
|
|
||||||
|
memset(opts, 0, sizeof(*opts));
|
||||||
|
|
||||||
|
// loop through arguments
|
||||||
|
for (arg = 1; arg < argc; arg++)
|
||||||
|
{
|
||||||
|
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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char buffer[1024];
|
file_error filerr;
|
||||||
UINT8 oprom[10] = { 0x12, 0x34, 0x56, 0x78 };
|
int displayendian;
|
||||||
offs_t basepc = 0;
|
int displaychunk;
|
||||||
int index;
|
UINT32 curbyte;
|
||||||
|
UINT32 length;
|
||||||
|
int maxchunks;
|
||||||
|
UINT32 curpc;
|
||||||
|
options opts;
|
||||||
|
int numbytes;
|
||||||
|
void *data;
|
||||||
|
char *p;
|
||||||
|
|
||||||
//const device_config *device, char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram
|
// parse options first
|
||||||
for (index = 0; index < ARRAY_LENGTH(dasm_table); index++)
|
if (parse_options(argc, argv, &opts))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// load the file
|
||||||
|
filerr = core_fload(opts.filename, &data, &length);
|
||||||
|
if (filerr != FILERR_NONE)
|
||||||
{
|
{
|
||||||
int result = (*dasm_table[index].func)(NULL, buffer, basepc, oprom, oprom);
|
fprintf(stderr, "Error opening file '%s'\n", opts.filename);
|
||||||
printf("%10s: (%d) %s\n", dasm_table[index].name, result & DASMFLAG_LENGTHMASK, buffer);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user