📄 asm.c
字号:
printf(ERR_DATA_REG,instruct[2]);
}
}
/****************************************************************/
void
afun23 (int ea_mask, uint16 opword)
{
/* ADDX, SUBX */
/* ADDX Dx,Dy */
int Dx, Dy;
(void)ea_mask;
if (size_is_long())
{
if ((Dx = get_data_register(instruct[1])) != 8)
{
if ((Dy = get_data_register(instruct[2])) != 8)
{
opword = (uint16)(opword | (Dy << 9) | Dx);
write_data(16,opword);
}
else
printf(ERR_DATA_REG,instruct[2]);
}
else
printf(ERR_DATA_REG,instruct[1]);
}
}
/****************************************************************/
static uint16
get_reg_list (char *user_list)
{
/* returns Register List Mask Field if a register list is present, */
/* success is FALSE if user_list is not a list of registers */
/* error is TRUE if list is of the wrong format */
/* list format: D0-D2/D4/D7/A1-A2/A7 etc. */
uint16 list = 0;
int i, j, Rn, Rt;
if (((get_data_register(user_list)) == 8) &&
((get_addr_register(user_list)) == 8))
{
success = FALSE;
return 0;
}
else
{
i = 0;
while(user_list[i] != '\0')
{
if ((Rn = get_data_register(&user_list[i])) != 8)
{ /* Rn = Rn + 0; */ }
else if ((Rn = get_addr_register(&user_list[i])) != 8)
Rn = Rn + 8;
else
{
user_list[i+2] = '\0';
printf("Invalid register entry: %s\n", &user_list[i]);
error = TRUE;
return 0;
}
list = (uint16)(list | (1 << Rn));
i += 2;
switch (user_list[i])
{
case '/':
i++;
break;
case '-':
i++;
if ((Rt = get_data_register(&user_list[i])) != 8)
{ /* Rt = Rt + 0; */ }
else if ((Rt = get_addr_register(&user_list[i])) != 8)
Rt = Rt + 8;
else
{
user_list[i+2] = '\0';
printf("Invalid register entry: %s\n", &user_list[i]);
error = TRUE;
return 0;
}
for (j = ++Rn; j <= Rt; j++)
{
list = (uint16)(list | (1 << j));
}
i+=2;
switch (user_list[i])
{
case '/':
i++;
break;
case '\0':
break;
default:
printf("Invalid list format: %s\n",user_list);
error = TRUE;
return 0;
}
break;
case '\0':
break;
default:
printf("Invalid list format: %s\n",user_list);
error = TRUE;
return 0;
}
}
return list;
}
}
/****************************************************************/
void
afun24 (int ea_mask, uint16 opword)
{
/* MOVEM <ea>,<list> */
/* MOVEM <list>,<ea> */
if (size_is_long())
{
success = TRUE;
opword2 = get_reg_list(instruct[1]);
if (success && !error)
{
opword2_flag = 1;
afun8b(ea_mask,opword,0);
}
else if (!success)
{
success = TRUE;
opword2 = get_reg_list(instruct[2]);
opword2_flag = 1;
if (!success)
{
printf("No valid register list was entered\n");
return;
}
if (error)
return;
opword = (uint16)(opword | 0x400); /* memory to register: dr=1 */
afun8(ea_mask,opword);
}
}
}
/****************************************************************/
void
afun25 (int ea_mask, uint16 opword)
{
/* MOVEC Rn,Rc */
int Rn, Rc;
(void)ea_mask;
/* control registers are write-only: dr=1 */
opword = (uint16)(opword | 0x0001);
if ((Rn = get_data_register(instruct[1])) != 8)
/* Rn = Rn | 0 */;
else if ((Rn = get_addr_register(instruct[1])) != 8)
Rn = Rn | 0x8;
else
{
printf("Not a vaild register: %s\n",instruct[1]);
return;
}
/*
* FIX !!!!!!! Just change to examine all currently defined Rc
* Do not check processor against Rc
*/
if (strcasecmp(instruct[2],"VBR") == 0)
Rc = 0x801;
#if (defined(CPU_FAM_MCF5XXX))
else if (strcasecmp(instruct[2],"CACR") == 0)
Rc = 0x002;
#endif
#if 0
else if (strcasecmp(instruct[2],"TCR") == 0)
Rc = 0x003;
else if (strcasecmp(instruct[2],"ACR2") == 0)
Rc = 0x???;
else if (strcasecmp(instruct[2],"ACR3") == 0)
Rc = 0x???;
#endif
#if (defined(CPU_FAM_MCF5XXX))
else if (strcasecmp(instruct[2],"ACR0") == 0)
Rc = 0x004;
else if (strcasecmp(instruct[2],"ACR1") == 0)
Rc = 0x005;
#endif
#if (defined(CPU_FAM_MCF5XXX))
else if (strcasecmp(instruct[2],"ROMBAR") == 0)
Rc = 0xC00;
else if ((strcasecmp(instruct[2],"RAMBAR0") == 0) ||
(strcasecmp(instruct[2],"RAMBAR") == 0) ||
(strcasecmp(instruct[2],"SRAMBAR") == 0))
Rc = 0xC04;
#endif
#if 0
else if (strcasecmp(instruct[2],"RAMBAR1") == 0)
Rc = 0xC05;
#endif
#if (defined(CPU_FAM_MCF5XXX))
else if (strcasecmp(instruct[2],"MBAR") == 0)
Rc = 0xC0F;
#endif
else
{
printf("Invalid control register: %s\n",instruct[2]);
return;
}
ext_word = (uint16)(Rc | (Rn << 12));
ext_word_flag = 1;
write_data(16,opword);
handle_ext_words();
}
/****************************************************************/
void
afun26 (int ea_mask, uint16 opword)
{ /* MOVE's */
uint16 d_ea, s_ea, reg, mod, temp, temp_flag;
temp = temp_flag = 0;
if (strcasecmp(instruct[1],"SR") == 0) /* MOVE from SR */
{
opword = 0x40C0;
afun5b(ea_mask,opword);
}
#ifdef CPU_FAM_MCF5XXXM
/* if there is a MAC define the MAC move instructions */
else if((strcasecmp(instruct[1],"MACSR") == 0)&& /* MOVE MACSR to CCR */
(strcasecmp(instruct[2],"CCR" ) == 0)) /* This needs to be before */
{ /* "Move to CCR" & "Move from MCASR" */
opword = 0xA9C0; /* !MAC!*/
write_data(16,opword);
}
else if (strcasecmp(instruct[1],"ACC") == 0) /* MOVE from ACC !MAC!*/
{
opword = 0xA180;
afun5b(ea_mask,opword);
}
else if (strcasecmp(instruct[1],"MACSR") == 0) /* MOVE from MACSR !MAC!*/
{
opword = 0xA980;
afun5b(ea_mask,opword);
}
else if (strcasecmp(instruct[1],"MASK") == 0) /* MOVE from MASK !MAC!*/
{
opword = 0xAD80;
afun5b(ea_mask,opword);
}
else if (strcasecmp(instruct[2],"ACC") == 0) /* MOVE to ACC !MAC!*/
{
ea_mask = (DRD | ARD | IM);
opword = 0xA100;
ext_long_flag = 1;
afun8(ea_mask,opword);
}
else if (strcasecmp(instruct[2],"MACSR") == 0) /* MOVE to MACSR !MAC!*/
{
ea_mask = (DRD | ARD | IM);
opword = 0xA900;
ext_long_flag = 1;
afun8(ea_mask,opword);
}
else if (strcasecmp(instruct[2],"MASK") == 0) /* MOVE to MASK !MAC!*/
{
ea_mask = (DRD | ARD | IM);
opword = 0xAD00;
ext_long_flag = 1;
afun8(ea_mask,opword);
}
#endif /* CPU_FAM_MCF5XXXM */
else if (strcasecmp(instruct[1],"CCR") == 0) /* MOVE from CCR */
{
opword = 0x42C0;
afun5(ea_mask,opword);
}
else if (strcasecmp(instruct[2],"SR") == 0) /* MOVE to SR */
{
ea_mask = (DRD | IM);
opword = 0x46C0;
ext_long_flag = 1;
afun8(ea_mask,opword);
}
else if (strcasecmp(instruct[2],"CCR") == 0) /* MOVE to CCR */
{
ea_mask = (DRD | IM);
opword = 0x44C0;
ext_long_flag = 1;
afun8(ea_mask,opword);
}
else
{
/* MOVE.L requires long extension word in immediate mode */
/* May have to force ext_word to be ext_long */
if (size == 2)
s_ea = get_ea(instruct[1],EA_ALL,1);
else
s_ea = get_ea(instruct[1],EA_ALL,0);
if (!error)
{ /* from table on p. 4-55 programmer's reference */
if (addr_mode & (DRD | ARD | ARI | ARIPO | ARIPR))
ea_mask = (DRD | ARD | ARI | ARIPO | ARIPR | ARID \
| ARII8 | AS | AL);
#ifdef CPU_MCF5407
if (addr_mode & (ARID | PCID ))
ea_mask = (DRD | ARD | ARI | ARIPO | ARIPR | ARID);
if (addr_mode & IM)
{
if(size==2) /*longword .l */
ea_mask = (DRD | ARD | ARI | ARIPO | ARIPR);
else
ea_mask = (DRD | ARD | ARI | ARIPO | ARIPR | ARID);
}
if (addr_mode & (ARII8 | PCII8 | AS | AL))
ea_mask = (DRD | ARD | ARI | ARIPO | ARIPR);
#else
if (addr_mode & (ARID | PCID))
ea_mask = (DRD | ARD | ARI | ARIPO | ARIPR | ARID);
if (addr_mode & (ARII8 | PCII8 | AS | AL | IM))
ea_mask = (DRD | ARD | ARI | ARIPO | ARIPR);
#endif /* CPU_MCF5407*/
/* second operand may require extension word also */
if (ext_word_flag)
{
temp = ext_word;
temp_flag = 1;
ext_word_flag = 0;
}
d_ea = get_ea(instruct[2],ea_mask,0);
if (!error)
{
reg = (uint16)(d_ea & 0x7);/* dest. mode and reg are swapped */
mod = (uint16)(d_ea >> 3); /* for the move command */
d_ea = (uint16)((reg << 3) | mod);
switch(size) /*size field specified on pg. 4-53 of PRM */
{
case 0: /* MOVE Byte = 0001 */
size = 1;
break;
case 1: /* MOVE uint16 = 0011 */
size = 3;
break;
case 2: /* MOVE uint32 = 0010 */
size = 2;
break;
default:
error = TRUE;
printf("What size?\n");
return;
}
opword = (uint16)((size << 12) | (d_ea << 6) | s_ea);
/*if both operands require extension words*/
if (ext_word_flag && temp_flag)
{
ext_long = (uint32)((temp << 16) | ext_word);
ext_long_flag = 1;
ext_word_flag = 0;
}
else if (temp_flag)
{
ext_word_flag = 1;
ext_word = temp;
}
write_data(16,opword);
handle_ext_words();
}
}
}
}
/****************************************************************/
void
afun27 (int ea_mask, uint16 opword)
{
/* DC.W DC.L */
uint32 opcode;
(void)ea_mask;
(void)opword;
opcode = (uint32) get_value(instruct[1],&success,BASE);
if (success == 0)
{
printf(INVALUE,instruct[1]);
return;
}
switch (size)
{
case 0x0:
printf("Invalid size: .W or .L only\n");
return;
case 0x1:
write_data(16,opcode);
return;
case 0x2:
write_data(32,opcode);
return;
}
}
/****************************************************************/
void
afun28 (int ea_mask, uint16 opword)
{
/* MAC.W MAC.L */
/* MSAC.W MSAC.L */
int reg;
(void) ea_mask;
opword2_flag = 1; /* tell handle_ext_words() that there is a second opword*/
if(strcasecmp(instruct[0],"MSAC")==0)
opword2 = (uint16)(opword2 | (1 << 8));
switch (size)
{
case 0:
printf("Invalid size: .W or .L only\n"); /* byte-sized input operands not allowed */
return;
case 1:
opword2 = (uint16)(opword2 | (0 << 11)); /* word-sized input operands */
break;
case 2:
opword2 = (uint16)(opword2 | (1 << 11)); /* long-sized input operands */
break;
default:
opword2 = (uint16)(opword2 | (1 << 11)); /* default to long-sized input operands */
break;
}
get_word_select(1);
if ((reg=get_data_register(instruct[1]))==8) /* Get Source Y word Select field */
{
if ((reg=get_addr_register(instruct[1])) != 8) /* Ry could be an address register */
{
opword = (uint16)(opword | (reg<<9) | 0x40 ); /* Ry IS an address register */
opword2 = (uint16)(opword2 | (word_sel << 7)); /* Set Source Y word Select field */
}
else
{
printf(ERR_REG,instruct[1]); /* Ry is NOT a data or address register */
return;
}
}
else
{
opword = (uint16)(opword | (reg <<9)); /* Ry is a Data register */
opword2 = (uint16)(opword2 | (word_sel << 7)); /* Set Source Y word Select field */
}
get_word_select(0x02);
if ((reg=get_data_register(instruct[2]))==8) /* Get Source X word Select field */
{
if ((reg=get_addr_register(instruct[2])) != 8) /* Ry could be an address register */
{
opword = (uint16)(opword | (reg) | 0x8 ); /* Ry IS an address register */
opword2 = (uint16)(opword2 | (word_sel << 6)); /* Set Source X word Select field */
}
else
{
printf(ERR_REG,instruct[2]); /* Ry is NOT a data or address register */
return;
}
}
else
{
opword = (uint16)(opword | (reg)); /* Ry is a Data register */
opword2 = (uint16)(opword2 | (word_sel << 6)); /* Set Source X word Select field */
}
if(instruct[3] != NULL)
{
if((strcasecmp(instruct[3],"<<")==0)||(strcasecmp(instruct[3],"<<1")==0))
{
opword2 = (uint16)(opword2 | (1 << 9)); /* append product<<1 to Scale Factor Field */
}
else if((strcasecmp(instruct[3],">>")==0)||(strcasecmp(instruct[3],">>1")==0))
{
opword2 = (uint16)(opword2 | (3 << 9)); /* append product>>1 to Scale Factor Field */
}
else
{
printf(ERR_OPER,instruct[3]);
return;
}
}
write_data(16,opword);
handle_ext_words();
}
/****************************************************************/
void
afun29 (int ea_mask, uint16 opword)
{
/* MACL.W MACL.L */
/* MSACL.W MSACL.L */
int reg,i;
int fiveoperands;
uint16 ea;
opword2_flag = 1; /* tell handle_ext_words() that there is a second opword*/
fiveoperands=FALSE;
if(strcasecmp(instruct[0],"MSACL")==0)
opword2 = (uint16)(opword2 | (1 << 8));
switch (size)
{
case 0:
printf("Invalid size: .W or .L only\n"); /* byte-sized input operands not allowed */
return;
case 1:
opword2 = (uint16)(opword2 | (0 << 11)); /* word-sized input operands */
break;
case 2:
opword2 = (uint16)(opword2 | (1 << 11)); /* long-sized input operands */
break;
default:
opword2 = (uint16)(opword2 | (1 << 11)); /* default to long-sized input operands */
break;
}
get_word_select(0x01);
if ((reg=get_data_register(instruct[1]))==8) /* Get Source Y field */
{
if ((reg=get_addr_register(instruct[1])) != 8) /* Ry could be an address register */
{
opword = (uint16)(opword | (reg<<9) | 0x40 ); /* Ry IS an address register */
opword2 = (uint16)(opword2 | (word_sel << 7)); /* Set Source Y field */
}
else
{
printf(ERR_REG,instruct[1]); /* Ry is NOT a data or address register */
return;
}
}
else
{
opword = (uint16)(opword | (reg <<9)); /* Ry is a Data register */
opword2 = (uint16)(opword2 | (word_sel << 7)); /* Set Source Y word select field */
}
get_word_select(0x02);
if ((reg=get_data_register(instruct[2]))==8) /* Get Source X field */
{
if ((reg=get_addr_register(instruct[2])) != 8) /* Rx could be an address register */
{
opword2 = (uint16)(opword2 | (reg) | 0x8 ); /* Rx IS an address register */
opword2 = (uint16)(opword2 | (word_sel << 6)); /* Set Source X field */
}
else
{
printf(ERR_REG,instruct[2]); /* Rx is NOT a data or address register */
return;
}
}
else
{
opword2 = (uint16)(opword2 | (reg)); /* Rx is a Data register */
opword2 = (uint16)(opword2 | (word_sel << 6)); /* Set Source X word select field */
}
/* handle instruct[3] */
if (((strcasecmp(instruct[3],"<<")==0)||(strcasecmp(instruct[3],"<<1")==0)))
{
opword2 = (uint16)(opword2 | (0x01 << 9)); /* instruction 3 is a >> shift */
fiveoperands=TRUE;
}
else if (((strcasecmp(instruct[3],">>")==0)||(strcasecmp(instruct[3],">>1")==0)))
{
opword2 = (uint16)(opword2 | (0x03 << 9)); /* instruction 3 is a >> shift */
fiveoperands=TRUE;
}
else
{
ea=get_ea(instruct[3],ea_mask,0);
if(!error)
opword = (uint16)(opword | ea); /* instruction 3 is an effective address */
else
{
printf(ERR_OPER,instruct[3]);
error=FALSE;
return;
}
}
/* handle instruct[4]*/
for (i=1; instruct[4][i] != '&' && instruct[4][i] != '\0' ; i++) /* Strip off the "&" if it is there */
{}
if(instruct[4][i]=='&')
{
instruct[4][i]='\0';
opword2 = (uint16)(opword2 | (0x1 <<5));
}
if(fiveoperands) /* operand 4 must be an effective address */
{
ea=get_ea(instruct[4],ea_mask,0);
if(!error)
opword = (uint16)(opword | ea); /* instruction 3 is an effective address */
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -