⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dis_cf.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 5 页
字号:
/*********************************************************************
 *
 * 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 + -