📄 asm.c
字号:
temp = get_value(strg[0],&success,temp_base);
/* 8-bit */
if (success && temp >= -128 && temp <= 127)
{
ext_word_flag = 1;
ext_word = (uint16)(temp & 0x00FF);
if ((*reg2 = get_data_register(strg[2])) != 8)
temp = 0x0; /* write Data bit */
else if ((*reg2 = get_addr_register(strg[2])) != 8)
temp = 0x8000; /* write Addr bit */
else
{
error = TRUE;
return 0;
}
ext_word = (uint16)(ext_word | temp | (*reg2 << 12) | 0x800);
strg[2] = &strg[2][2];
if (strg[2][0] == '.')
{
switch (strg[2][1])
{
case 'L':
case 'l':
/* wrote .L above with XXX | 0x800; */
break;
default:
error = TRUE;
return 0;
}
strg[2] = &strg[2][2];
}
if (strg[2][0] == '*')
{
switch (strg[2][1])
{
case '1':
break;
case '2':
ext_word = ext_word | 0x200;
break;
case '4':
ext_word = ext_word | 0x400;
break;
case '8':
ext_word = ext_word | 0x600;
break;
default:
error = TRUE;
return 0;
}
strg[2] = &strg[2][2];
}
if (strg[2][0] != NULL)
{
error = TRUE;
return 0;
}
return 1;
}
}
}
return 0;
}
/****************************************************************/
static int
parse_operand (char *temp[], char *raw)
{
int i, j, parens;
i = j = parens = 0;
temp[0] = raw;
temp[1] = temp [2] = NULL;
if (raw[0] == '(')
{
temp[0] = &raw[1];
parens++;
i++;
}
while (raw[i] != NULL)
{
if (raw[i] == '(' || raw[i] == ',' || raw[i] == ')')
{
j++;
if (raw[i] == '(')
parens++;
if (raw[i] == ')')
parens--;
raw[i] = NULL;
temp[j] = &raw[i+1];
}
i++;
}
if (parens != 0)
return 0;
else
return 1;
}
/****************************************************************/
static uint16
get_ea (char *operand, int ea_mask, int force_long)
{
uint16 ea;
int reg, reg2, mode;
char *tstr[3], raw[MAX_OPERAND];
strcpy(raw,operand);
if (is_DRD(®, &mode, raw))
{}
else if (is_ARD(®, &mode, raw))
{}
else if (is_ARI(®, &mode, raw))
{}
else if (is_ARIPO(®, &mode, raw))
{}
else if (is_ARIPR(®, &mode, raw))
{}
else if (is_IM(®, &mode, raw))
{
if (force_long && ext_word_flag)
{
ext_long_flag = 1;
ext_long = (uint32) ext_word;
ext_word_flag = 0;
}
}
else if (is_AS_AL(®, &mode, raw))
{}
else /* Must seperate the operand */
{
if (parse_operand(tstr, raw))
{
if (is_ARID_PCID(®, &mode, tstr))
{}
else if (is_ARII8_PCII8(®, ®2, &mode, tstr))
{}
else
{
printf("Invalid operand: %s\n",operand);
error = TRUE;
return 0;
}
}
else
{
printf("Syntax Error: %s\n",operand);
error = TRUE;
return 0;
}
}
if (!(addr_mode & ea_mask))
{
error = TRUE;
printf("Invalid addressing mode for '%s' instruction\n",instruct[0]);
return 0;
}
ea = (uint16)((mode << 3) | reg);
return ea;
}
/****************************************************************/
void
afun1 (int ea_mask, uint16 opword) /* funcs already have access to instruct[] */
{
(void) ea_mask;
/* This function is used for all instructions
* whose opcode is written entirely in the isa table
* RTS, NOP, HALT, PULSE, RTE
*/
write_data (16,opword);
}
/****************************************************************/
void
afun2 (int ea_mask, uint16 opword)
{
(void) ea_mask;
/* First opword is known, Second word is immediate data */
/* STOP #0xDATA */
ext_word = (uint16)get_imm_data(instruct[1],0xFFFF0000);
if (!error)
{
ext_word_flag = 1;
write_data (16,opword);
handle_ext_words();
}
}
/****************************************************************/
void
afun3 (int ea_mask, uint16 opword)
{
/* ORI, ANDI, SUBI, ADDI, EORI,*/
/* ORI #<data>,Dn */
if (size_is_long())
{
ext_long = get_imm_data(instruct[1],0x0);
if (!error)
{
ext_long_flag = 1;
afun5(ea_mask,opword);
}
}
}
/****************************************************************/
void
afun4 (int ea_mask, uint16 opword)
{
/* NEG,NEGX,NOT,SWAP,EXTB */
/* Dn - source operand */
/* opword: XXXXXXXXXXXXX|REG# */
int Dn;
(void)ea_mask;
if (size_is_long())
{
Dn = get_data_register(instruct[1]);
if (!reg_error)
{
opword = (uint16)(opword | Dn);
write_data(16,opword);
}
else
printf(ERR_DATA_REG,instruct[1]);
}
}
/****************************************************************/
void
afun5 (int ea_mask, uint16 opword)
{
/* Dn - destination operand */
/* opword: XXXXXXXXXXXXX|REG# */
int Dn;
(void) ea_mask;
Dn = get_data_register(instruct[2]);
if (!reg_error)
{
opword = (uint16)(opword | Dn);
write_data(16,opword);
handle_ext_words();
}
else
printf(ERR_DATA_REG,instruct[2]);
}
/****************************************************************/
void
afun5b (int ea_mask, uint16 opword)
{
/* Rn - destination register */
/* opword: XXXXXXXXXXXXX|REG# */
int Rn;
(void) ea_mask;
if ((Rn=get_data_register(instruct[2]))==8) /* Check is Rn IS NOT a Data register */
{
if ((Rn=get_addr_register(instruct[2])) != 8) /* Check is Rn IS an Address register */
{
opword = (uint16)(opword | Rn | 8 ); /* Rn is a Address register */
write_data(16,opword);
handle_ext_words();
}
else
printf(ERR_REG,instruct[2]); /* Rn is NOT a data or address register */
}
else
{
opword = (uint16)(opword | Rn); /* Rn is a Data register */
write_data(16,opword);
handle_ext_words();
}
}
/****************************************************************/
void
afun6 (int ea_mask, uint16 opword)
{
/* LINK An,#<displacement> */
/* opword: XXXXXXXXXXXXX|REG# */
/* | displacement | */
int32 disp;
disp = get_imm_data(instruct[2],0x0);
if (!error)
{
/* 16-bit, -32768 < disp < 32767 */
if (disp <= 32767 && disp >= -32768)
{
ext_word = (uint16)disp;
ext_word_flag = 1;
afun7(ea_mask,opword);
}
else
printf("Error: displacement larger that 16-bits\n");
}
}
/****************************************************************/
void
afun7 (int ea_mask, uint16 opword)
{
/* UNLK An */
/* An - source operand */
/* opword: XXXXXXXXXXXXX|REG# */
int An;
(void) ea_mask;
An = get_addr_register(instruct[1]);
if (!reg_error)
{
opword = (uint16)(opword | An);
write_data(16,opword);
handle_ext_words();
}
else
printf(ERR_ADDR_REG,instruct[1]);
}
/****************************************************************/
void
afun8 (int ea_mask, uint16 opword)
{
/* PEA, JMP, JSR, Scc's */
/* <ea> - source operand*/
/* XXXXXXXXXX|mod|reg| */
uint16 ea;
ea = get_ea(instruct[1],ea_mask,0);
if (!error)
{
opword = (uint16)(opword | ea);
write_data(16,opword);
handle_ext_words();
}
}
/****************************************************************/
static void
afun8b (int ea_mask, uint16 opword, int force_long)
{
/* <ea> - source operand*/
/* XXXXXXXXXX|mod|reg| */
uint16 ea;
ea = get_ea(instruct[2],ea_mask,force_long);
if (!error)
{
opword = (uint16)(opword | ea);
write_data(16,opword);
handle_ext_words();
}
}
/****************************************************************/
void
afun9 (int ea_mask, uint16 opword)
{
/* BTST, BSET, BCHG, BCLR */
if (instruct[1][0] == '#') /* BXXX #<data>,<ea> */
{
ea_mask = EA_DATA1;
if (strcasecmp(instruct[0],"BTST") == 0)
opword = 0x0800;
else if (strcasecmp(instruct[0],"BCHG") == 0)
opword = 0x0840;
else if (strcasecmp(instruct[0],"BSET") == 0)
opword = 0x08C0;
else /* BCLR */
opword = 0x0880;
opword2 = (uint16)get_imm_data(instruct[1],0xffffff00);
if (!error)
{
opword2_flag = 1; /* tell handle_ext_words() that there */
afun8b(ea_mask,opword,0); /* are two opwords */
}
}
else /* BXXX Dn,<ea> */
{
if (strcasecmp(instruct[0],"BTST") == 0)
opword = 0x0100;
else if (strcasecmp(instruct[0],"BCHG") == 0)
opword = 0x0140;
else if (strcasecmp(instruct[0],"BSET") == 0)
opword = 0x01C0;
else /* BCLR */
opword = 0x0180;
if (strcasecmp(instruct[0],"BTST") == 0)
ea_mask = EA_DATA;
else
ea_mask = EA_DATALT1;
afun17(ea_mask,opword);
}
}
/****************************************************************/
void
afun10 (int ea_mask, uint16 opword)
{
/* CLR, TST, WDDATA */
/* XXXXXXXX|SZ|MOD|REG */
opword = (uint16)(opword & 0xff00); /* clear size bits */
opword = (uint16)(opword | (size << 6));
afun8(ea_mask,opword);
}
/****************************************************************/
void
afun11 (int ea_mask, uint16 opword)
{
/* EXT.s Dn */
/* XXXXXXX|OPM|XXX|REG */
switch (size) /* write OPMODE for each instruction */
{
case 0:
error = TRUE;
printf("Invalid size specified: .W or .L only\n");
break;
case 1:
opword = (uint16)(opword | 0x80);
break;
case 2:
opword = (uint16)(opword | 0xC0);
break;
}
if (!error)
afun4(ea_mask,opword);
}
/****************************************************************/
void
afun12 (int ea_mask, uint16 opword)
{
/* MULU, MULS */
/* MULx.s <ea>,Dn */
/* .W: XXXX|REG|XXX|MOD|REG */
/* .L: XXXXXXXXXX|MOD|REG */
/* X|RDI|XXXXXXXXXXXX */
int Dn;
switch (size)
{
case 0:
error = TRUE;
printf("Invalid size specified: .W or .L only\n");
break;
case 1:
if (strcasecmp(instruct[0],"MULS") == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -