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

📄 dis_68k.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* MC68000 Disassembler:
 *	ELS...
 *	This disassembler is a hack of the mc68dis disassembler.
 *	NOTE: this adds approximately 20K to the size of the monitor.
 *
 *	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
 */

#include "config.h"
#if INCLUDE_DISASSEMBLER
#include "cpu.h"
#include "ctype.h"
#include "genlib.h"
#include "stddefs.h"
#include "warmstart.h"

#define NULL 0

#define	BIT3(x)	(int)((x >> 3) & 0x1L)	/* ----x--- bit 3 */
#define	BIT5(x)	 (int)((x >> 5) & 0x1L)	/* --x----- bit 5 */
#define	BIT6(x)	 (int)((x >> 6) & 0x1L)	/* -x------ bit 6 */
#define	BIT7(x)	 (int)((x >> 7) & 0x1L)	/* x------- bit 7 */
#define BIT8(x)	(int)((x >> 8) & 0x1L)
#define BIT10(x) (int)((x >> 10) & 0x1L)
#define BIT11(x) (int)((x >> 11) & 0x1L)
#define BIT12(x) (int)((x >> 12) & 0x1L)
#define BIT15(x) (int)((x >> 15) & 0x1L)
#define	BITS15_8(x) (int)((x >> 8) & 0xffL)	
#define BITS15_7(x) (int)((x >> 7) & 0x1ffL)
#define BITS14_12(x) (int)((x >> 12) & 0x7L)
#define	BITS11_9(x) (int)((x >> 9) & 0x7L)	/* bits 11 through 9 */
#define	BITS11_8(x) (int)((x >> 8) & 0xfL)	/* bits 11 through 8 */
#define	BITS10_9(x) (int)((x >> 9) & 0x3L)	/* bits 10 through 9 */
#define	BITS10_8(x) (int)((x >> 8) & 0x7L)	/* bits 10 through 8 */
#define	BITS8_6(x) (int)((x >> 6) & 0x7L)	/* bits 8 through 6 */
#define BITS8_3(x) (int)((x >> 3) & 0x3fL)	/* bits 8 through 3 */
#define	BITS7_6(x) (int)((x >> 6) & 0x3L)	/* bits 7 through 6 */
#define	BITS5_4(x) (int)((x >> 4) & 0x3L)	/* bits 5 through 4 */
#define	BITS5_3(x) (int)((x >> 3) & 0x7L)	/* bits 5 through 3 */
#define	BITS5_0(x) (int)(x & 0x3fL)		/* bits 5 through 0 */
#define	BITS4_3(x) (int)((x >> 3) & 0x3L)	/* bits 4 through 3 */
#define	BITS3_0(x) (int)(x & 0xfL)		/* bits 3 through 0 */
#define	BITS2_0(x) (int)(x & 0x7L)		/* bits 2 through 0 */
#define	LOW8(x) (int)(x & 0xffL)		/* low 8 bits of quantity	*/
#define HIOF32(x) (int)((x >> 31) & 0x1L)	/* sign bit of 32 bit quantity	*/
#define	HI4OF16(x) (int)((x >> 12) & 0xfL)

#define	NCPS	8	/* Number of chars per symbol.		*/
#define	NHEX	80	/* Maximum # chars in object per line.	*/
#define	NLINE	33	/* Maximum # chars in mnemonic per line.*/
#define	FAIL	0
#define	LEAD	1
#define	NOLEAD	0
#define	TERM	0

#define	BYTE	1	 /* values for size parm to eff_add */
#define	WORD	2
#define	LONG	3

#define	SIGNED		1 /* immediate value signed or unsigned */
#define	UNSIGNED	0
#define	NOTSIGNED	0

unsigned short curinstr;	/* for saving first part of instruction
				   when cur2bytes is used to read displ */
unsigned short oldinstr = 0;	/* to save previous instruction for
				   testing that swbeg follows jump	*/


unsigned short	cur2bytes;	/* for storing the results of 'get2bytes()' */

static int	shownext;
static long	loc;		/* byte location being disassembled */
/* IMPORTANT: remember that loc is incremented*/
/* only by the getbyte routine	*/
static char	object[NHEX];	/* array to store object code for output*/
static char	mneu[NLINE];	/* array to store mnemonic code for output*/

char	conv_temp[NHEX];	/* Temporary location for ascii	*/
/* representation of operands.	*/

char	comp_temp[NHEX];	/* temp for calling compoff	*/

static char	size[] = {
	'b','w','l'};

char	*cond_codes[] = {
			"t      ",	"f      ",	"hi     ",	"ls     ",
			"cc     ",	"cs     ",	"ne     ",	"eq     ",
			"vc     ",	"vs     ",	"pl     ",	"mi     ",
			"ge     ",	"lt     ",	"gt     ",	"le     "
		};

char 	*addregs[] = { 
	"%a0","%a1","%a2","%a3","%a4","%a5","%fp","%sp" };

void	confused();
char	*eff_add();
void	bit_movep_imm(), move_byte(), move_long(), move_word(), miscell();
void	addq_subq_scc_dbcc(), bcc_bsr_bra(), moveq(), or_div_sbcd(), sub_subx();
void	unassigned(), cmp_eor(), and_mul_abcd_exg(), add_addx(), shft_rot();

void (*code_map[16])() =
{
		bit_movep_imm,		/* upper nibble 0x0 */
		move_byte,		/* upper nibble 0x1 */
		move_long,		/* upper nibble 0x2 */
		move_word,		/* upper nibble 0x3 */
		miscell,		/* upper nibble 0x4 */
		addq_subq_scc_dbcc, 	/* upper nibble 0x5 */
		bcc_bsr_bra,		/* upper nibble 0x6 */
		moveq,			/* upper nibble 0x7 */
		or_div_sbcd,		/* upper nibble 0x8 */
		sub_subx,		/* upper nibble 0x9 */
		unassigned,		/* upper nibble 0xa */
		cmp_eor,		/* upper nibble 0xb */
		and_mul_abcd_exg,	/* upper nibble 0xc */
		add_addx,		/* upper nibble 0xd */
		shft_rot,		/* upper nibble 0xe */
		unassigned		/* upper nibble 0xf */
};

char *DisHelp[] = {
	"Disassemble memory",
	"{address | .} [lines]",
	0,
};

extern int getreg();

/* ELS: With the original disassembler, it attempted to recover from 
	a confused state by re-syncing on the next line of source.
*/
void
confused()
{
	printf("\tDisassembler confused around 0x%lx\n",loc);
	monrestart(MISC);
}

/*
 *	compoff (lng, temp)
 *
 *	This routine will compute the location to which control is to be
 *	transferred.  'lng' is the number indicating the jump amount
 *	(already in proper form, meaning masked and negated if necessary)
 *	and 'temp' is a character array which already has the actual
 *	jump amount.  The result computed here will go at the end of 'temp'.
 *	(This is a great routine for people that don't like to compute in
 *	hex arithmetic.)
 */

void
compoff(long lng, char *temp)
{
	extern	long	loc;	/* from _extn.c */

	lng += loc;
	sprintf(temp,"%s <%lx>",temp,lng);
}


/*
 *	convert (num, temp, flag)
 *
 *	Convert the passed number to hex leaving the result in the
 *	supplied string array.
 *	If  LEAD  is specified, preceed the number with '0' or '0x' to
 *	indicate the base (used for information going to the mnemonic
 *	printout).  NOLEAD  will be used for all other printing (for
 *	printing the offset, object code, and the second byte in two
 *	byte immediates, displacements, etc.) and will assure that
 *	there are leading zeros.
 */

void
convert(num,temp,flag)
unsigned int	num;
char temp[];
int	flag;
{
	if (flag == NOLEAD)
		sprintf(temp,"%04x",num);
	if (flag == LEAD)
		sprintf(temp,"0x%x",num);
}

/*
 *	get2bytes()
 *
 *	This routine will get 2 bytes, print them in the object file
 *	and place the result in 'cur2bytes'.
 *
 */

void
get2bytes()
{
	uchar bytes[16], *bc;

	bc = (uchar *)loc;
	bytes[0] = bc[0];
	bytes[1] = bc[1];
	cur2bytes = *(unsigned short *)loc;
	loc += 2;
	convert( (cur2bytes & 0xffff), bytes, NOLEAD);
	sprintf(object,"%s%s ",object, bytes);
}

