📄 dis_cf.c
字号:
/*********************************************************************
*
* Copyright:
* 1998-1999 MOTOROLA, INC. All Rights Reserved.
* You are hereby granted a copyright license to use, modify, and
* distribute the SOFTWARE so long as this entire notice is
* retained without alteration in any modified and/or redistributed
* versions, and that such modified versions are clearly identified
* as such. No licenses are granted by implication, estoppel or
* otherwise under any patents or trademarks of Motorola, Inc. This
* software is provided on an "AS IS" basis and without warranty.
*
* To the maximum extent permitted by applicable law, MOTOROLA
* DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING
* IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
* PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH REGARD TO THE
* SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) AND ANY
* ACCOMPANYING WRITTEN MATERIALS.
*
* To the maximum extent permitted by applicable law, IN NO EVENT
* SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING
* WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS
* INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY
* LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
*
* Motorola assumes no responsibility for the maintenance and support
* of this software
********************************************************************/
/*
* dis_cf.c:
*
* General notice:
* This code is part of a boot-monitor package developed as a generic base
* platform for embedded system designs. As such, it is likely to be
* distributed to various projects beyond the control of the original
* author. Please notify the author of any enhancements made or bugs found
* so that all may benefit from the changes. In addition, notification back
* to the author will allow the new user to pick up changes that may have
* been made by other users after this version of the code was distributed.
*
* Note1: the majority of this code was edited with 4-space tabs.
* Note2: as more and more contributions are accepted, the term "author"
* is becoming a mis-representation of credit.
*
* Original author: Ed Sutter
* Email: esutter@lucent.com
* Phone: 908-582-2351
*
* NOTE:
* This file originated from the Motorola DBUG file:
* dss/src/dbug/v2/cpu/m68k/mc68k.c
* (see above copyright notice).
* It was downloaded from the Motorola website:
* http://www.mot/com/SPS/HPESD/prod/coldfire/dbugfirm.html
*
*/
#include "config.h"
#include "genlib.h"
#if INCLUDE_DISASSEMBLER
#define SYMBOL_TABLE
#undef SYMBOL_TABLE
#define MCF5206
typedef unsigned char BYTE; /* 8 bits */
typedef unsigned short int WORD; /* 16 bits */
typedef unsigned long int LONG; /* 32 bits */
typedef signed char SBYTE; /* 8 bits */
typedef signed short int SWORD; /* 16 bits */
typedef signed long int SLONG; /* 32 bits */
typedef void *ADDRESS;
ADDRESS cpu_disasm (ADDRESS, int);
int
cpu_read_data(ADDRESS add,int wide)
{
if (wide == 8) {
return((int)*(BYTE *)add);
}
else if (wide == 16) {
return((int)*(WORD *)add);
}
else if (wide == 32) {
return((int)*(LONG *)add);
}
else {
printf("cpu_read_data() confused: wide = %d\n",wide);
return(0);
}
}
/* Don't change any of the following defines !!! */
#ifdef FALSE
#undef FALSE
#endif
#define FALSE 0
#ifdef TRUE
#undef TRUE
#endif
#define TRUE 1
#define SIZE_BYTE (8)
#define SIZE_WORD (16)
#define SIZE_LONG (32)
/*
* M68K addressing modes
*/
#define DRD (0x00000001) /* data register direct */
#define ARD (0x00000002) /* address register direct */
#define ARI (0x00000004) /* address register indirect */
#define ARIPO (0x00000008) /* ari with postincrement */
#define ARIPR (0x00000010) /* ari with predecrement */
#define ARID (0x00000020) /* ari with displacement */
#define ARII8 (0x00000040) /* ari with index 8-bit */
#define ARIIB (0x00000080) /* ari with index base */
#define MIPO (0x00000100) /* memory indirect postindexed */
#define MIPR (0x00000200) /* memory indirect preindexed */
#define PCID (0x00000400) /* program counter indirect disp */
#define PCII8 (0x00000800) /* pci with index 8-bit */
#define PCIIB (0x00001000) /* pci with index base */
#define PCMIPO (0x00002000) /* pc memory indirect postindexed */
#define PCMIPR (0x00004000) /* pc memory indirect preindexed */
#define AS (0x00008000) /* absolute short */
#define AL (0x00010000) /* absolute long */
#define IM (0x00020000) /* immediate */
/*
* Addressing mode categories
*/
#if (defined(MCF5200))
#define EA_DATA (DRD | ARI | ARIPO | ARIPR | ARID | ARII8 \
| PCID | PCII8 | AS | AL | IM )
#define EA_MEMORY (ARI | ARIPO | ARIPR | ARID | ARII8 \
| PCID | PCII8 | AS | AL | IM )
#define EA_CONTROL (ARI | ARID | ARII8 | PCID | PCII8 | AS | AL )
#define EA_ALTER (DRD | ARD | ARI | ARIPO | ARIPR | ARID | ARII8 )
#define EA_DATA_ALTER (DRD | ARI | ARIPO | ARIPR | ARID | ARII8 )
#define EA_MEM_ALTER (ARI | ARIPO | ARIPR | ARID | ARII8 )
#define EA_CTRL_ALTER (ARI | ARID | ARII8 )
#define EA_ALL (DRD | ARD | ARI | ARIPO | ARIPR | ARID | ARII8 \
| PCID | PCII8 | AS | AL | IM )
#define EA_NONE (0)
#define EA_DATA1 (DRD | ARI | ARIPO | ARIPR | ARID)
#define EA_DATA2 (DRD | IM)
#define EA_DATA3 (DRD | ARI | ARIPO | ARIPR | ARID | ARII8 | AS | AL \
| IM | PCID | PCII8)
#define EA_DATALT1 (DRD | ARI | ARIPO | ARIPR | ARID | ARII8 | AS | AL )
#define EA_DATALT2 (DRD)
#define EA_DATALT3 (DRD | ARI | ARIPO | ARIPR | ARID)
#define EA_ALTER1 (DRD | ARD | ARI | ARIPO | ARIPR | ARID | ARII8 | AS | AL)
#define EA_MEMALT1 (ARI | ARIPO | ARIPR | ARID | ARII8 | AS | AL)
#define EA_CTRL1 (ARI | ARID)
#define EA_CTRALT3 (ARI | ARID)
#ifdef MCF5200M
#define EA_MAC1 (ARI | ARIPO | ARIPR | ARID)
#define EA_MAC2 (DRD | ARD | IM)
#endif
#else
#define EA_DATA (DRD | ARI | ARIPO | ARIPR | ARID | ARII8 \
| ARIIB | MIPO | MIPR | PCID | PCII8 | PCIIB \
| PCMIPO | PCMIPR | AS | AL | IM )
#define EA_MEMORY (ARI | ARIPO | ARIPR | ARID | ARII8 \
| ARIIB | MIPO | MIPR | PCID | PCII8 | PCIIB \
| PCMIPO | PCMIPR | AS | AL | IM )
#define EA_CONTROL (ARI | ARID | ARII8 | ARIIB \
| MIPO | MIPR | PCID | PCII8 | PCIIB \
| PCMIPO | PCMIPR | AS | AL )
#define EA_ALTER (DRD | ARD | ARI | ARIPO | ARIPR | ARID | ARII8 \
| ARIIB | MIPO | MIPR \
| PCMIPO | PCMIPR )
#define EA_DATA_ALTER (DRD | ARI | ARIPO | ARIPR | ARID | ARII8 | ARIIB \
| MIPO | MIPR | PCMIPO | PCMIPR )
#define EA_MEM_ALTER (ARI | ARIPO | ARIPR | ARID | ARII8 | ARIIB \
| PCMIPO | PCMIPR )
#define EA_CTRL_ALTER (ARI | ARID | ARII8 | ARIIB | MIPO | MIPR \
| PCMIPO | PCMIPR )
#define EA_ALL (DRD | ARD | ARI | ARIPO | ARIPR | ARID | ARII8 \
| ARIIB | MIPO | MIPR | PCID | PCII8 | PCIIB \
| PCMIPO | PCMIPR | AS | AL | IM )
#define EA_NONE (0)
#define EA_DATA1 (DRD | ARI | ARIPO | ARIPR | ARID | ARII8 | ARIIB \
| MIPO | MIPR | PCID | PCII8 | PCIIB | PCMIPO \
| PCMIPR | AS | AL )
#define EA_DATALT1 (DRD | ARI | ARIPO | ARIPR | ARID | ARII8 | ARIIB \
| MIPO | MIPR | AS | AL )
#define EA_DATALT2 (DRD | ARI | ARIPO | ARIPR | ARID | ARII8 | AS | AL )
#define EA_ALTER1 (DRD | ARD | ARI | ARIPO | ARIPR | ARID | ARII8 \
| ARIIB | MIPO | MIPR | AS | AL)
#define EA_MEMALT1 (ARI | ARIPO | ARIPR | ARID | ARII8 | ARIIB \
| MIPO | MIPR | AS | AL)
#define EA_CTRALT1 (DRD | ARI | ARID | ARII8 | ARIIB | MIPO | MIPR \
| AS | AL )
#define EA_CTRALT2 (DRD | ARI | ARID | ARII8 | ARIIB | MIPO | MIPR \
| PCID | PCII8 | PCIIB | PCMIPO | PCMIPR | AS | AL )
#define EA_CTRALT3 (ARI | ARIPR | ARID | ARII8 | ARIIB | MIPO | MIPR \
| AS | AL )
#define EA_CTRL1 (ARI | ARIPO | ARID | ARII8 | ARIIB | MIPO | MIPR \
| PCID | PCII8 | PCIIB | PCMIPO | PCMIPR | AS | AL )
#endif
typedef struct
{
WORD keepers;
WORD match;
char *instruction;
int ea_mask;
void (*handler)(int, WORD);
} INSTRENTRY;
extern const INSTRENTRY isa[];
/********************************************************/
#define ADDRESS_REGISTER -2
#define DATA_REGISTER -3
/********************************************************/
static char dstr[80];
static ADDRESS disasm_pc;
static int disasm_op_size;
static int valid_instruction;
/********************************************************/
static void
inc_disasm_pc (unsigned int num)
{
disasm_pc = (ADDRESS)((unsigned int)disasm_pc +
(unsigned int)num);
}
/********************************************************/
static void
append_instruction (char *buf, char *instruction)
{
sprintf(buf,"%-10s",instruction);
}
#if 0
static void
append_string (char *buf, char *string)
{
/*
* This routine appends a string.
*/
strcat(buf,string);
}
#endif
#define append_string(a,b) strcat(a,b)
static void
append_value (char *buf, int value, int size)
{
/*
* This routine appends a value in hex notation.
*/
char buffer[9];
buffer[0] = '\0';
switch (size)
{
case 8:
sprintf(buffer,"0x%02X",value & 0x000000FF);
break;
case 16:
sprintf(buffer,"0x%04X",value & 0x0000FFFF);
break;
case 32:
sprintf(buffer,"0x%08X",value);
break;
}
strcat(buf,buffer);
}
static int
append_size2 (char *buf, int opword, int size_offset, int instr_size)
{
/*
* This field accepts `opword' and then determines according
* to the offset which size is specified.
*
* The `offset' are given by the bit number as listed in the
* M68000 Family Programmer's Reference, Chapter 8. [15 .. 0]
*/
int i, j, mask;
mask = 0x3; /* 2 bits */
for (i = 1; i < size_offset; i++)
mask = mask << 1;
i = (opword & mask) >> (size_offset - 1);
if (instr_size)
{
for (j = 0; *(char *)((int)buf +j) != ' '; ++j)
;
buf[j] = '.';
switch (i)
{
case 1:
buf[++j] = 'B';
disasm_op_size = SIZE_BYTE;
break;
case 2:
buf[++j] = 'L';
disasm_op_size = SIZE_LONG;
break;
case 3:
buf[++j] = 'W';
disasm_op_size = SIZE_WORD;
break;
default:
valid_instruction = FALSE;
break;
}
}
else
{
switch (i)
{
case 1:
strcat(buf,".B");
break;
case 2:
strcat(buf,".L");
break;
case 3:
strcat(buf,".W");
break;
default:
valid_instruction = FALSE;
break;
}
}
return i;
}
static int
append_size (char *buf, int opword, int size_offset, int instr_size)
{
/*
* This field accepts `opword' and then determines according
* to the offset which size is specified.
*
* The `offset' are given by the bit number as listed in the
* M68000 Family Programmer's Reference, Chapter 8. [15 .. 0]
*/
int i, j, mask;
mask = 0x3; /* 2 bits */
for (i = 1; i < size_offset; i++)
mask = mask << 1;
i = (opword & mask) >> (size_offset - 1);
disasm_op_size = -1;
if (instr_size)
{
for (j = 0; *(char *)((int)buf +j) != ' '; ++j)
;
buf[j] = '.';
switch (i)
{
case 0:
buf[++j] = 'B';
disasm_op_size = SIZE_BYTE;
break;
case 1:
buf[++j] = 'W';
disasm_op_size = SIZE_WORD;
break;
case 2:
buf[++j] = 'L';
disasm_op_size = SIZE_LONG;
break;
default:
valid_instruction = FALSE;
break;
}
}
else
{
switch (i)
{
case 0:
strcat(buf,".B");
break;
case 1:
strcat(buf,".W");
break;
case 2:
strcat(buf,".L");
break;
default:
valid_instruction = FALSE;
break;
}
}
return i;
}
static void
append_register (char *buf, int opword, int reg_offset, int reg_num_offset)
{
/*
* This field accepts `opword' and then determines according
* to the offsets which register (A0..A7,D0..D7) is specified.
* The register name is then concatenated to the end of the
* disasm_stmt.
*
* The `offsets' are given by the bit number as listed in the
* M68000 Family Programmer's Reference, Chapter 8. [15 .. 0]
*/
int i, mask;
char regnum[3];
/* Determine what kind of register */
if (reg_offset == ADDRESS_REGISTER)
{
strcat(buf,"A");
}
else
{
if (reg_offset == DATA_REGISTER)
{
strcat(buf,"D");
}
else
{
mask = 1;
for (i = 0; i < reg_offset; i++)
mask = mask << 1;
if (opword & mask)
strcat(buf,"A");
else
strcat(buf,"D");
}
}
/* determine register number */
/* The offset given is the msb of the 3 bit field containing */
/* the register number. */
mask = 0x7; /* 3 bits */
for (i = 2; i < reg_num_offset; i++)
mask = mask << 1;
i = (opword & mask) >> (reg_num_offset - 2);
sprintf(regnum,"%d",i);
strcat(buf,regnum);
}
static void
append_displacement (char *buf, int extension, int disp_offset)
{
/*
* This function determines and appends a 16 or 32 bit disp.
* The `offsets' are given by the bit number as listed in the
* M68000 Family Programmer's Reference, Chapter 2. [15 .. 0]
*/
int i, mask, disp;
mask = 0x3; /* 2 bits */
for (i = 1; i < disp_offset; i++)
mask = mask << 1;
i = (extension & mask) >> (disp_offset - 1);
switch (i)
{
case 0:
case 1:
break;
case 2:
disp = (int)((SWORD)cpu_read_data((ADDRESS)disasm_pc,16));
inc_disasm_pc(2);
append_value(buf,disp,16);
break;
case 3:
disp = (int)((SLONG)cpu_read_data((ADDRESS)disasm_pc,32));
inc_disasm_pc(4);
append_value(buf,disp,32);
break;
}
}
static void
append_size_scale (char *buf, int extension, int size_offset, int scale_offset)
{
/*
* This function determines the size and scale information
* for addressing modes that require it.
*
* The `offsets' are given by the bit number as listed in the
* M68000 Family Programmer's Reference, Chapter 2. [15 .. 0]
*/
int i, mask, size, scale;
mask = 0x1; /* 1 bits */
for (i = 0; i < size_offset; i++)
mask = mask << 1;
size = (extension & mask) >> size_offset;
mask = 0x3; /* 2 bits */
for (i = 1; i < scale_offset; i++)
mask = mask << 1;
scale = (extension & mask) >> (scale_offset - 1);
if (size)
append_string(buf,".L");
else
append_string(buf,".W");
switch (scale)
{
case 0:
append_string(buf,"*1");
break;
case 1:
append_string(buf,"*2");
break;
case 2:
append_string(buf,"*4");
break;
case 3:
/* valid_instruction = FALSE; */
append_string(buf,"*8");
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -