mirror of https://github.com/xemu-project/xemu.git
a couple more dsp instructions
This commit is contained in:
parent
b21312d8ac
commit
79e8643d16
|
@ -224,7 +224,7 @@ static const OpcodeEntry nonparallel_opcodes[] = {
|
|||
{ "0000101111DDDDDD0110bbbb", "btst #n, D", dis_btst_reg, emu_btst_reg },
|
||||
{ "0000110000011110000000SD", "clb S, D", NULL, NULL },
|
||||
{ "0000000101iiiiii1000d101", "cmp #xx, S2", dis_cmp_imm, emu_cmp_imm },
|
||||
{ "00000001010000001100d101", "cmp #xxxx, S2", NULL, NULL },
|
||||
{ "00000001010000001100d101", "cmp #xxxx, S2", dis_cmp_long, emu_cmp_long },
|
||||
{ "00001100000111111111gggd", "cmpu S1, S2", dis_cmpu, emu_cmpu },
|
||||
{ "000000000000001000000000", "debug", NULL, NULL },
|
||||
{ "00000000000000110000CCCC", "debugcc", NULL, NULL },
|
||||
|
@ -314,7 +314,7 @@ static const OpcodeEntry nonparallel_opcodes[] = {
|
|||
{ "00000100W1dddddd0q1qqqqq", "movep Y:qq <-> R", NULL, NULL },
|
||||
{ "00000001000sssss11QQdk00", "mpy S, #n, D", NULL, NULL },
|
||||
{ "00000001001001111sdkQQQQ", "mpy_s_u S1, S2, D", NULL, NULL },
|
||||
{ "000000010100000111qqdk00", "mpyi #xxxx, S, D", NULL, NULL },
|
||||
{ "000000010100000111qqdk00", "mpyi #xxxx, S, D", dis_mpyi, emu_mpyi },
|
||||
{ "00000001000sssss11QQdk01", "mpyr S, #n, D", NULL, NULL },
|
||||
{ "000000010100000111qqdk01", "mpyri #xxxx, S, D", NULL, NULL },
|
||||
{ "000000000000000000000000", "nop", NULL, emu_nop},
|
||||
|
@ -339,7 +339,7 @@ static const OpcodeEntry nonparallel_opcodes[] = {
|
|||
{ "000000000000000000001100", "rts", NULL, emu_rts },
|
||||
{ "000000000000000010000111", "stop", NULL, emu_stop },
|
||||
{ "0000000101iiiiii1000d100", "sub #xx, D", dis_sub_imm, emu_sub_imm },
|
||||
{ "00000001010000001100d100", "sub #xxxx, D", NULL, NULL },
|
||||
{ "00000001010000001100d100", "sub #xxxx, D", dis_sub_long, emu_sub_long },
|
||||
{ "00000010CCCC00000JJJd000", "tcc S1, D1", dis_tcc, emu_tcc },
|
||||
{ "00000011CCCC0ttt0JJJdTTT", "tcc S1,D2 S2,D2", dis_tcc, emu_tcc },
|
||||
{ "00000010CCCC1ttt00000TTT", "tcc S2, D2", dis_tcc, emu_tcc },
|
||||
|
|
|
@ -723,6 +723,15 @@ static void dis_cmp_imm(dsp_core_t* dsp) {
|
|||
xx, registers_name[d ? DSP_REG_B : DSP_REG_A]);
|
||||
}
|
||||
|
||||
static void dis_cmp_long(dsp_core_t* dsp) {
|
||||
uint32_t xxxx = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->disasm_cur_inst_len++;
|
||||
|
||||
uint32_t d = (dsp->disasm_cur_inst >> 3) & 1;
|
||||
sprintf(dsp->disasm_str_instr, "cmp #$%06x,%s",
|
||||
xxxx, registers_name[d ? DSP_REG_B : DSP_REG_A]);
|
||||
}
|
||||
|
||||
static void dis_cmpu(dsp_core_t* dsp) {
|
||||
uint32_t ggg = (dsp->disasm_cur_inst >> 1) & BITMASK(3);
|
||||
uint32_t d = dsp->disasm_cur_inst & 1;
|
||||
|
@ -745,18 +754,10 @@ static void dis_div(dsp_core_t* dsp)
|
|||
uint32_t srcreg=DSP_REG_NULL, destreg;
|
||||
|
||||
switch((dsp->disasm_cur_inst>>4) & BITMASK(2)) {
|
||||
case 0:
|
||||
srcreg = DSP_REG_X0;
|
||||
break;
|
||||
case 1:
|
||||
srcreg = DSP_REG_Y0;
|
||||
break;
|
||||
case 2:
|
||||
srcreg = DSP_REG_X1;
|
||||
break;
|
||||
case 3:
|
||||
srcreg = DSP_REG_Y1;
|
||||
break;
|
||||
case 0: srcreg = DSP_REG_X0; break;
|
||||
case 1: srcreg = DSP_REG_Y0; break;
|
||||
case 2: srcreg = DSP_REG_X1; break;
|
||||
case 3: srcreg = DSP_REG_Y1; break;
|
||||
}
|
||||
destreg = DSP_REG_A+((dsp->disasm_cur_inst>>3) & 1);
|
||||
|
||||
|
@ -1710,6 +1711,30 @@ static void dis_move_y_imm(dsp_core_t* dsp) {
|
|||
dis_move_xy_imm(dsp, DSP_SPACE_Y);
|
||||
}
|
||||
|
||||
static void dis_mpyi(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t xxxx = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->disasm_cur_inst_len++;
|
||||
|
||||
uint32_t k = (dsp->disasm_cur_inst >> 2) & 1;
|
||||
uint32_t d = (dsp->disasm_cur_inst >> 3) & 1;
|
||||
uint32_t qq = (dsp->disasm_cur_inst >> 4) & BITMASK(2);
|
||||
|
||||
unsigned int srcreg = DSP_REG_NULL;
|
||||
switch (qq) {
|
||||
case 0: srcreg = DSP_REG_X0; break;
|
||||
case 1: srcreg = DSP_REG_Y0; break;
|
||||
case 2: srcreg = DSP_REG_X1; break;
|
||||
case 3: srcreg = DSP_REG_Y1; break;
|
||||
}
|
||||
|
||||
unsigned int destreg = d ? DSP_REG_B : DSP_REG_A;
|
||||
|
||||
sprintf(dsp->disasm_str_instr, "mpyi %s#$%06x,%s,%s",
|
||||
k ? "-" : "+", xxxx,
|
||||
registers_name[srcreg], registers_name[destreg]);
|
||||
}
|
||||
|
||||
static void dis_norm(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t srcreg, destreg;
|
||||
|
@ -1801,6 +1826,15 @@ static void dis_sub_imm(dsp_core_t* dsp)
|
|||
xx, registers_name[d ? DSP_REG_B : DSP_REG_A]);
|
||||
}
|
||||
|
||||
static void dis_sub_long(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t xxxx = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->disasm_cur_inst_len++;
|
||||
uint32_t d = (dsp->disasm_cur_inst >> 3) & 1;
|
||||
sprintf(dsp->disasm_str_instr, "sub #$%06x,%s",
|
||||
xxxx, registers_name[d ? DSP_REG_B : DSP_REG_A]);
|
||||
}
|
||||
|
||||
static void dis_tcc(dsp_core_t* dsp)
|
||||
{
|
||||
char ccname[16];
|
||||
|
|
|
@ -5765,13 +5765,10 @@ static const emu_func_t opcodes_parmove[16] = {
|
|||
* Non-parallel moves instructions
|
||||
**********************************/
|
||||
|
||||
static void emu_add_imm(dsp_core_t* dsp)
|
||||
static void emu_add_x(dsp_core_t* dsp, uint32_t x, uint32_t d)
|
||||
{
|
||||
uint32_t xx = (dsp->cur_inst >> 8) & BITMASK(6);
|
||||
|
||||
uint32_t source[3], dest[3];
|
||||
|
||||
if ((dsp->cur_inst >> 3) & 1) {
|
||||
if (d) {
|
||||
dest[0] = dsp->registers[DSP_REG_B2];
|
||||
dest[1] = dsp->registers[DSP_REG_B1];
|
||||
dest[2] = dsp->registers[DSP_REG_B0];
|
||||
|
@ -5782,8 +5779,8 @@ static void emu_add_imm(dsp_core_t* dsp)
|
|||
}
|
||||
|
||||
source[2] = 0;
|
||||
source[1] = xx;
|
||||
source[0] = 0;
|
||||
source[1] = x;
|
||||
source[0] = source[1] & (1<<23) ? 0xff : 0x0;
|
||||
|
||||
uint16_t newsr = dsp_add56(source, dest);
|
||||
|
||||
|
@ -5803,43 +5800,19 @@ static void emu_add_imm(dsp_core_t* dsp)
|
|||
dsp->registers[DSP_REG_SR] |= newsr;
|
||||
}
|
||||
|
||||
static void emu_add_imm(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t xx = (dsp->cur_inst >> 8) & BITMASK(6);
|
||||
uint32_t d = (dsp->cur_inst >> 3) & 1;
|
||||
emu_add_x(dsp, xx, d);
|
||||
}
|
||||
|
||||
static void emu_add_long(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t xxxx = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->cur_inst_len++;
|
||||
|
||||
uint32_t source[3], dest[3];
|
||||
|
||||
if ((dsp->cur_inst >> 3) & 1) {
|
||||
dest[0] = dsp->registers[DSP_REG_B2];
|
||||
dest[1] = dsp->registers[DSP_REG_B1];
|
||||
dest[2] = dsp->registers[DSP_REG_B0];
|
||||
} else {
|
||||
dest[0] = dsp->registers[DSP_REG_A2];
|
||||
dest[1] = dsp->registers[DSP_REG_A1];
|
||||
dest[2] = dsp->registers[DSP_REG_A0];
|
||||
}
|
||||
|
||||
source[2] = 0;
|
||||
source[1] = xxxx;
|
||||
source[0] = source[1] & (1<<23) ? 0xff : 0x0;
|
||||
|
||||
uint16_t newsr = dsp_add56(source, dest);
|
||||
|
||||
if ((dsp->cur_inst >> 3) & 1) {
|
||||
dsp->registers[DSP_REG_B2] = dest[0];
|
||||
dsp->registers[DSP_REG_B1] = dest[1];
|
||||
dsp->registers[DSP_REG_B0] = dest[2];
|
||||
} else {
|
||||
dsp->registers[DSP_REG_A2] = dest[0];
|
||||
dsp->registers[DSP_REG_A1] = dest[1];
|
||||
dsp->registers[DSP_REG_A0] = dest[2];
|
||||
}
|
||||
|
||||
emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]);
|
||||
|
||||
dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_V)|(1<<DSP_SR_C));
|
||||
dsp->registers[DSP_REG_SR] |= newsr;
|
||||
uint32_t d = (dsp->cur_inst >> 3) & 1;
|
||||
emu_add_x(dsp, xxxx, d);
|
||||
}
|
||||
|
||||
static void emu_and_long(dsp_core_t* dsp)
|
||||
|
@ -6515,6 +6488,36 @@ static void emu_cmp_imm(dsp_core_t* dsp)
|
|||
dsp->registers[DSP_REG_SR] |= newsr;
|
||||
}
|
||||
|
||||
static void emu_cmp_long(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t xxxx = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->cur_inst_len++;
|
||||
|
||||
uint32_t d = (dsp->cur_inst >> 3) & 1;
|
||||
|
||||
uint32_t source[3], dest[3];
|
||||
if (d) {
|
||||
dest[2] = dsp->registers[DSP_REG_B0];
|
||||
dest[1] = dsp->registers[DSP_REG_B1];
|
||||
dest[0] = dsp->registers[DSP_REG_B2];
|
||||
} else {
|
||||
dest[2] = dsp->registers[DSP_REG_A0];
|
||||
dest[1] = dsp->registers[DSP_REG_A1];
|
||||
dest[0] = dsp->registers[DSP_REG_A2];
|
||||
}
|
||||
|
||||
source[2] = 0;
|
||||
source[1] = xxxx;
|
||||
source[0] = 0x0;
|
||||
|
||||
uint16_t newsr = dsp_sub56(source, dest);
|
||||
|
||||
emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]);
|
||||
|
||||
dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<<DSP_SR_V)|(1<<DSP_SR_C));
|
||||
dsp->registers[DSP_REG_SR] |= newsr;
|
||||
}
|
||||
|
||||
static void emu_cmpu(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t ggg = (dsp->cur_inst >> 1) & BITMASK(3);
|
||||
|
@ -6572,10 +6575,10 @@ static void emu_div(dsp_core_t* dsp)
|
|||
|
||||
srcreg = DSP_REG_NULL;
|
||||
switch((dsp->cur_inst>>4) & BITMASK(2)) {
|
||||
case 0: srcreg = DSP_REG_X0; break;
|
||||
case 1: srcreg = DSP_REG_Y0; break;
|
||||
case 2: srcreg = DSP_REG_X1; break;
|
||||
case 3: srcreg = DSP_REG_Y1; break;
|
||||
case 0: srcreg = DSP_REG_X0; break;
|
||||
case 1: srcreg = DSP_REG_Y0; break;
|
||||
case 2: srcreg = DSP_REG_X1; break;
|
||||
case 3: srcreg = DSP_REG_Y1; break;
|
||||
}
|
||||
source[2] = 0;
|
||||
source[1] = dsp->registers[srcreg];
|
||||
|
@ -7667,6 +7670,40 @@ static void emu_move_y_imm(dsp_core_t* dsp)
|
|||
emu_move_xy_imm(dsp, DSP_SPACE_Y);
|
||||
}
|
||||
|
||||
static void emu_mpyi(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t xxxx = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->cur_inst_len++;
|
||||
|
||||
uint32_t k = (dsp->cur_inst >> 2) & 1;
|
||||
uint32_t d = (dsp->cur_inst >> 3) & 1;
|
||||
uint32_t qq = (dsp->cur_inst >> 4) & BITMASK(2);
|
||||
|
||||
unsigned int srcreg = DSP_REG_NULL;
|
||||
switch (qq) {
|
||||
case 0: srcreg = DSP_REG_X0; break;
|
||||
case 1: srcreg = DSP_REG_Y0; break;
|
||||
case 2: srcreg = DSP_REG_X1; break;
|
||||
case 3: srcreg = DSP_REG_Y1; break;
|
||||
}
|
||||
|
||||
uint32_t source[3];
|
||||
dsp_mul56(xxxx, dsp->registers[srcreg], source, k ? SIGN_MINUS : SIGN_PLUS);
|
||||
|
||||
if (d) {
|
||||
dsp->registers[DSP_REG_B2] = source[0];
|
||||
dsp->registers[DSP_REG_B1] = source[1];
|
||||
dsp->registers[DSP_REG_B0] = source[2];
|
||||
} else {
|
||||
dsp->registers[DSP_REG_A2] = source[0];
|
||||
dsp->registers[DSP_REG_A1] = source[1];
|
||||
dsp->registers[DSP_REG_A0] = source[2];
|
||||
}
|
||||
|
||||
emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]);
|
||||
dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<<DSP_SR_V);
|
||||
}
|
||||
|
||||
static void emu_norm(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t cursr,cur_e, cur_euz, dest[3], numreg, rreg;
|
||||
|
@ -7858,11 +7895,8 @@ static void emu_stop(dsp_core_t* dsp)
|
|||
DPRINTF("Dsp: STOP instruction\n");
|
||||
}
|
||||
|
||||
static void emu_sub_imm(dsp_core_t* dsp)
|
||||
static void emu_sub_x(dsp_core_t* dsp, uint32_t x, uint32_t d)
|
||||
{
|
||||
uint32_t xx = (dsp->cur_inst >> 8) & BITMASK(6);
|
||||
uint32_t d = (dsp->cur_inst >> 3) & 1;
|
||||
|
||||
uint32_t source[3], dest[3];
|
||||
|
||||
if (d) {
|
||||
|
@ -7876,8 +7910,8 @@ static void emu_sub_imm(dsp_core_t* dsp)
|
|||
}
|
||||
|
||||
source[2] = 0;
|
||||
source[1] = xx;
|
||||
source[0] = 0;
|
||||
source[1] = x;
|
||||
source[0] = source[1] & (1<<23) ? 0xff : 0x0;
|
||||
|
||||
uint16_t newsr = dsp_sub56(source, dest);
|
||||
|
||||
|
@ -7897,6 +7931,22 @@ static void emu_sub_imm(dsp_core_t* dsp)
|
|||
dsp->registers[DSP_REG_SR] |= newsr;
|
||||
}
|
||||
|
||||
static void emu_sub_imm(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t xx = (dsp->cur_inst >> 8) & BITMASK(6);
|
||||
uint32_t d = (dsp->cur_inst >> 3) & 1;
|
||||
emu_sub_x(dsp, xx, d);
|
||||
}
|
||||
|
||||
static void emu_sub_long(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t xxxx = read_memory_p(dsp, dsp->pc+1);
|
||||
dsp->cur_inst_len++;
|
||||
|
||||
uint32_t d = (dsp->cur_inst >> 3) & 1;
|
||||
emu_sub_x(dsp, xxxx, d);
|
||||
}
|
||||
|
||||
static void emu_tcc(dsp_core_t* dsp)
|
||||
{
|
||||
uint32_t cc_code, regsrc1, regdest1;
|
||||
|
|
Loading…
Reference in New Issue