mirror of
https://github.com/holub/mame
synced 2025-05-24 23:05:32 +03:00
Rewrite of the Motorola DSP56k CPU core. (Andrew Gardner)
* Fixed flag calculation and sign extension for numerous ops. * Added rnd, mpysuuu, and dmac ops. * Fixed do loop behavior to skip empty loops. * Added stack underflow exception handling.
This commit is contained in:
parent
6bd48dad88
commit
44a99ed738
@ -308,37 +308,37 @@ CPU_DISASSEMBLE( dsp56k )
|
|||||||
int parallelType = -1;
|
int parallelType = -1;
|
||||||
|
|
||||||
/* Note: it's important that NPDM comes before RtRDM here */
|
/* Note: it's important that NPDM comes before RtRDM here */
|
||||||
/* No Parallel Data Move : 0100 1010 ---- ---- : A-131 */
|
/* No Parallel Data Move : 0100 1010 .... .... : A-131 */
|
||||||
if ((op & 0xff00) == 0x4a00)
|
if ((op & 0xff00) == 0x4a00)
|
||||||
{
|
{
|
||||||
op_byte = op & 0x00ff;
|
op_byte = op & 0x00ff;
|
||||||
parallelType = kNoParallelDataMove;
|
parallelType = kNoParallelDataMove;
|
||||||
}
|
}
|
||||||
/* Register to Register Data Move : 0100 IIII ---- ---- : A-133 */
|
/* Register to Register Data Move : 0100 IIII .... .... : A-133 */
|
||||||
else if ((op & 0xf000) == 0x4000)
|
else if ((op & 0xf000) == 0x4000)
|
||||||
{
|
{
|
||||||
op_byte = op & 0x00ff;
|
op_byte = op & 0x00ff;
|
||||||
parallelType = kRegisterToRegister;
|
parallelType = kRegisterToRegister;
|
||||||
}
|
}
|
||||||
/* Address Register Update : 0011 0zRR ---- ---- : A-135 */
|
/* Address Register Update : 0011 0zRR .... .... : A-135 */
|
||||||
else if ((op & 0xf800) == 0x3000)
|
else if ((op & 0xf800) == 0x3000)
|
||||||
{
|
{
|
||||||
op_byte = op & 0x00ff;
|
op_byte = op & 0x00ff;
|
||||||
parallelType = kAddressRegister;
|
parallelType = kAddressRegister;
|
||||||
}
|
}
|
||||||
/* X Memory Data Move : 1mRR HHHW ---- ---- : A-137 */
|
/* X Memory Data Move : 1mRR HHHW .... .... : A-137 */
|
||||||
else if ((op & 0x8000) == 0x8000)
|
else if ((op & 0x8000) == 0x8000)
|
||||||
{
|
{
|
||||||
op_byte = op & 0x00ff;
|
op_byte = op & 0x00ff;
|
||||||
parallelType = kXMemoryDataMove;
|
parallelType = kXMemoryDataMove;
|
||||||
}
|
}
|
||||||
/* X Memory Data Move : 0101 HHHW ---- ---- : A-137 */
|
/* X Memory Data Move : 0101 HHHW .... .... : A-137 */
|
||||||
else if ((op & 0xf000) == 0x5000)
|
else if ((op & 0xf000) == 0x5000)
|
||||||
{
|
{
|
||||||
op_byte = op & 0x00ff;
|
op_byte = op & 0x00ff;
|
||||||
parallelType = kXMemoryDataMove2;
|
parallelType = kXMemoryDataMove2;
|
||||||
}
|
}
|
||||||
/* X Memory Data Move with short displacement : 0000 0101 BBBB BBBB ---- HHHW ---- ---- : A-139 */
|
/* X Memory Data Move with short displacement : 0000 0101 BBBB BBBB ---- HHHW .... .... : A-139 */
|
||||||
else if ((op & 0xff00) == 0x0500)
|
else if ((op & 0xff00) == 0x0500)
|
||||||
{
|
{
|
||||||
/* Now check it against all the other potential collisions */
|
/* Now check it against all the other potential collisions */
|
||||||
|
@ -242,7 +242,7 @@ static CPU_RESET( dsp56k )
|
|||||||
agu_reset(cpustate);
|
agu_reset(cpustate);
|
||||||
alu_reset(cpustate);
|
alu_reset(cpustate);
|
||||||
|
|
||||||
/* HACK - Put a jump to 0x0000 at 0x0000 - this keeps the CPU put in MAME */
|
/* HACK - Put a jump to 0x0000 at 0x0000 - this keeps the CPU locked to the instruction at address 0x0000 */
|
||||||
memory_write_word_16le(cpustate->program, 0x0000, 0x0124);
|
memory_write_word_16le(cpustate->program, 0x0000, 0x0124);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,15 @@
|
|||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO:
|
||||||
|
- 0x01ee: should this move sign extend? otherwise the test-against-minus means nothing.
|
||||||
|
- Restore only the proper bits upon loop termination!
|
||||||
|
- BFCLR has some errata in the docs that may need to be applied.
|
||||||
|
- *_bit_set(0) is difficult to read. maybe make it *_bit_chg(0).
|
||||||
|
- Potentially "better" reporting for unimplemented opcodes.
|
||||||
|
*/
|
||||||
|
|
||||||
/************************/
|
/************************/
|
||||||
/* Datatypes and macros */
|
/* Datatypes and macros */
|
||||||
/************************/
|
/************************/
|
||||||
@ -175,6 +184,7 @@ static UINT16 decode_BBB_bitmask(dsp56k_core* cpustate, UINT16 BBB, UINT16 *iVal
|
|||||||
static int decode_cccc_table(dsp56k_core* cpustate, UINT16 cccc);
|
static int decode_cccc_table(dsp56k_core* cpustate, UINT16 cccc);
|
||||||
static void decode_DDDDD_table(dsp56k_core* cpustate, UINT16 DDDDD, typed_pointer* ret);
|
static void decode_DDDDD_table(dsp56k_core* cpustate, UINT16 DDDDD, typed_pointer* ret);
|
||||||
static void decode_DD_table(dsp56k_core* cpustate, UINT16 DD, typed_pointer* ret);
|
static void decode_DD_table(dsp56k_core* cpustate, UINT16 DD, typed_pointer* ret);
|
||||||
|
static void decode_DDF_table(dsp56k_core* cpustate, UINT16 DD, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
|
||||||
static void decode_F_table(dsp56k_core* cpustate, UINT16 F, typed_pointer* ret);
|
static void decode_F_table(dsp56k_core* cpustate, UINT16 F, typed_pointer* ret);
|
||||||
static void decode_h0hF_table(dsp56k_core* cpustate, UINT16 h0h, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
|
static void decode_h0hF_table(dsp56k_core* cpustate, UINT16 h0h, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
|
||||||
static void decode_HH_table(dsp56k_core* cpustate, UINT16 HH, typed_pointer* ret);
|
static void decode_HH_table(dsp56k_core* cpustate, UINT16 HH, typed_pointer* ret);
|
||||||
@ -1125,9 +1135,9 @@ static size_t dsp56k_op_addsub_2(dsp56k_core* cpustate, const UINT16 op_byte, ty
|
|||||||
case DT_LONG_WORD: useVal = (UINT64)*((UINT64*)S.addr); break;
|
case DT_LONG_WORD: useVal = (UINT64)*((UINT64*)S.addr); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Verify : Sign-extend everyone for proper add/sub op */
|
/* Sign-extend word for proper add/sub op */
|
||||||
if (useVal & U64(0x0000000080000000))
|
if ((S.data_type == DT_WORD) && useVal & U64(0x0000000080000000))
|
||||||
useVal |= U64(0xffffffff00000000);
|
useVal |= U64(0x000000ff00000000);
|
||||||
|
|
||||||
/* Operate*/
|
/* Operate*/
|
||||||
if (op_type == OP_ADD)
|
if (op_type == OP_ADD)
|
||||||
@ -1141,8 +1151,8 @@ static size_t dsp56k_op_addsub_2(dsp56k_core* cpustate, const UINT16 op_byte, ty
|
|||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* * * * * * * * * */
|
/* * * * * * * * * */
|
||||||
/* TODO S, L, E, U, V, C */
|
/* TODO S, L, E, U, V, C */
|
||||||
if (*((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
if (*((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
if (*((UINT64*)D.addr) == 0) Z_bit_set(cpustate, 1);
|
if (*((UINT64*)D.addr) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
|
|
||||||
cycles += 2; /* TODO: + mv oscillator cycles */
|
cycles += 2; /* TODO: + mv oscillator cycles */
|
||||||
return 1;
|
return 1;
|
||||||
@ -1192,8 +1202,8 @@ static size_t dsp56k_op_mac_1(dsp56k_core* cpustate, const UINT16 op_byte, typed
|
|||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* * * * * * * * - */
|
/* * * * * * * * - */
|
||||||
/* TODO: S, L, E, V */
|
/* TODO: S, L, E, V */
|
||||||
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(cpustate, 1);
|
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
|
|
||||||
cycles += 2; /* TODO: +mv oscillator cycles */
|
cycles += 2; /* TODO: +mv oscillator cycles */
|
||||||
return 1;
|
return 1;
|
||||||
@ -1246,8 +1256,8 @@ static size_t dsp56k_op_mpy_1(dsp56k_core* cpustate, const UINT16 op_byte, typed
|
|||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* * * * * * * * - */
|
/* * * * * * * * - */
|
||||||
/* TODO: S, L, E, V */
|
/* TODO: S, L, E, V */
|
||||||
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(cpustate, 1);
|
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
|
|
||||||
cycles += 2; /* TODO: +mv oscillator cycles */
|
cycles += 2; /* TODO: +mv oscillator cycles */
|
||||||
return 1;
|
return 1;
|
||||||
@ -1334,9 +1344,9 @@ static size_t dsp56k_op_add(dsp56k_core* cpustate, const UINT16 op_byte, typed_p
|
|||||||
case DT_LONG_WORD: addVal = (UINT64)*((UINT64*)S.addr); break;
|
case DT_LONG_WORD: addVal = (UINT64)*((UINT64*)S.addr); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Verify : Sign-extend everyone for proper addition op */
|
/* Sign-extend word for proper add/sub op */
|
||||||
if (addVal & U64(0x0000000080000000))
|
if ((S.data_type == DT_WORD) && addVal & U64(0x0000000080000000))
|
||||||
addVal |= U64(0xffffffff00000000);
|
addVal |= U64(0x000000ff00000000);
|
||||||
|
|
||||||
/* Operate*/
|
/* Operate*/
|
||||||
*((UINT64*)D.addr) += addVal;
|
*((UINT64*)D.addr) += addVal;
|
||||||
@ -1347,8 +1357,8 @@ static size_t dsp56k_op_add(dsp56k_core* cpustate, const UINT16 op_byte, typed_p
|
|||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* * * * * * * * * */
|
/* * * * * * * * * */
|
||||||
/* TODO S, L, E, U, V, C */
|
/* TODO S, L, E, U, V, C */
|
||||||
if (*((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
if (*((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
if (*((UINT64*)D.addr) == 0) Z_bit_set(cpustate, 1);
|
if (*((UINT64*)D.addr) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
|
|
||||||
cycles += 2; /* TODO: + mv oscillator cycles */
|
cycles += 2; /* TODO: + mv oscillator cycles */
|
||||||
return 1;
|
return 1;
|
||||||
@ -1395,9 +1405,29 @@ static size_t dsp56k_op_tfr(dsp56k_core* cpustate, const UINT16 op_byte, typed_p
|
|||||||
/* RND : .... .... 0010 F000 : A-188 */
|
/* RND : .... .... 0010 F000 : A-188 */
|
||||||
static size_t dsp56k_op_rnd(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
|
static size_t dsp56k_op_rnd(dsp56k_core* cpustate, const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
|
||||||
{
|
{
|
||||||
|
typed_pointer D = {NULL, DT_BYTE};
|
||||||
|
|
||||||
|
decode_F_table(cpustate, BITS(op_byte,0x0008), &D);
|
||||||
|
|
||||||
|
*p_accum = *((UINT64*)D.addr);
|
||||||
|
|
||||||
|
/* WARNING : ROUNDING NOT FULLY IMPLEMENTED YET! */
|
||||||
|
if ((*((UINT64*)D.addr) & U64(0x000000000000ffff)) >= 0x8000)
|
||||||
|
*((UINT64*)D.addr) += U64(0x0000000000010000);
|
||||||
|
|
||||||
|
*((UINT64*)D.addr) = *((UINT64*)D.addr) & U64(0x000000ffffff0000);
|
||||||
|
|
||||||
|
d_register->addr = D.addr;
|
||||||
|
d_register->data_type = D.data_type;
|
||||||
|
|
||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* * * * * * * * - */
|
/* * * * * * * * - */
|
||||||
return 0;
|
/* TODO: S, L, E, U, V */
|
||||||
|
if ((*((UINT64*)D.addr)) & U64(0x0000008000000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
|
if ((*((UINT64*)D.addr)) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
|
|
||||||
|
cycles += 2; /* TODO: + mv oscillator clock cycles */
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TST : .... .... 0010 F001 : A-218 */
|
/* TST : .... .... 0010 F001 : A-218 */
|
||||||
@ -1445,8 +1475,8 @@ static size_t dsp56k_op_inc(dsp56k_core* cpustate, const UINT16 op_byte, typed_p
|
|||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* * * * * * * * * */
|
/* * * * * * * * * */
|
||||||
/* TODO: S, L, E, U, V, C */
|
/* TODO: S, L, E, U, V, C */
|
||||||
if ( *((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
if ( *((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) Z_bit_set(cpustate, 1);
|
if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
|
|
||||||
cycles += 2; /* TODO: +mv oscillator cycles */
|
cycles += 2; /* TODO: +mv oscillator cycles */
|
||||||
return 1;
|
return 1;
|
||||||
@ -1478,8 +1508,8 @@ static size_t dsp56k_op_inc24(dsp56k_core* cpustate, const UINT16 op_byte, typed
|
|||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* * * * * * ? * * */
|
/* * * * * * ? * * */
|
||||||
/* TODO: S, L, E, U, V, C */
|
/* TODO: S, L, E, U, V, C */
|
||||||
if ( *((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
if ( *((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) Z_bit_set(cpustate, 1);
|
if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
|
|
||||||
cycles += 2; /* TODO: + mv oscillator clock cycles */
|
cycles += 2; /* TODO: + mv oscillator clock cycles */
|
||||||
return 1;
|
return 1;
|
||||||
@ -1536,10 +1566,10 @@ static size_t dsp56k_op_asr(dsp56k_core* cpustate, const UINT16 op_byte, typed_p
|
|||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* * * * * * * 0 ? */
|
/* * * * * * * 0 ? */
|
||||||
/* TODO: S, L, E, U */
|
/* TODO: S, L, E, U */
|
||||||
if (*((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
if (*((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
if (*((UINT64*)D.addr) == 0) Z_bit_set(cpustate, 1);
|
if (*((UINT64*)D.addr) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
V_bit_set(cpustate, 0);
|
V_bit_set(cpustate, 0);
|
||||||
if (*p_accum & U64(0x0000000000000001)) C_bit_set(cpustate, 1);
|
if (*p_accum & U64(0x0000000000000001)) C_bit_set(cpustate, 1); else C_bit_set(cpustate, 0);
|
||||||
|
|
||||||
cycles += 2; /* TODO: + mv oscillator cycles */
|
cycles += 2; /* TODO: + mv oscillator cycles */
|
||||||
return 1;
|
return 1;
|
||||||
@ -1577,9 +1607,9 @@ static size_t dsp56k_op_lsr(dsp56k_core* cpustate, const UINT16 op_byte, typed_p
|
|||||||
/* * * - - ? ? 0 ? */
|
/* * * - - ? ? 0 ? */
|
||||||
/* TODO: S, L */
|
/* TODO: S, L */
|
||||||
N_bit_set(cpustate, 0);
|
N_bit_set(cpustate, 0);
|
||||||
if (((PAIR64*)D.addr)->w.h == 0) Z_bit_set(cpustate, 1);
|
if (((PAIR64*)D.addr)->w.h == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
V_bit_set(cpustate, 0);
|
V_bit_set(cpustate, 0);
|
||||||
if (*p_accum & U64(0x0000000000010000)) C_bit_set(cpustate, 1);
|
if (*p_accum & U64(0x0000000000010000)) C_bit_set(cpustate, 1); else C_bit_set(cpustate, 0);
|
||||||
|
|
||||||
cycles += 2; /* TODO: + mv oscillator cycles */
|
cycles += 2; /* TODO: + mv oscillator cycles */
|
||||||
return 1;
|
return 1;
|
||||||
@ -1656,11 +1686,20 @@ static size_t dsp56k_op_cmp(dsp56k_core* cpustate, const UINT16 op_byte, typed_p
|
|||||||
|
|
||||||
switch(S.data_type)
|
switch(S.data_type)
|
||||||
{
|
{
|
||||||
case DT_WORD: cmpVal = (UINT64)*((UINT16*)S.addr); break;
|
case DT_WORD: cmpVal = (UINT64)*((UINT16*)S.addr) << 16; break;
|
||||||
case DT_DOUBLE_WORD: cmpVal = (UINT64)*((UINT32*)S.addr); break;
|
case DT_DOUBLE_WORD: cmpVal = (UINT64)*((UINT32*)S.addr); break;
|
||||||
case DT_LONG_WORD: cmpVal = (UINT64)*((UINT64*)S.addr); break;
|
case DT_LONG_WORD: cmpVal = (UINT64)*((UINT64*)S.addr); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sign-extend word for proper subtraction op */
|
||||||
|
if ((S.data_type == DT_WORD) && cmpVal & U64(0x0000000080000000))
|
||||||
|
cmpVal |= U64(0x000000ff00000000);
|
||||||
|
|
||||||
|
/* Make sure they're both real 40-bit values */
|
||||||
|
cmpVal &= U64(0x000000ffffffffff);
|
||||||
|
*((UINT64*)D.addr) &= U64(0x000000ffffffffff);
|
||||||
|
|
||||||
|
/* Operate */
|
||||||
result = *((UINT64*)D.addr) - cmpVal;
|
result = *((UINT64*)D.addr) - cmpVal;
|
||||||
|
|
||||||
d_register->addr = D.addr;
|
d_register->addr = D.addr;
|
||||||
@ -1669,7 +1708,7 @@ static size_t dsp56k_op_cmp(dsp56k_core* cpustate, const UINT16 op_byte, typed_p
|
|||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* * * * * * * * * */
|
/* * * * * * * * * */
|
||||||
/* TODO: S, L, E, U, N, V, C */
|
/* TODO: S, L, E, U, N, V, C */
|
||||||
if (result == 0) Z_bit_set(cpustate, 1); /* TODO: Do you clear it if this isn't true? */
|
if (result == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
|
|
||||||
|
|
||||||
cycles += 2; /* TODO: + mv oscillator clock cycles */
|
cycles += 2; /* TODO: + mv oscillator clock cycles */
|
||||||
@ -1701,8 +1740,8 @@ static size_t dsp56k_op_not(dsp56k_core* cpustate, const UINT16 op_byte, typed_p
|
|||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* * * - - ? ? 0 - */
|
/* * * - - ? ? 0 - */
|
||||||
/* TODO: S?, L */
|
/* TODO: S?, L */
|
||||||
if ( *((UINT64*)D.addr) & U64(0x0000000080000000)) N_bit_set(cpustate, 1);
|
if ( *((UINT64*)D.addr) & U64(0x0000000080000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
if ((*((UINT64*)D.addr) & U64(0x00000000ffff0000)) == 0) Z_bit_set(cpustate, 1);
|
if ((*((UINT64*)D.addr) & U64(0x00000000ffff0000)) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
V_bit_set(cpustate, 0);
|
V_bit_set(cpustate, 0);
|
||||||
|
|
||||||
cycles += 2; /* TODO: + mv oscillator cycles */
|
cycles += 2; /* TODO: + mv oscillator cycles */
|
||||||
@ -1743,8 +1782,8 @@ static size_t dsp56k_op_dec24(dsp56k_core* cpustate, const UINT16 op_byte, typed
|
|||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* * * * * * ? * * */
|
/* * * * * * ? * * */
|
||||||
/* TODO: S, L, E, U, V, C */
|
/* TODO: S, L, E, U, V, C */
|
||||||
if ( *((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
if ( *((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) Z_bit_set(cpustate, 1);
|
if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
|
|
||||||
cycles += 2; /* TODO: + mv oscillator clock cycles */
|
cycles += 2; /* TODO: + mv oscillator clock cycles */
|
||||||
return 1;
|
return 1;
|
||||||
@ -1770,8 +1809,8 @@ static size_t dsp56k_op_and(dsp56k_core* cpustate, const UINT16 op_byte, typed_p
|
|||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* * * - - ? ? 0 - */
|
/* * * - - ? ? 0 - */
|
||||||
/* TODO: S, L */
|
/* TODO: S, L */
|
||||||
if ( *((UINT64*)D.addr) & U64(0x0000000080000000)) N_bit_set(cpustate, 1);
|
if ( *((UINT64*)D.addr) & U64(0x0000000080000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
if ((*((UINT64*)D.addr) & U64(0x00000000ffff0000)) == 0) Z_bit_set(cpustate, 1);
|
if ((*((UINT64*)D.addr) & U64(0x00000000ffff0000)) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
V_bit_set(cpustate, 0);
|
V_bit_set(cpustate, 0);
|
||||||
|
|
||||||
cycles += 2; /* TODO: + mv oscillator cycles */
|
cycles += 2; /* TODO: + mv oscillator cycles */
|
||||||
@ -1901,8 +1940,8 @@ static size_t dsp56k_op_mpy(dsp56k_core* cpustate, const UINT16 op_byte, typed_p
|
|||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* * * * * * * * - */
|
/* * * * * * * * - */
|
||||||
/* TODO: S, L, E, V */
|
/* TODO: S, L, E, V */
|
||||||
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(cpustate, 1);
|
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
|
|
||||||
cycles += 2; /* TODO: +mv oscillator cycles */
|
cycles += 2; /* TODO: +mv oscillator cycles */
|
||||||
return 1;
|
return 1;
|
||||||
@ -1967,8 +2006,8 @@ static size_t dsp56k_op_mac(dsp56k_core* cpustate, const UINT16 op_byte, typed_p
|
|||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* * * * * * * * - */
|
/* * * * * * * * - */
|
||||||
/* TODO: S, L, E, V */
|
/* TODO: S, L, E, V */
|
||||||
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(cpustate, 1);
|
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
|
|
||||||
cycles += 2; /* TODO: +mv oscillator cycles */
|
cycles += 2; /* TODO: +mv oscillator cycles */
|
||||||
return 1;
|
return 1;
|
||||||
@ -2015,6 +2054,9 @@ static size_t dsp56k_op_macr(dsp56k_core* cpustate, const UINT16 op_byte, typed_
|
|||||||
|
|
||||||
/* Round the result */
|
/* Round the result */
|
||||||
/* WARNING : ROUNDING NOT FULLY IMPLEMENTED YET! */
|
/* WARNING : ROUNDING NOT FULLY IMPLEMENTED YET! */
|
||||||
|
if ((opD & U64(0x000000000000ffff)) >= 0x8000)
|
||||||
|
opD += U64(0x0000000000010000);
|
||||||
|
|
||||||
opD &= U64(0x000000ffffff0000);
|
opD &= U64(0x000000ffffff0000);
|
||||||
|
|
||||||
/* And out the bits that don't live in the register */
|
/* And out the bits that don't live in the register */
|
||||||
@ -2030,8 +2072,8 @@ static size_t dsp56k_op_macr(dsp56k_core* cpustate, const UINT16 op_byte, typed_
|
|||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* * * * * * * * - */
|
/* * * * * * * * - */
|
||||||
/* TODO: S, L, E, V */
|
/* TODO: S, L, E, V */
|
||||||
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(cpustate, 1);
|
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
|
|
||||||
cycles += 2; /* TODO: +mv oscillator cycles */
|
cycles += 2; /* TODO: +mv oscillator cycles */
|
||||||
return 1;
|
return 1;
|
||||||
@ -2184,7 +2226,7 @@ static size_t dsp56k_op_bfop(dsp56k_core* cpustate, const UINT16 op, const UINT1
|
|||||||
UINT16 iVal = op2 & 0x00ff;
|
UINT16 iVal = op2 & 0x00ff;
|
||||||
decode_BBB_bitmask(cpustate, BITS(op2,0xe000), &iVal);
|
decode_BBB_bitmask(cpustate, BITS(op2,0xe000), &iVal);
|
||||||
|
|
||||||
workAddr = assemble_address_from_Pppppp_table(cpustate, BITS(OP,0x0020), BITS(OP,0x001f));
|
workAddr = assemble_address_from_Pppppp_table(cpustate, BITS(op,0x0020), BITS(op,0x001f));
|
||||||
previousValue = memory_read_word_16le(cpustate->data, WORD(workAddr));
|
previousValue = memory_read_word_16le(cpustate->data, WORD(workAddr));
|
||||||
workingWord = previousValue;
|
workingWord = previousValue;
|
||||||
|
|
||||||
@ -2596,20 +2638,71 @@ static size_t dsp56k_op_debugcc(dsp56k_core* cpustate, const UINT16 op, UINT8* c
|
|||||||
/* WARNING : DOCS SAY THERE IS A PARALLEL MOVE HERE !!! */
|
/* WARNING : DOCS SAY THERE IS A PARALLEL MOVE HERE !!! */
|
||||||
static size_t dsp56k_op_div(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
|
static size_t dsp56k_op_div(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
|
||||||
{
|
{
|
||||||
|
/* WARNING : THIS DOES NOT WORK. IT DOESN'T EVEN TRY !!! */
|
||||||
|
typed_pointer S = {NULL, DT_BYTE};
|
||||||
|
typed_pointer D = {NULL, DT_BYTE};
|
||||||
|
|
||||||
|
decode_DDF_table(cpustate, BITS(op,0x0003), BITS(op,0x0008), &S, &D);
|
||||||
|
|
||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* - * - - - - ? ? */
|
/* - * - - - - ? ? */
|
||||||
/* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if the most significantst
|
/* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if the most significantst
|
||||||
bit of the destination operand is changed as a result of the left shift. Cleared otherwise. */
|
bit of the destination operand is changed as a result of the left shift. Cleared otherwise. */
|
||||||
/* C - Set if bit 39 of the result is cleared. Cleared otherwise. */
|
/* C - Set if bit 39 of the result is cleared. Cleared otherwise. */
|
||||||
return 0;
|
cycles += 2;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DMAC : 0001 0101 10s1 FsQQ : A-80 */
|
/* DMAC : 0001 0101 10s1 FsQQ : A-80 */
|
||||||
static size_t dsp56k_op_dmac(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
|
static size_t dsp56k_op_dmac(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
|
||||||
{
|
{
|
||||||
|
UINT8 ss = 0;
|
||||||
|
INT64 result = 0;
|
||||||
|
|
||||||
|
void* D = NULL;
|
||||||
|
void* S1 = NULL;
|
||||||
|
void* S2 = NULL;
|
||||||
|
|
||||||
|
decode_QQF_special_table(cpustate, BITS(op,0x0003), BITS(op,0x0008), &S1, &S2, &D);
|
||||||
|
|
||||||
|
ss = BITS(op,0x0024);
|
||||||
|
|
||||||
|
/* Fixed-point 2's complement multiplication requires a shift */
|
||||||
|
if (ss == 0x00 || ss == 0x01)
|
||||||
|
{
|
||||||
|
/* Signed * Signed */
|
||||||
|
INT32 s1 = ((INT32)(*((UINT16*)S1)));
|
||||||
|
INT32 s2 = ((INT32)(*((UINT16*)S2)));
|
||||||
|
result = ( s1 * s2 ) << 1;
|
||||||
|
}
|
||||||
|
else if (ss == 0x2)
|
||||||
|
{
|
||||||
|
/* Signed * Unsigned */
|
||||||
|
/* WARNING : THERE IS A HUGE CHANCE THIS DOESN'T WORK RIGHT */
|
||||||
|
INT32 s1 = ((INT32)(*((UINT16*)S1)));
|
||||||
|
INT32 s2 = (UINT32)(*((UINT16*)S2));
|
||||||
|
result = ( s1 * s2 ) << 1;
|
||||||
|
}
|
||||||
|
else if (ss == 0x3)
|
||||||
|
{
|
||||||
|
/* Unsigned * Unsigned */
|
||||||
|
UINT32 s1 = (UINT32)(*((UINT16*)S1));
|
||||||
|
UINT32 s2 = (UINT32)(*((UINT16*)S2));
|
||||||
|
result = ( s1 * s2 ) << 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Shift right, then accumulate */
|
||||||
|
(*((UINT64*)D)) = (*((UINT64*)D)) >> 16;
|
||||||
|
(*((UINT64*)D)) += result;
|
||||||
|
|
||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* - * * * * * * - */
|
/* - * * * * * * - */
|
||||||
return 0;
|
/* TODO: L, E, U, V */
|
||||||
|
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
|
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
|
|
||||||
|
cycles += 2;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DO : 0000 0000 110- --RR xxxx xxxx xxxx xxxx : A-82 */
|
/* DO : 0000 0000 110- --RR xxxx xxxx xxxx xxxx : A-82 */
|
||||||
@ -2623,6 +2716,7 @@ static size_t dsp56k_op_do(dsp56k_core* cpustate, const UINT16 op, const UINT16
|
|||||||
/* DO : 0000 1110 iiii iiii xxxx xxxx xxxx xxxx : A-82 */
|
/* DO : 0000 1110 iiii iiii xxxx xxxx xxxx xxxx : A-82 */
|
||||||
static size_t dsp56k_op_do_1(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
|
static size_t dsp56k_op_do_1(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
|
||||||
{
|
{
|
||||||
|
UINT8 retSize = 0;
|
||||||
UINT8 iValue = BITS(op,0x00ff);
|
UINT8 iValue = BITS(op,0x00ff);
|
||||||
|
|
||||||
/* Don't execute if the loop counter == 0 */
|
/* Don't execute if the loop counter == 0 */
|
||||||
@ -2645,24 +2739,34 @@ static size_t dsp56k_op_do_1(dsp56k_core* cpustate, const UINT16 op, const UINT1
|
|||||||
/* Third instruction cycle */
|
/* Third instruction cycle */
|
||||||
LF_bit_set(cpustate, 1);
|
LF_bit_set(cpustate, 1);
|
||||||
|
|
||||||
|
/* Undocumented, but it must be true to nest Dos in DoForevers */
|
||||||
|
FV_bit_set(cpustate, 0);
|
||||||
|
|
||||||
|
|
||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* - * - - - - - - */
|
/* - * - - - - - - */
|
||||||
/* TODO : L */
|
/* TODO : L */
|
||||||
|
|
||||||
cycles += 6; /* TODO: + mv oscillator cycles */
|
cycles += 6; /* TODO: + mv oscillator cycles */
|
||||||
|
retSize = 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Skip over the contents of the loop */
|
||||||
|
cpustate->ppc = PC;
|
||||||
|
PC = PC + 2 + op2;
|
||||||
|
|
||||||
cycles += 10; /* TODO: + mv oscillator cycles */
|
cycles += 10; /* TODO: + mv oscillator cycles */
|
||||||
|
retSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 2;
|
return retSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DO : 0000 0100 000D DDDD xxxx xxxx xxxx xxxx : A-82 */
|
/* DO : 0000 0100 000D DDDD xxxx xxxx xxxx xxxx : A-82 */
|
||||||
static size_t dsp56k_op_do_2(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
|
static size_t dsp56k_op_do_2(dsp56k_core* cpustate, const UINT16 op, const UINT16 op2, UINT8* cycles)
|
||||||
{
|
{
|
||||||
|
UINT8 retSize = 0;
|
||||||
UINT16 lValue = 0x0000;
|
UINT16 lValue = 0x0000;
|
||||||
typed_pointer S = {NULL, DT_BYTE};
|
typed_pointer S = {NULL, DT_BYTE};
|
||||||
decode_DDDDD_table(cpustate, BITS(op,0x001f), &S);
|
decode_DDDDD_table(cpustate, BITS(op,0x001f), &S);
|
||||||
@ -2704,13 +2808,19 @@ static size_t dsp56k_op_do_2(dsp56k_core* cpustate, const UINT16 op, const UINT1
|
|||||||
/* TODO : L */
|
/* TODO : L */
|
||||||
|
|
||||||
cycles += 6; /* TODO: + mv oscillator cycles */
|
cycles += 6; /* TODO: + mv oscillator cycles */
|
||||||
|
retSize = 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Skip over the contents of the loop */
|
||||||
|
cpustate->ppc = PC;
|
||||||
|
PC = PC + 2 + op2;
|
||||||
|
|
||||||
cycles += 10; /* TODO: + mv oscillator cycles */
|
cycles += 10; /* TODO: + mv oscillator cycles */
|
||||||
|
retSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 2;
|
return retSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DO FOREVER : 0000 0000 0000 0010 xxxx xxxx xxxx xxxx : A-88 */
|
/* DO FOREVER : 0000 0000 0000 0010 xxxx xxxx xxxx xxxx : A-88 */
|
||||||
@ -2977,19 +3087,22 @@ static size_t dsp56k_op_macsuuu(dsp56k_core* cpustate, const UINT16 op, UINT8* c
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Signed * Unsigned */
|
/* Signed * Unsigned */
|
||||||
/* TODO: THERE IS A HUGE CHANCE THIS DOESN'T WORK RIGHT */
|
/* WARNING : THERE IS A HUGE CHANCE THIS DOESN'T WORK RIGHT */
|
||||||
UINT32 s1 = (UINT32)((INT32)(*((UINT16*)S1)));
|
INT32 s1 = ((INT32)(*((UINT16*)S1)));
|
||||||
UINT32 s2 = (UINT32)(*((UINT16*)S2));
|
INT32 s2 = (UINT32)(*((UINT16*)S2));
|
||||||
result = ( s1 * s2 ) << 1;
|
result = ( s1 * s2 ) << 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*((UINT64*)D)) += result;
|
(*((UINT64*)D)) += result;
|
||||||
|
|
||||||
|
/* And out the bits that don't live in the register */
|
||||||
|
(*((UINT64*)D)) &= U64(0x000000ffffffffff);
|
||||||
|
|
||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* - * * * * * * - */
|
/* - * * * * * * - */
|
||||||
/* TODO: L, E, U, V */
|
/* TODO: L, E, U, V */
|
||||||
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(cpustate, 1);
|
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
|
|
||||||
cycles += 2;
|
cycles += 2;
|
||||||
return 1;
|
return 1;
|
||||||
@ -3383,7 +3496,7 @@ static size_t dsp56k_op_movep_1(dsp56k_core* cpustate, const UINT16 op, UINT8* c
|
|||||||
pp = op & 0x001f;
|
pp = op & 0x001f;
|
||||||
pp = assemble_address_from_IO_short_address(cpustate, pp);
|
pp = assemble_address_from_IO_short_address(cpustate, pp);
|
||||||
|
|
||||||
W = BITS(OP,0x0100);
|
W = BITS(op,0x0100);
|
||||||
|
|
||||||
/* A little different than most W if's - opposite read and write */
|
/* A little different than most W if's - opposite read and write */
|
||||||
if (W)
|
if (W)
|
||||||
@ -3403,7 +3516,7 @@ static size_t dsp56k_op_movep_1(dsp56k_core* cpustate, const UINT16 op, UINT8* c
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Postincrement
|
// Postincrement
|
||||||
execute_m_table(cpustate, BITS(OP,0x00c0), BITS(OP,0x0020));
|
execute_m_table(cpustate, BITS(op,0x00c0), BITS(op,0x0020));
|
||||||
|
|
||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* * * - - - - - - */
|
/* * * - - - - - - */
|
||||||
@ -3423,9 +3536,47 @@ static size_t dsp56k_op_moves(dsp56k_core* cpustate, const UINT16 op, UINT8* cyc
|
|||||||
/* MPY(su,uu) : 0001 0101 1100 FsQQ : A-164 */
|
/* MPY(su,uu) : 0001 0101 1100 FsQQ : A-164 */
|
||||||
static size_t dsp56k_op_mpysuuu(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
|
static size_t dsp56k_op_mpysuuu(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
|
||||||
{
|
{
|
||||||
|
UINT8 s = 0;
|
||||||
|
INT64 result = 0;
|
||||||
|
|
||||||
|
void* D = NULL;
|
||||||
|
void* S1 = NULL;
|
||||||
|
void* S2 = NULL;
|
||||||
|
|
||||||
|
decode_QQF_special_table(cpustate, BITS(op,0x0003), BITS(op,0x0008), &S1, &S2, &D);
|
||||||
|
|
||||||
|
s = BITS(op,0x0004);
|
||||||
|
|
||||||
|
/* Fixed-point 2's complement multiplication requires a shift */
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
/* Unsigned * Unsigned */
|
||||||
|
UINT32 s1 = (UINT32)(*((UINT16*)S1));
|
||||||
|
UINT32 s2 = (UINT32)(*((UINT16*)S2));
|
||||||
|
result = ( s1 * s2 ) << 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Signed * Unsigned */
|
||||||
|
/* WARNING : THERE IS A HUGE CHANCE THIS DOESN'T WORK RIGHT */
|
||||||
|
INT32 s1 = ((INT32)(*((UINT16*)S1)));
|
||||||
|
INT32 s2 = (UINT32)(*((UINT16*)S2));
|
||||||
|
result = ( s1 * s2 ) << 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*((UINT64*)D)) = result;
|
||||||
|
|
||||||
|
/* And out the bits that don't live in the register */
|
||||||
|
(*((UINT64*)D)) &= U64(0x000000ffffffffff);
|
||||||
|
|
||||||
/* S L E U N Z V C */
|
/* S L E U N Z V C */
|
||||||
/* - * * * * * * - */
|
/* - * * * * * * - */
|
||||||
return 0;
|
/* TODO: L, E, U, V */
|
||||||
|
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1); else N_bit_set(cpustate, 0);
|
||||||
|
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(cpustate, 1); else Z_bit_set(cpustate, 0);
|
||||||
|
|
||||||
|
cycles += 2;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NEGC : 0001 0101 0110 F000 : A-168 */
|
/* NEGC : 0001 0101 0110 F000 : A-168 */
|
||||||
@ -3554,6 +3705,13 @@ static size_t dsp56k_op_reset(dsp56k_core* cpustate, const UINT16 op, UINT8* cyc
|
|||||||
/* RTI : 0000 0000 0000 0111 : A-194 */
|
/* RTI : 0000 0000 0000 0111 : A-194 */
|
||||||
static size_t dsp56k_op_rti(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
|
static size_t dsp56k_op_rti(dsp56k_core* cpustate, const UINT16 op, UINT8* cycles)
|
||||||
{
|
{
|
||||||
|
/* WARNING : THERE SHOULD BE A MORE GENERAL HANDLING OF STACK ERRORS. */
|
||||||
|
if (SP == 0)
|
||||||
|
{
|
||||||
|
dsp56k_add_pending_interrupt(cpustate, "Stack Error");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
cpustate->ppc = PC;
|
cpustate->ppc = PC;
|
||||||
PC = SSH;
|
PC = SSH;
|
||||||
|
|
||||||
@ -3786,6 +3944,23 @@ static void decode_DD_table(dsp56k_core* cpustate, UINT16 DD, typed_pointer* ret
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void decode_DDF_table(dsp56k_core* cpustate, UINT16 DD, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret)
|
||||||
|
{
|
||||||
|
UINT16 switchVal = (DD << 1) | F;
|
||||||
|
|
||||||
|
switch (switchVal)
|
||||||
|
{
|
||||||
|
case 0x0: src_ret->addr = &X0; src_ret->data_type = DT_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
|
||||||
|
case 0x1: src_ret->addr = &X0; src_ret->data_type = DT_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
|
||||||
|
case 0x2: src_ret->addr = &Y0; src_ret->data_type = DT_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
|
||||||
|
case 0x3: src_ret->addr = &Y0; src_ret->data_type = DT_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
|
||||||
|
case 0x4: src_ret->addr = &X1; src_ret->data_type = DT_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
|
||||||
|
case 0x5: src_ret->addr = &X1; src_ret->data_type = DT_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
|
||||||
|
case 0x6: src_ret->addr = &Y1; src_ret->data_type = DT_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
|
||||||
|
case 0x7: src_ret->addr = &Y1; src_ret->data_type = DT_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void decode_F_table(dsp56k_core* cpustate, UINT16 F, typed_pointer* ret)
|
static void decode_F_table(dsp56k_core* cpustate, UINT16 F, typed_pointer* ret)
|
||||||
{
|
{
|
||||||
switch(F)
|
switch(F)
|
||||||
@ -4250,7 +4425,7 @@ static void dsp56k_process_loop(dsp56k_core* cpustate)
|
|||||||
if (LC == 1)
|
if (LC == 1)
|
||||||
{
|
{
|
||||||
/* End of loop processing */
|
/* End of loop processing */
|
||||||
SR = SSL; /* TODO: A-83. I believe only the Loop Flag comes back here. */
|
SR = SSL; /* TODO: A-83. I believe only the Loop Flag comes back here. And maybe the do forever bit too. */
|
||||||
SP--;
|
SP--;
|
||||||
|
|
||||||
LA = SSH;
|
LA = SSH;
|
||||||
@ -4531,9 +4706,10 @@ static void SetDestinationValue(typed_pointer source, typed_pointer dest)
|
|||||||
{
|
{
|
||||||
case DT_BYTE: *((UINT64*)dest.addr) = (*((UINT8*)source.addr)) & 0xff; break;
|
case DT_BYTE: *((UINT64*)dest.addr) = (*((UINT8*)source.addr)) & 0xff; break;
|
||||||
|
|
||||||
case DT_WORD: destinationValue = (*((INT16*)source.addr)) << 16; /* Sign extend */
|
case DT_WORD: destinationValue = (*((UINT16*)source.addr)) << 16;
|
||||||
destinationValue &= U64(0x000000ffffff0000);
|
if (destinationValue & U64(0x0000000080000000))
|
||||||
*((UINT64*)dest.addr) = destinationValue; break; /* Forget not, yon shift register */
|
destinationValue |= U64(0x000000ff00000000);
|
||||||
|
*((UINT64*)dest.addr) = (UINT64)destinationValue; break; /* Forget not, yon shift register */
|
||||||
|
|
||||||
case DT_DOUBLE_WORD: *((UINT64*)dest.addr) = (*((UINT32*)source.addr)) & 0xffffffff; break;
|
case DT_DOUBLE_WORD: *((UINT64*)dest.addr) = (*((UINT32*)source.addr)) & 0xffffffff; break;
|
||||||
case DT_LONG_WORD: *((UINT64*)dest.addr) = (*((UINT64*)source.addr)) & U64(0x000000ffffffffff); break;
|
case DT_LONG_WORD: *((UINT64*)dest.addr) = (*((UINT64*)source.addr)) & U64(0x000000ffffffffff); break;
|
||||||
|
@ -142,7 +142,7 @@ static void pcu_reset(dsp56k_core* cpustate)
|
|||||||
// This, in actuality, is handled with the internal boot ROM.
|
// This, in actuality, is handled with the internal boot ROM.
|
||||||
for (i = 0; i < 0x800; i++)
|
for (i = 0; i < 0x800; i++)
|
||||||
{
|
{
|
||||||
UINT32 mem_offset = (0xc0000<<1) + (i<<1); /* TODO: TEST */
|
UINT32 mem_offset = (0xc000<<1) + (i<<1); /* TODO: TEST */
|
||||||
|
|
||||||
// TODO - DO I HAVE TO FLIP THIS WORD?
|
// TODO - DO I HAVE TO FLIP THIS WORD?
|
||||||
// P:$c000 -> Internal P:$0000 low byte
|
// P:$c000 -> Internal P:$0000 low byte
|
||||||
|
@ -189,14 +189,12 @@ static READ32_HANDLER( psac_rom_r )
|
|||||||
/* irq 3 is network. don't generate if you don't emulate the network h/w! */
|
/* irq 3 is network. don't generate if you don't emulate the network h/w! */
|
||||||
/* irq 5 is vblank */
|
/* irq 5 is vblank */
|
||||||
/* irq 7 does nothing (it jsrs to a rts and then rte) */
|
/* irq 7 does nothing (it jsrs to a rts and then rte) */
|
||||||
|
|
||||||
static INTERRUPT_GEN(polygonet_interrupt)
|
static INTERRUPT_GEN(polygonet_interrupt)
|
||||||
{
|
{
|
||||||
cpu_set_input_line(device, M68K_IRQ_5, HOLD_LINE);
|
cpu_set_input_line(device, M68K_IRQ_5, HOLD_LINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sound CPU communications */
|
/* sound CPU communications */
|
||||||
|
|
||||||
static READ32_HANDLER( sound_r )
|
static READ32_HANDLER( sound_r )
|
||||||
{
|
{
|
||||||
int latch = soundlatch3_r(space, 0);
|
int latch = soundlatch3_r(space, 0);
|
||||||
@ -286,8 +284,7 @@ static WRITE32_HANDLER( dsp_w_lines )
|
|||||||
cputag_set_input_line(space->machine, "dsp", DSP56K_IRQ_MODB, CLEAR_LINE);
|
cputag_set_input_line(space->machine, "dsp", DSP56K_IRQ_MODB, CLEAR_LINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 0x04000000 is the ??? line */
|
/* 0x04000000 is the COMBNK line - it switches who has access to the shared RAM - the dsp or the 68020 */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static WRITE32_HANDLER( dsp_host_interface_w )
|
static WRITE32_HANDLER( dsp_host_interface_w )
|
||||||
@ -311,6 +308,21 @@ static READ32_HANDLER( network_r )
|
|||||||
return 0x08000000;
|
return 0x08000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WRITE32_HANDLER( plygonet_palette_w )
|
||||||
|
{
|
||||||
|
int r,g,b;
|
||||||
|
|
||||||
|
COMBINE_DATA(&paletteram32[offset]);
|
||||||
|
|
||||||
|
r = (paletteram32[offset] >>16) & 0xff;
|
||||||
|
g = (paletteram32[offset] >> 8) & 0xff;
|
||||||
|
b = (paletteram32[offset] >> 0) & 0xff;
|
||||||
|
|
||||||
|
palette_set_color(space->machine,offset,MAKE_RGB(r,g,b));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************************/
|
/**********************************************************************************/
|
||||||
/******* DSP56k maps *******/
|
/******* DSP56k maps *******/
|
||||||
/**********************************************************************************/
|
/**********************************************************************************/
|
||||||
@ -506,20 +518,6 @@ static WRITE16_HANDLER( dsp56k_ram_bank04_write )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WRITE32_HANDLER( plygonet_palette_w )
|
|
||||||
{
|
|
||||||
int r,g,b;
|
|
||||||
|
|
||||||
COMBINE_DATA(&paletteram32[offset]);
|
|
||||||
|
|
||||||
r = (paletteram32[offset] >>16) & 0xff;
|
|
||||||
g = (paletteram32[offset] >> 8) & 0xff;
|
|
||||||
b = (paletteram32[offset] >> 0) & 0xff;
|
|
||||||
|
|
||||||
palette_set_color(space->machine,offset,MAKE_RGB(r,g,b));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************************/
|
/**********************************************************************************/
|
||||||
|
|
||||||
static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 32 )
|
static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 32 )
|
||||||
|
Loading…
Reference in New Issue
Block a user