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

📄 asm.c

📁 motorola自己开发的针对coldfire 5272的Dbug bootloader程序
💻 C
📖 第 1 页 / 共 4 页
字号:
			printf(ERR_OPER,instruct[4]);
			error=FALSE;
			return;
		}
	}
	else
	{
		if ((reg=get_data_register(instruct[4]))==8)			/* Get Rw Destination field */
		{	
			if ((reg=get_addr_register(instruct[4])) != 8)		/* Rw could be an address register */
			{
				opword2  = (uint16)(opword2 | (reg << 12) | 0x8000 );		/* Rw IS an address register */
			}
			else												/* Rw is NOT a data or address register */
			{
				printf(ERR_OPER,instruct[4]);			
				return;
			}													
		}
		else
		{
			opword2 = (uint16)(opword2 | (reg << 12));				/* Rw is a Data register */
		}
	}

/* handle instruct[5] IF !NULL */
	if(instruct[5] != NULL)
	{
		if ((reg=get_data_register(instruct[5]))==8)			/* Get Rw Destination field */
		{	
			if ((reg=get_addr_register(instruct[5])) != 8)		/* Rw could be an address register */
				opword2  = (uint16)(opword2 | (reg << 12) | 0x8000 );		/* Rw IS an address register */
		
			else												/* Rw is NOT a data or address register */
			{
				printf(ERR_OPER,instruct[5]);			
				return;
			}
		}
		else
			opword2 = (uint16)(opword2 | (reg << 12));				/* Rw is a Data register */
	}


	write_data(16,opword);
	handle_ext_words();

}
/****************************************************************/
void
afun30 (int ea_mask, uint16 opword)
{

	/* INTOUCH <Ay> */
	int reg;
	(void) ea_mask;

	if ((reg=get_addr_register(instruct[1])) != 8)		/* Ay could be an address register */
		opword  = (uint16)(opword  | reg);				/* Ay IS an address register */
	else
	{
		printf(ERR_ADDR_REG,instruct[1]);			
		return;
	}

	write_data(16,opword);
	handle_ext_words();


}
/****************************************************************/
void
afun31 (int ea_mask, uint16 opword)
{
	/* MOV3Q #<data>,<ea> */
	/* XXXX|DATa|XXX|MOD|REG    	*/
	uint16 data;
	
	data = (uint16)get_imm_data(instruct[1],0);
	if (!error)
	{
		if (data == 0xffff)
			data = 0;
		else if ((data > 7)||(data == 0 ))
		{
			printf(ERR_OPER,instruct[1]);
			return;
		}
		
		opword = (uint16)(opword | (data << 9));
		afun8b(ea_mask,opword,0);
		
	}
}
/****************************************************************/
void
afun32 (int ea_mask, uint16 opword)
{
	/* MVS <ea>y,Dx */
	/* MVZ <ea>y,Dx */
	/* XXXX|REG|XX|S|MOD|REG    	*/
	
	uint16 ea;
	int reg;
	
	switch (size)
	{
		case 0:
			/* byte-sized input operands */
			break;
		case 1:
			opword = (uint16)(opword | (1 << 6));			/* word-sized input operands */
			break;
		case 2:
		    printf("Invalid size: .B or .W only\n");	/* NO long-sized input operands */
			return;
		default:
			/* default to byte-sized input operands */
			break;
	}

	ea=get_ea(instruct[1],ea_mask,0);
	
	if(!error)
		opword = (uint16)(opword | ea);						
	else
	{
		printf(ERR_OPER,instruct[1]);
		error=FALSE;
		return;
	}
	
	if ((reg=get_data_register(instruct[2])) != 8)		
	opword  = (uint16)(opword  | (reg<<9));				
	else
	{
		printf(ERR_DATA_REG,instruct[2]);			
		return;
	}

	write_data(16,opword);
	handle_ext_words();


}
/****************************************************************/
void
afun33 (int ea_mask, uint16 opword)
{
	/* TAS */
	/* opword: XXXXXXXXXX|MOD|REG	*/

	if((size==1)||(size==2))
	{
		printf("Invalid size: .B  only\n");			/*Byte-sized input operands only*/
		return;
	}
	else
		afun8(ea_mask,opword);

}	
/****************************************************************/
void
afun34 (int ea_mask, uint16 opword)
{
	/* CMPA <ea>,An		 	*/
	/* XXXX|REG|XXXXXX|MOD|REG	*/

	int An;

#if (defined(CPU_MCF5407))

	opword= 0xB000;
	switch (size)
	{
		case 0:
			/* byte */
			printf("Invalid size: .W and .L  only\n");
			return;
		case 1:
			opword = (uint16)(opword | (3 << 6));
			break;
		case 2:
			opword = (uint16)(opword | (7 << 6));
			ext_long_flag=1;
			break;
		default:
			opword = (uint16)(opword | (7 << 6));
			ext_long_flag=1;
			break;
	}
	
	An = get_addr_register(instruct[2]);
	if (!reg_error)
	{
		opword = (uint16)(opword | (An << 9));
		afun8(ea_mask,opword);
	}
	else
		printf(ERR_ADDR_REG,instruct[2]);

#else
	if (size_is_long())
	{
		An = get_addr_register(instruct[2]);
		if (!reg_error)
		{
			ext_long_flag=1;
			opword = (uint16)(opword | (An << 9));
			afun8(ea_mask,opword);
		}
		else
			printf(ERR_ADDR_REG,instruct[2]);
	}
#endif

}
/****************************************************************/
void 
afun35 (int ea_mask, uint16 opword)
{
	/* CMPI #<data>,Dn		     */
#if (defined(CPU_MCF5407))

	opword= 0x0C00;
	switch (size)
	{
		case 0:
			/* byte */
			ext_word = (uint16)get_imm_data(instruct[1],0x0);
			ext_word_flag=1;
			break;
		case 1:
			opword = (uint16)(opword | (1 << 6));
			ext_word = (uint16)get_imm_data(instruct[1],0x0);
			ext_word_flag=1;
			break;
		case 2:
			opword = (uint16)(opword | (1 << 7));
			ext_long = get_imm_data(instruct[1],0x0);
			ext_long_flag=1;
			break;
		default:
			opword = (uint16)(opword | (1 << 7));
			ext_long = get_imm_data(instruct[1],0x0);
			ext_long_flag=1;
			break;
	}
	
	if (!error)
	{
		afun5(ea_mask,opword);
	}

#else
	if (size_is_long())
	{
		ext_long = get_imm_data(instruct[1],0x0);
		if (!error)
		{
			ext_long_flag = 1;
			afun5(ea_mask,opword);
		}
	}
#endif
}	
/****************************************************************/
void 
afun36 (int ea_mask, uint16 opword)
{
	/* DIVS.L DIVU.L DIVS.W DIVU.W*/
	int Dn;
		
	switch (size)
	{
		case 0:
			error = TRUE;
			printf("Invalid size specified:  .W or .L only\n");
			break;
		case 1:
			if (strcasecmp(instruct[0],"DIVS") == 0)
				opword = 0x81C0;
			else 	/* DIVU */
				opword = 0x80C0;

			ea_mask = EA_DATA;
			afun15b(ea_mask,opword,0);
			break;
		case 2:
		default:
			opword = 0x4C40;
			ea_mask = (DRD | ARI | ARIPO | ARIPR | ARID);
			if (strcasecmp(instruct[0],"DIVS") == 0)
				opword2 = 0x0800;
			Dn = get_data_register(instruct[2]);
			if (!reg_error)
			{
				opword2 = (uint16)(opword2 | (Dn << 12) | Dn);
				opword2_flag = 1;
				afun8(ea_mask,opword);
			}
			break;
	}
}	
/****************************************************************/
void 
afun37 (int ea_mask, uint16 opword)
{
	/* REMS.L REMU.L*/
	int Dn,Dw, i;
	
	switch (size)
	{
		case 0:
			error = TRUE;
			printf("Invalid size specified:  .W or .L only\n");
			break;
		case 1:
			error = TRUE;
			printf("Invalid size specified:  .W or .L only\n");
			break;
		case 2:
		default:
			if (strcasecmp(instruct[0],"REMS") == 0)
				opword2 = 0x0800;
		
			for (i=0; (instruct[2][i] != ':') && (instruct[2][i] != '\0') ; i++)
			{}
			
			if (instruct[2][i] == ':') 
			{
				instruct[2][i] ='\0';
				instruct[3]=&instruct[2][i+1];	
			}
			else
			{ 
				/* error there is no ":", no second register!*/
				printf(ERR_OPER,instruct[2]);
				return;
			}


			Dn = get_data_register(instruct[3]);
			if (!reg_error)
			{
				Dw = get_data_register(instruct[2]);
				if (!reg_error)
				{
					opword2 = (uint16)(opword2 | (Dn << 12) | Dw);
					opword2_flag = 1;
					afun8(ea_mask,opword);
				}	
			}
			break;
	}
}	
/****************************************************************/
static int 
check_equ(void)
{	/* Function looks for occurance of 'EQUATE' statement. 
	 * If one is present, the symbol and value are stored 
	 * in the symbol table and a '0' is returned.
	 */
	int value, temp_base, i;

	if ((strcasecmp(instruct[1],"equ") == 0) ||	
	   (instruct[1][0] == '.' && strcasecmp(&instruct[1][1],"equ") == 0))
	{
		if (instruct[2] != NULL)
		{
			check_base(instruct[2], &temp_base);
			value = get_value(instruct[2],&success,temp_base);
			if (success)
			{
        			for (i=1; instruct[0][i] != ':' && instruct[0][i] != '\0'; i++)
        			{}
   				if (instruct[0][i] == ':') 
					instruct[0][i] = '\0';	
				symtab_add (instruct[0],value);
			}
			else
				printf(INVALUE,instruct[0]);
			return 1;  /* found 'equ', get new user_input */
		}
	}
	return 0;	/* no 'equ', user input is an instruction */		
}

#if 0
/****************************************************************/
static void
get_instr (int flag)
{
	/*This do-while loop prints the current address where
	 *an instruction will be written.  It then gets the input
	 *from the user and prompts until it gets a printable
	 *character (ie. not just a CR).  If an EQUATE statement
	 *is present, the value of the symbol is stored in the symbol
	 *table, and the user is prompted again. If the input 'flag' 
	 *is 1, then only one instruction is to be assembled. 
	 */ 

	int num_args = 0;
	switch (flag)
	{
		case 0:
			while (num_args == 0)
			{
				printf("%08lX: ",(ADDRESS)asm_pc);
        			get_history_line(user_input);
				num_args = make_argv(user_input, instruct);
				if (num_args)
					num_args = check_equ();
			}
			return;

		case 1:		/* only one instruction to be assembled */
			return;	
	}
}
#endif

/****************************************************************/
static void
sep_operands (void)
{	/* Fuction parses the operands in instruct[1] and stores the 
	 * source operand in instruct[1] and the destination operand
	 * in instruct[2] (if present). 
	 */ 
	int i,j, parens = 0;

	for (j=1; (instruct[j] != NULL); j++)
	{

		for (i=0; ((instruct[j][i] != ',') || parens) && (instruct[j][i] != '\0'); i++)
		{
			if (instruct[j][i] == '(')
				parens++;
			if (instruct[j][i] == ')')
				parens--;
		}

		if (instruct[j][i] == ',')
		{
        	instruct[j][i] = '\0';
			instruct[j+1] = &instruct[j][i+1];
		}
		else
		instruct[j+1] = NULL;
	}

}   
#if 0
/****************************************************************/
static void
init_globals(void)
{
        error = FALSE;
        opword2 = ext_word = ext_long = 0;
        opword2_flag = ext_word_flag = ext_long_flag = 0;
}
#endif
/****************************************************************/
static void
check_size_and_label(void)
{                        
        int i;
 
        for (i=1; instruct[0][i] != ':' && instruct[0][i] != '\0' && instruct[0][i] != '.'; i++)
        {}
        if (instruct[0][i] == ':')      /* found a label        */
        { 
                instruct[0][i] = '\0';
                symtab_add (instruct[0], asm_pc);
				
				if (instruct[1])
					instruct[0] = instruct[1];
				else 
					instruct[0] = NULL;

				if (instruct[2])
					instruct[1] = instruct[2];
				else 
					instruct[1] = NULL;

                instruct[2] = NULL;
                
				for (i=1; instruct[0][i] != '\0' && instruct[0][i] != '.'; i++)
                {}
        }
        if (instruct[0][i] == '.')
        {
                switch (instruct[0][i+1])
                {
                        case 'b':
                        case 'B':       /*byte*/
                                size = 0;
                                break;
                        case 'w':
                        case 'W':       /*word*/
                                size = 1;
                                break;
                        case 'l':
                        case 'L':       /*long*/
                                size = 2;
                                break;
                        default:
                                error = TRUE;
                                printf("Not a valid ColdFire instruction: %s\n",instruct[0]);
                                break;
                }
                instruct[0][i] = '\0';
        }        
        else
                size = -1; /* no size entered */
}


#if 0
/****************************************************************/
ADDRESS
cpu_asm (ADDRESS ass_addr, int single_isa, char **argv,int offset)
{
        /*
         * This routine assembles ColdFire instructions, and
         * returns when a '.' is entered by the user.  The
         * address where the next instruction can be written
         * is returned.
         */
        int index, opword, done, valid_instruction; 
	extern const int ISASIZE;
        asm_pc = ass_addr;
	if (single_isa)
	{
		for (index=0; argv[index+offset] != NULL; index++)
			instruct[index] = argv[index+offset];
	}
        get_instr(single_isa);
        while (*instruct[0] != '.' && !done)
        {
		init_globals();
		valid_instruction = FALSE;
                check_size_and_label ();
		if (instruct[0] != '\0' && !(error)) /* check to see if only a label was entered */
		{	for (index=0; index < ISASIZE; index++)  /* or false size specifier */
                	{
                        	if ((strcasecmp(instruct[0],isa[index].instruction)) == 0)
                        	{
					valid_instruction = TRUE;
                                	sep_operands ();
					opword = isa[index].match;
					if (isa[index].asm_func)
						isa[index].asm_func(isa[index].ea_mask, opword);
					else
						printf("Assembler operation not found!\n");
                                	break;       
                        	}		    
					   	   		 
                	}         
                	if (!valid_instruction)
                        	printf("Not a valid instruction: %s\n",instruct[0]);
		}
		if (single_isa)
			done = TRUE; 
                get_instr(single_isa);
        }
        return asm_pc;
}        
/****************************************************************/

/********************************************************************/
#else
ADDRESS
cpu_asm (ADDRESS pc, char **args)
{
	int index;
	uint16 opword;
	extern const int ISASIZE;

	error = FALSE;

	for (index = 0; args[index] != NULL; index++)
		instruct[index] = args[index];

	asm_pc = pc;

	/* Is this an equate statement? */
	if (check_equ())
		goto done;

	check_size_and_label();

	/* Go to done if error or only a label was entered */
	if (error || (instruct[0] == '\0'))
		goto done;

	for (index = 0; index < ISASIZE; index++)
	{
		if (strcasecmp(instruct[0], isa[index].instruction) == 0)
		{
			opword2 = 0;
			ext_word = 0;
			ext_long = 0;
			opword2_flag = 0;
			ext_word_flag = 0;
			ext_long_flag = 0;
			opword = isa[index].match;
			sep_operands();
			isa[index].asm_func(isa[index].ea_mask, opword);
			break;
		}
	}

	done:
	if ((index == ISASIZE) || error)
		printf("Error: Invalid instruction: %s\n",instruct[0]);

	return asm_pc;
}
#endif
/********************************************************************/

⌨️ 快捷键说明

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