/*
 *	print_dis ()
 *
 *	Print the disassembled line, consisting of the object code
 *	and the mnemonics.  The breakpointable line number, if any,
 *	has already been printed, and 'object' contains the offset
 *	within the section for the instruction.
 */

void
print_dis()
{
	printf("%-35s%s\n",object,mneu);
}

/*
 *	prt_offset ()
 *
 *	Print the offset, right justified, followed by a ':'.
 */
void
prt_offset()
{
	if (shownext)
		strcpy(object,"NextInst: ");
	else
		sprintf(object,"0x%08lx: ",loc);
}

int
disass(ulong at,int lines,int next)
{
	int	i;
	ulong	start;

	shownext = next;

	if ((at == 0) && (lines == 0)) {
		lines = 1;
		getreg("PC",&loc);
		start = loc;
	}
	else {
		loc = at;
		start = at;
	}

	for(i=0;i<lines;i++) {
		prt_offset();
		mneu[0] = '\0';
		oldinstr = curinstr;
		get2bytes();
		/*save bytes in case eff_add changes it*/
		curinstr = cur2bytes;
		comp_temp[0] = '\0';
		(*code_map[HI4OF16(cur2bytes)])();
		/* if there was any pc rel computation 
				   put it at the end of assembly line */
		strcat(mneu,comp_temp);
		print_dis();
	}
	return((int)loc - start);
}

int
Dis(int argc,char *argv[])
{
	int lines;
	ulong	at;

	if (*argv[1] == '.')
		getreg("PC",&at);
	else
		at = strtoul(argv[1],0,0);

	if (argc == 3)
		lines = strtol(argv[2],0,0);
	else
		lines = 8;

	while(1) {
		disass(at,lines,0);
		if (More())
			at = loc;
		else
			break;
	}
	return(0);
}

void
move_address()
{
	strcat(mneu,"mova._  ");
	mneu[5] = BIT12(cur2bytes) ? 'w' : 'l';
	strcat(mneu,eff_add(BITS5_3(cur2bytes),BITS2_0(cur2bytes),
	    BIT12(cur2bytes) ? WORD : LONG,NOTSIGNED));
	sprintf(mneu,"%s,%s",mneu,addregs[BITS11_9(curinstr)]);
}

