mirror of
https://github.com/holub/mame
synced 2025-05-23 22:20:01 +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;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
op_byte = op & 0x00ff;
|
||||
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)
|
||||
{
|
||||
op_byte = op & 0x00ff;
|
||||
parallelType = kRegisterToRegister;
|
||||
}
|
||||
/* Address Register Update : 0011 0zRR ---- ---- : A-135 */
|
||||
/* Address Register Update : 0011 0zRR .... .... : A-135 */
|
||||
else if ((op & 0xf800) == 0x3000)
|
||||
{
|
||||
op_byte = op & 0x00ff;
|
||||
parallelType = kAddressRegister;
|
||||
}
|
||||
/* X Memory Data Move : 1mRR HHHW ---- ---- : A-137 */
|
||||
/* X Memory Data Move : 1mRR HHHW .... .... : A-137 */
|
||||
else if ((op & 0x8000) == 0x8000)
|
||||
{
|
||||
op_byte = op & 0x00ff;
|
||||
parallelType = kXMemoryDataMove;
|
||||
}
|
||||
/* X Memory Data Move : 0101 HHHW ---- ---- : A-137 */
|
||||
/* X Memory Data Move : 0101 HHHW .... .... : A-137 */
|
||||
else if ((op & 0xf000) == 0x5000)
|
||||
{
|
||||
op_byte = op & 0x00ff;
|
||||
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)
|
||||
{
|
||||
/* Now check it against all the other potential collisions */
|
||||
|
@ -242,7 +242,7 @@ static CPU_RESET( dsp56k )
|
||||
agu_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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
/************************/
|
||||
@ -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 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_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_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);
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/* TODO: Verify : Sign-extend everyone for proper add/sub op */
|
||||
if (useVal & U64(0x0000000080000000))
|
||||
useVal |= U64(0xffffffff00000000);
|
||||
/* Sign-extend word for proper add/sub op */
|
||||
if ((S.data_type == DT_WORD) && useVal & U64(0x0000000080000000))
|
||||
useVal |= U64(0x000000ff00000000);
|
||||
|
||||
/* Operate*/
|
||||
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 */
|
||||
/* * * * * * * * * */
|
||||
/* TODO S, L, E, U, V, C */
|
||||
if (*((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
||||
if (*((UINT64*)D.addr) == 0) Z_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); else Z_bit_set(cpustate, 0);
|
||||
|
||||
cycles += 2; /* TODO: + mv oscillator cycles */
|
||||
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 */
|
||||
/* * * * * * * * - */
|
||||
/* TODO: S, L, E, V */
|
||||
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
||||
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_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); else Z_bit_set(cpustate, 0);
|
||||
|
||||
cycles += 2; /* TODO: +mv oscillator cycles */
|
||||
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 */
|
||||
/* * * * * * * * - */
|
||||
/* TODO: S, L, E, V */
|
||||
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
||||
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_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); else Z_bit_set(cpustate, 0);
|
||||
|
||||
cycles += 2; /* TODO: +mv oscillator cycles */
|
||||
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;
|
||||
}
|
||||
|
||||
/* TODO: Verify : Sign-extend everyone for proper addition op */
|
||||
if (addVal & U64(0x0000000080000000))
|
||||
addVal |= U64(0xffffffff00000000);
|
||||
/* Sign-extend word for proper add/sub op */
|
||||
if ((S.data_type == DT_WORD) && addVal & U64(0x0000000080000000))
|
||||
addVal |= U64(0x000000ff00000000);
|
||||
|
||||
/* Operate*/
|
||||
*((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 */
|
||||
/* * * * * * * * * */
|
||||
/* TODO S, L, E, U, V, C */
|
||||
if (*((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
||||
if (*((UINT64*)D.addr) == 0) Z_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); else Z_bit_set(cpustate, 0);
|
||||
|
||||
cycles += 2; /* TODO: + mv oscillator cycles */
|
||||
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 */
|
||||
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 */
|
||||
/* * * * * * * * - */
|
||||
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 */
|
||||
@ -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 */
|
||||
/* * * * * * * * * */
|
||||
/* TODO: S, L, E, U, V, C */
|
||||
if ( *((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
||||
if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) Z_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); else Z_bit_set(cpustate, 0);
|
||||
|
||||
cycles += 2; /* TODO: +mv oscillator cycles */
|
||||
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 */
|
||||
/* * * * * * ? * * */
|
||||
/* TODO: S, L, E, U, V, C */
|
||||
if ( *((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
||||
if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) Z_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); else Z_bit_set(cpustate, 0);
|
||||
|
||||
cycles += 2; /* TODO: + mv oscillator clock cycles */
|
||||
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 */
|
||||
/* * * * * * * 0 ? */
|
||||
/* TODO: S, L, E, U */
|
||||
if (*((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
||||
if (*((UINT64*)D.addr) == 0) Z_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); else Z_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 */
|
||||
return 1;
|
||||
@ -1577,9 +1607,9 @@ static size_t dsp56k_op_lsr(dsp56k_core* cpustate, const UINT16 op_byte, typed_p
|
||||
/* * * - - ? ? 0 ? */
|
||||
/* TODO: S, L */
|
||||
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);
|
||||
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 */
|
||||
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)
|
||||
{
|
||||
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_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;
|
||||
|
||||
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 */
|
||||
/* * * * * * * * * */
|
||||
/* 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 */
|
||||
@ -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 */
|
||||
/* * * - - ? ? 0 - */
|
||||
/* TODO: S?, L */
|
||||
if ( *((UINT64*)D.addr) & U64(0x0000000080000000)) N_bit_set(cpustate, 1);
|
||||
if ((*((UINT64*)D.addr) & U64(0x00000000ffff0000)) == 0) Z_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); else Z_bit_set(cpustate, 0);
|
||||
V_bit_set(cpustate, 0);
|
||||
|
||||
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 */
|
||||
/* * * * * * ? * * */
|
||||
/* TODO: S, L, E, U, V, C */
|
||||
if ( *((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
||||
if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) Z_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); else Z_bit_set(cpustate, 0);
|
||||
|
||||
cycles += 2; /* TODO: + mv oscillator clock cycles */
|
||||
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 */
|
||||
/* * * - - ? ? 0 - */
|
||||
/* TODO: S, L */
|
||||
if ( *((UINT64*)D.addr) & U64(0x0000000080000000)) N_bit_set(cpustate, 1);
|
||||
if ((*((UINT64*)D.addr) & U64(0x00000000ffff0000)) == 0) Z_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); else Z_bit_set(cpustate, 0);
|
||||
V_bit_set(cpustate, 0);
|
||||
|
||||
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 */
|
||||
/* * * * * * * * - */
|
||||
/* TODO: S, L, E, V */
|
||||
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
||||
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_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); else Z_bit_set(cpustate, 0);
|
||||
|
||||
cycles += 2; /* TODO: +mv oscillator cycles */
|
||||
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 */
|
||||
/* * * * * * * * - */
|
||||
/* TODO: S, L, E, V */
|
||||
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
||||
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_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); else Z_bit_set(cpustate, 0);
|
||||
|
||||
cycles += 2; /* TODO: +mv oscillator cycles */
|
||||
return 1;
|
||||
@ -2015,6 +2054,9 @@ static size_t dsp56k_op_macr(dsp56k_core* cpustate, const UINT16 op_byte, typed_
|
||||
|
||||
/* Round the result */
|
||||
/* WARNING : ROUNDING NOT FULLY IMPLEMENTED YET! */
|
||||
if ((opD & U64(0x000000000000ffff)) >= 0x8000)
|
||||
opD += U64(0x0000000000010000);
|
||||
|
||||
opD &= U64(0x000000ffffff0000);
|
||||
|
||||
/* 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 */
|
||||
/* * * * * * * * - */
|
||||
/* TODO: S, L, E, V */
|
||||
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
||||
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_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); else Z_bit_set(cpustate, 0);
|
||||
|
||||
cycles += 2; /* TODO: +mv oscillator cycles */
|
||||
return 1;
|
||||
@ -2184,7 +2226,7 @@ static size_t dsp56k_op_bfop(dsp56k_core* cpustate, const UINT16 op, const UINT1
|
||||
UINT16 iVal = op2 & 0x00ff;
|
||||
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));
|
||||
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 !!! */
|
||||
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 */
|
||||
/* - * - - - - ? ? */
|
||||
/* 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. */
|
||||
/* 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 */
|
||||
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 */
|
||||
/* - * * * * * * - */
|
||||
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 */
|
||||
@ -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 */
|
||||
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);
|
||||
|
||||
/* 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 */
|
||||
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 */
|
||||
/* - * - - - - - - */
|
||||
/* TODO : L */
|
||||
|
||||
cycles += 6; /* TODO: + mv oscillator cycles */
|
||||
retSize = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skip over the contents of the loop */
|
||||
cpustate->ppc = PC;
|
||||
PC = PC + 2 + op2;
|
||||
|
||||
cycles += 10; /* TODO: + mv oscillator cycles */
|
||||
retSize = 0;
|
||||
}
|
||||
|
||||
return 2;
|
||||
return retSize;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
UINT8 retSize = 0;
|
||||
UINT16 lValue = 0x0000;
|
||||
typed_pointer S = {NULL, DT_BYTE};
|
||||
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 */
|
||||
|
||||
cycles += 6; /* TODO: + mv oscillator cycles */
|
||||
retSize = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skip over the contents of the loop */
|
||||
cpustate->ppc = PC;
|
||||
PC = PC + 2 + op2;
|
||||
|
||||
cycles += 10; /* TODO: + mv oscillator cycles */
|
||||
retSize = 0;
|
||||
}
|
||||
|
||||
return 2;
|
||||
return retSize;
|
||||
}
|
||||
|
||||
/* 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
|
||||
{
|
||||
/* Signed * Unsigned */
|
||||
/* TODO: THERE IS A HUGE CHANCE THIS DOESN'T WORK RIGHT */
|
||||
UINT32 s1 = (UINT32)((INT32)(*((UINT16*)S1)));
|
||||
UINT32 s2 = (UINT32)(*((UINT16*)S2));
|
||||
/* 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 */
|
||||
/* - * * * * * * - */
|
||||
/* TODO: L, E, U, V */
|
||||
if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(cpustate, 1);
|
||||
if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_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); else Z_bit_set(cpustate, 0);
|
||||
|
||||
cycles += 2;
|
||||
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 = 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 */
|
||||
if (W)
|
||||
@ -3403,7 +3516,7 @@ static size_t dsp56k_op_movep_1(dsp56k_core* cpustate, const UINT16 op, UINT8* c
|
||||
}
|
||||
|
||||
// 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 */
|
||||
/* * * - - - - - - */
|
||||
@ -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 */
|
||||
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 */
|
||||
/* - * * * * * * - */
|
||||
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 */
|
||||
@ -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 */
|
||||
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;
|
||||
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)
|
||||
{
|
||||
switch(F)
|
||||
@ -4250,7 +4425,7 @@ static void dsp56k_process_loop(dsp56k_core* cpustate)
|
||||
if (LC == 1)
|
||||
{
|
||||
/* 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--;
|
||||
|
||||
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_WORD: destinationValue = (*((INT16*)source.addr)) << 16; /* Sign extend */
|
||||
destinationValue &= U64(0x000000ffffff0000);
|
||||
*((UINT64*)dest.addr) = destinationValue; break; /* Forget not, yon shift register */
|
||||
case DT_WORD: destinationValue = (*((UINT16*)source.addr)) << 16;
|
||||
if (destinationValue & U64(0x0000000080000000))
|
||||
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_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.
|
||||
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?
|
||||
// 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 5 is vblank */
|
||||
/* irq 7 does nothing (it jsrs to a rts and then rte) */
|
||||
|
||||
static INTERRUPT_GEN(polygonet_interrupt)
|
||||
{
|
||||
cpu_set_input_line(device, M68K_IRQ_5, HOLD_LINE);
|
||||
}
|
||||
|
||||
/* sound CPU communications */
|
||||
|
||||
static READ32_HANDLER( sound_r )
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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 )
|
||||
@ -311,6 +308,21 @@ static READ32_HANDLER( network_r )
|
||||
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 *******/
|
||||
/**********************************************************************************/
|
||||
@ -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 )
|
||||
|
Loading…
Reference in New Issue
Block a user