void
bit_movep_imm()
{
	static char *misc_ops[4] = {
					"btst    ",
					"bchg    ",
					"bclr    ",
					"bset    "
					};
	if (BIT8(cur2bytes)) {
		if (BITS5_3(cur2bytes) == 1) {	/* movep */
			strcat(mneu,"movp._  ");
			mneu[5] = BIT6(cur2bytes) ? 'l' : 'w';
			if (BIT7(cur2bytes))
				sprintf(mneu,"%s%%d%d,%s",mneu,
				    BITS11_9(curinstr),
				    eff_add(5,BITS2_0(cur2bytes),
				    NULL,NULL));
				else
				sprintf(mneu,"%s%s,%%d%d",mneu,
				    eff_add(5,BITS2_0(cur2bytes),NULL,
				    NULL), BITS11_9(curinstr));
		}
		else {	/* dynamic bit */
			strcat(mneu,misc_ops[BITS7_6(cur2bytes)]);
			sprintf(mneu,"%s%%d%d,%s",mneu,BITS11_9(curinstr),
			    eff_add(BITS5_3(cur2bytes),BITS2_0(cur2bytes),
			    NULL,NULL));
		}
		return;
	} /* end if (BIT8(cur2bytes)) */
	switch(BITS11_9(cur2bytes)) {
		char add_temp[16];
	case 0:
		if (BITS7_6(cur2bytes) == 3)
			confused();
		strcat(mneu,"ori._   ");
		mneu[4] = size[BITS7_6(cur2bytes)];
		strcat(mneu,eff_add(7,4,BITS7_6(cur2bytes) + 1,UNSIGNED));
		strcat(mneu,",");
		if (BITS5_0(curinstr) == 074) {
			if (BITS7_6(curinstr) == 0)
				strcat(mneu,"%cc");
			else if (BITS7_6(curinstr) == 1)
				strcat(mneu,"%sr");
				else
				confused();
		}
		else
			strcat(mneu,eff_add(BITS5_3(curinstr),
			    BITS2_0(curinstr),NULL,NULL));
		return;
	case 1:
		if (BITS7_6(cur2bytes) == 3)
			confused();
		strcat(mneu,"andi._  ");
		mneu[5] = size[BITS7_6(cur2bytes)];
		strcat(mneu,eff_add(7,4,BITS7_6(cur2bytes) + 1,UNSIGNED));
		strcat(mneu,",");
		if (BITS5_0(curinstr) == 074) {
			if (BITS7_6(curinstr) == 0)
				strcat(mneu,"%cc");
			else if (BITS7_6(curinstr) == 1)
				strcat(mneu,"%sr");
				else
				confused();
		}
		else
			strcat(mneu,eff_add(BITS5_3(curinstr),
			    BITS2_0(curinstr),NULL,NULL));
		return;
	case 2:
		if ((BITS7_6(cur2bytes) == 3) || (BITS5_0(cur2bytes) == 074))
			confused();
		strcat(mneu,"subi._  ");
		mneu[5] = size[BITS7_6(cur2bytes)];
		strcat(mneu,eff_add(7,4,BITS7_6(cur2bytes) + 1,UNSIGNED));
		strcat(mneu,",");
		strcat(mneu,eff_add(BITS5_3(curinstr),BITS2_0(curinstr),
		    NULL,NULL));
		return;
	case 3:
		if ((BITS7_6(cur2bytes) == 3) || (BITS5_0(cur2bytes) == 074))
			confused();
		strcat(mneu,"addi._  ");
		mneu[5] = size[BITS7_6(cur2bytes)];
		strcat(mneu,eff_add(7,4,BITS7_6(cur2bytes) + 1,UNSIGNED));
		strcat(mneu,",");
		strcat(mneu,eff_add(BITS5_3(curinstr),BITS2_0(curinstr),
		    NULL,NULL));
		return;
	case 4:
		strcat(mneu,misc_ops[BITS7_6(cur2bytes)]);
		strcat(mneu,eff_add(7,4,(BITS7_6(cur2bytes) ==1) ?
		    BYTE : WORD,UNSIGNED));
		strcat(mneu,",");
		strcat(mneu,eff_add(BITS5_3(curinstr),
		    BITS2_0(curinstr),NULL,NULL));
		return;
	case 5:
		if (BITS7_6(cur2bytes) == 3)
			confused();
		strcat(mneu,"eori._   ");
		mneu[5] = size[BITS7_6(cur2bytes)];
		strcat(mneu,eff_add(7,4,BITS7_6(cur2bytes) + 1,UNSIGNED));
		strcat(mneu,",");
		if (BITS5_0(curinstr) == 074) {
			if (BITS7_6(curinstr) == 0)
				strcat(mneu,"%cc");
			else if (BITS7_6(curinstr == 1))
				strcat(mneu,"%sr");
				else
				confused();
		}
		else
			strcat(mneu,eff_add(BITS5_3(curinstr),
			    BITS2_0(curinstr),NULL,NULL));
		return;
	case 6:
		if ((BITS7_6(cur2bytes) == 3) || (BITS5_0(cur2bytes) == 074))
			confused();
		strcat(mneu,"cmpi._  ");
		mneu[5] = size[BITS7_6(cur2bytes)];
		strcpy(add_temp,eff_add(7,4,BITS7_6(cur2bytes)+1,NOTSIGNED));
		strcat(mneu,eff_add(BITS5_3(curinstr),BITS2_0(curinstr),
		    NULL,NULL));
		strcat(mneu,",");
		strcat(mneu,add_temp);
		return;
#ifdef M68010
	case 7:
		{
			short osz, regtype, regnum, movsdir;
			char  curea[24], rreg[6];
			short ea1, eareg;
			osz = BITS7_6(cur2bytes);
			if (osz == 3)
				confused();
			ea1 = BITS5_3(cur2bytes);
			eareg = BITS2_0(cur2bytes);
			strcat(mneu,"movs.");
			strcat(mneu,(osz==2)?("l"):( (osz==1)?("w"):("b") ));
			strcat(mneu,"  ");
			get2bytes();
			movsdir = BIT11(cur2bytes);
			regtype = BIT15(cur2bytes);
			regnum  = BITS14_12(cur2bytes);
			strcpy(curea,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -