summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Andrew Gardner <andrew-gardner@users.noreply.github.com>2008-10-22 04:15:30 +0000
committer Andrew Gardner <andrew-gardner@users.noreply.github.com>2008-10-22 04:15:30 +0000
commit40a5d0c5435c47bddb353f339b023688b1964f31 (patch)
tree092b9f69021e5d41c7c0bb789694ef6a2bd81a7c /src
parenta30f534c524ba3f9976b93a309cf2ebcdad82660 (diff)
Rewrite of the Motorola DSP56k CPU core. (Andrew Gardner)
* Implemented tst, or, jsr, rti, tst2, and 2 new movec ops. * Added opbase handler to plygonet.c
Diffstat (limited to 'src')
-rw-r--r--src/emu/cpu/dsp56k/dsp56ops.c213
-rw-r--r--src/mame/drivers/plygonet.c30
2 files changed, 213 insertions, 30 deletions
diff --git a/src/emu/cpu/dsp56k/dsp56ops.c b/src/emu/cpu/dsp56k/dsp56ops.c
index 669cee60f96..4484a38f4cb 100644
--- a/src/emu/cpu/dsp56k/dsp56ops.c
+++ b/src/emu/cpu/dsp56k/dsp56ops.c
@@ -181,13 +181,11 @@ static void decode_JJJF_table(UINT16 JJJ, UINT16 F, typed_pointer* src_ret, type
static void decode_JJF_table(UINT16 JJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
static void decode_QQF_special_table(UINT16 QQ, UINT16 F, void **S1, void **S2, void **D);
static void decode_RR_table(UINT16 RR, typed_pointer* ret);
-#ifdef UNUSED_FUNCTION
static void decode_Z_table(UINT16 Z, typed_pointer* ret);
-#endif
static void execute_m_table(int x, UINT16 m);
static void execute_MM_table(UINT16 rnum, UINT16 MM);
-#ifdef UNUSED_FUNCTION
static UINT16 execute_q_table(int x, UINT16 q);
+#ifdef UNUSED_FUNCTION
static void execute_z_table(int x, UINT16 z);
#endif
static UINT16 assemble_address_from_Pppppp_table(UINT16 P, UINT16 ppppp);
@@ -1258,9 +1256,25 @@ static size_t dsp56k_op_rnd(const UINT16 op_byte, typed_pointer* d_register, UIN
/* TST : .... .... 0010 F001 : A-218 */
static size_t dsp56k_op_tst(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
{
+ typed_pointer D = {NULL, DT_LONG_WORD};
+
+ decode_F_table(BITS(op_byte,0x0008), &D);
+
+ *p_accum = *((UINT64*)D.addr);
+
+ d_register->addr = D.addr;
+ d_register->data_type = D.data_type;
+
/* S L E U N Z V C */
/* 0 * * * * * 0 0 */
- return 0;
+ /* TODO: S, L, E, U */
+ if ((*((UINT64*)D.addr)) & U64(0x0000008000000000)) N_bit_set(1); else N_bit_set(0);
+ if ((*((UINT64*)D.addr)) == 0) Z_bit_set(1); else Z_bit_set(0);
+ V_bit_set(0);
+ C_bit_set(0);
+
+ cycles += 2; /* TODO: + mv oscillator clock cycles */
+ return 1;
}
/* INC : .... .... 0010 F010 : A-104 */
@@ -1283,11 +1297,29 @@ static size_t dsp56k_op_inc24(const UINT16 op_byte, typed_pointer* d_register, U
/* OR : .... .... 0010 F1JJ : A-176 */
static size_t dsp56k_op_or(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
{
+ typed_pointer S = {NULL, DT_BYTE};
+ typed_pointer D = {NULL, DT_BYTE};
+
+ decode_JJF_table(BITS(op_byte,0x0003), BITS(op_byte,0x0008), &S, &D);
+
+ /* Save some data for the parallel move */
+ *p_accum = *((UINT64*)D.addr);
+
+ /* OR a word of S with A1|B1 */
+ ((PAIR64*)D.addr)->w.h = *((UINT16*)S.addr) | ((PAIR64*)D.addr)->w.h;
+
+ d_register->addr = D.addr;
+ d_register->data_type = D.data_type;
+
/* S L E U N Z V C */
/* * * - - ? ? 0 - */
- /* N - Set if bit 31 of the result is set. Cleared otherwise. */
- /* Z - Set if bits 16-31 of the result are zero. Cleared otherwise. */
- return 0;
+ /* TODO: S, L */
+ if ( *((UINT64*)D.addr) & U64(0x0000000080000000)) N_bit_set(1); else N_bit_set(0);
+ if ((*((UINT64*)D.addr) & U64(0x00000000ffff0000)) == 0) Z_bit_set(1); else Z_bit_set(0);
+ V_bit_set(0);
+
+ cycles += 2; /* TODO: + mv oscillator cycles */
+ return 1;
}
/* ASR : .... .... 0011 F000 : A-32 */
@@ -1540,7 +1572,10 @@ static size_t dsp56k_op_and(const UINT16 op_byte, typed_pointer* d_register, UIN
/* AND a word of S with A1|B1 */
((PAIR64*)D.addr)->w.h = *((UINT16*)S.addr) & ((PAIR64*)D.addr)->w.h;
-
+
+ d_register->addr = D.addr;
+ d_register->data_type = D.data_type;
+
/* S L E U N Z V C */
/* * * - - ? ? 0 - */
/* TODO: S, L */
@@ -1913,9 +1948,9 @@ static size_t dsp56k_op_bcc_1(const UINT16 op, UINT8* cycles)
INT16 offset = (INT16)assemble_address_from_6bit_signed_relative_short_address(BITS(op,0x003f));
PC += 1;
+
core.ppc = PC;
PC += offset;
-
change_pc(PC) ;
cycles += 4;
@@ -2320,8 +2355,23 @@ static size_t dsp56k_op_jscc_1(const UINT16 op, UINT8* cycles)
/* JSR : 0000 0001 0011 00-- xxxx xxxx xxxx xxxx : A-114 */
static size_t dsp56k_op_jsr(const UINT16 op, const UINT16 op2, UINT8* cycles)
{
+ /* TODO: It says "signed" absolute offset. Weird. */
+ UINT16 branchOffset = op2;
+
+ /* TODO: Verify, since it's not in the docs, but it must be true */
+ PC += 2;
+
+ SP++;
+ SSH = PC;
+ SSL = SR;
+
+ core.ppc = PC;
+ PC = branchOffset;
+ change_pc(PC);
+
/* S L E U N Z V C */
/* - - - - - - - - */
+ cycles += 4; /* TODO: + jx oscillator cycles */
return 0;
}
@@ -2452,23 +2502,87 @@ static size_t dsp56k_op_movec(const UINT16 op, UINT8* cycles)
/* MOVE(C) : 0011 1WDD DDD1 q0RR : A-144 */
static size_t dsp56k_op_movec_1(const UINT16 op, UINT8* cycles)
{
+ UINT8 W;
+ UINT16 memOffset;
+ typed_pointer SD = {NULL, DT_BYTE};
+
+ W = BITS(op,0x0400);
+ decode_DDDDD_table(BITS(op,0x03e0), &SD);
+ memOffset = execute_q_table(BITS(op,0x0003), BITS(op,0x0008));
+
+ if (W)
+ {
+ /* Write D */
+ UINT16 tempData = data_read_word_16le(WORD(memOffset));
+ typed_pointer temp_src = { (void*)&tempData, DT_WORD };
+ SetDestinationValue(temp_src, SD);
+ }
+ else
+ {
+ /* Read S */
+ UINT16 tempData = *((UINT16*)SD.addr);
+ typed_pointer temp_src = { (void*)&tempData, DT_WORD };
+ SetDataMemoryValue(temp_src, WORD(memOffset));
+ }
+
/* S L E U N Z V C */
/* * ? ? ? ? ? ? ? */
/* All ? bits - If SR is specified as a destination operand, set according to the corresponding
bit of the source operand. If SR is not specified as a destination operand, L is set if data
limiting occurred. All ? bits are not affected otherwise.*/
- return 0;
+ if (W && (SD.addr != &SR))
+ {
+ /* If you're writing to something other than the SR */
+ /* TODO */
+ }
+
+ cycles += 2; /* + mvc oscillator clock cycles */
+ return 1;
}
/* MOVE(C) : 0011 1WDD DDD1 Z11- : A-144 */
static size_t dsp56k_op_movec_2(const UINT16 op, UINT8* cycles)
{
+ UINT8 W;
+ UINT16 memOffset;
+ typed_pointer SD = {NULL, DT_BYTE};
+ typed_pointer XMemOffset = {NULL, DT_BYTE};
+
+ W = BITS(op,0x0400);
+ decode_Z_table(BITS(op,0x0008), &XMemOffset);
+ decode_DDDDD_table(BITS(op,0x03e0), &SD);
+
+ memOffset = *((UINT16*)XMemOffset.addr);
+
+ if (W)
+ {
+ /* Write D */
+ UINT16 tempData = data_read_word_16le(WORD(memOffset));
+ typed_pointer temp_src = { (void*)&tempData, DT_WORD };
+ SetDestinationValue(temp_src, SD);
+ }
+ else
+ {
+ /* Read S */
+ UINT16 tempData = *((UINT16*)SD.addr);
+ typed_pointer temp_src = { (void*)&tempData, DT_WORD };
+ SetDataMemoryValue(temp_src, WORD(memOffset));
+ }
+
+
/* S L E U N Z V C */
/* * ? ? ? ? ? ? ? */
/* All ? bits - If SR is specified as a destination operand, set according to the corresponding
bit of the source operand. If SR is not specified as a destination operand, L is set if data
limiting occurred. All ? bits are not affected otherwise.*/
- return 0;
+ if (W && (SD.addr != &SR))
+ {
+ /* If you're writing to something other than the SR */
+ /* TODO */
+ }
+
+ cycles += 2; /* + mvc oscillator clock cycles */
+ return 1;
}
/* MOVE(C) : 0011 1WDD DDD1 t10- xxxx xxxx xxxx xxxx : A-144 */
@@ -2803,16 +2917,43 @@ static size_t dsp56k_op_rep_1(const UINT16 op, UINT8* cycles)
/* S L E U N Z V C */
/* - * - - - - - - */
- /* TODO */
+ /* TODO: L */
return 1;
}
/* REP : 0000 0100 001D DDDD : A-180 */
static size_t dsp56k_op_rep_2(const UINT16 op, UINT8* cycles)
{
+ /* TODO: This is non-interruptable, probably have to turn off interrupts here */
+ UINT16 repValue;
+ typed_pointer D = {NULL, DT_BYTE};
+ decode_DDDDD_table(BITS(op,0x001f), &D);
+
+ /* TODO: handle special A&B source cases */
+ if (D.addr == &A || D.addr == &B)
+ logerror("DSP56k ERROR : Rep with A or B instruction not implemented yet!\n");
+
+ repValue = *((UINT16*)D.addr);
+
+ if (repValue != 0)
+ {
+ TEMP = LC;
+ LC = repValue;
+
+ core.repFlag = 1;
+ core.repAddr = PC + WORD(1);
+
+ cycles += 4; /* TODO: + mv oscillator clock cycles */
+ }
+ else
+ {
+ cycles += 6; /* TODO: + mv oscillator clock cycles */
+ }
+
/* S L E U N Z V C */
/* - * - - - - - - */
- return 0;
+ /* TODO: L */
+ return 1;
}
/* REPcc : 0000 0001 0101 cccc : A-184 */
@@ -2834,9 +2975,17 @@ static size_t dsp56k_op_reset(const UINT16 op, UINT8* cycles)
/* RTI : 0000 0000 0000 0111 : A-194 */
static size_t dsp56k_op_rti(const UINT16 op, UINT8* cycles)
{
+ core.ppc = PC;
+ PC = SSH;
+ change_pc(PC);
+
+ SR = SSL;
+ SP = SP - 1;
+
/* S L E U N Z V C */
- /* - ? ? ? ? ? ? ? */
+ /* ? ? ? ? ? ? ? ? */
/* All ? bits - Set according to value pulled from the stack. */
+ cycles += 4; /* TODO: + rx oscillator clock cycles */
return 0;
}
@@ -2927,10 +3076,22 @@ static size_t dsp56k_op_tfr3(const UINT16 op, UINT8* cycles)
/* TST(2) : 0001 0101 0001 -1DD : A-220 */
static size_t dsp56k_op_tst2(const UINT16 op, UINT8* cycles)
{
+ typed_pointer D = {NULL, DT_BYTE};
+ decode_DD_table(BITS(op,0x0003), &D);
+
/* S L E U N Z V C */
/* - * * * * * 0 0 */
/* (L,E,U should be set to 0) */
- return 0;
+ L_bit_set(0);
+ E_bit_set(0);
+ // U_bit_set(0); /* TODO: Conflicting opinions? "Set if unnormalized." Documentation is weird (A&B?) */
+ if ((*((UINT16*)D.addr)) & 0x8000) N_bit_set(1); else N_bit_set(0);
+ if ((*((UINT16*)D.addr)) == 0x0000) Z_bit_set(1); else Z_bit_set(0);
+ // V_bit_set(0); /* TODO: Verify as well! */
+ C_bit_set(0);
+
+ cycles += 2;
+ return 1;
}
/* WAIT : 0000 0000 0000 1011 : A-222 */
@@ -3193,7 +3354,7 @@ static void decode_RR_table(UINT16 RR, typed_pointer* ret)
case 0x03: ret->addr = &R3; ret->data_type = DT_WORD; break;
}
}
-#ifdef UNUSED_FUNCTION
+
static void decode_Z_table(UINT16 Z, typed_pointer* ret)
{
switch(Z)
@@ -3203,7 +3364,7 @@ static void decode_Z_table(UINT16 Z, typed_pointer* ret)
case 0x00: ret->addr = &B1; ret->data_type = DT_WORD; break;
}
}
-#endif
+
static void execute_m_table(int x, UINT16 m)
{
UINT16 *rX = 0x00 ;
@@ -3245,19 +3406,19 @@ static void execute_MM_table(UINT16 rnum, UINT16 MM)
case 0x3: (*rX) = (*rX)+(*nX) ; break;
}
}
-#ifdef UNUSED_FUNCTION
-// Returns R address
+
+/* Returns R value */
static UINT16 execute_q_table(int x, UINT16 q)
{
- UINT16 *rX = 0x00 ;
- UINT16 *nX = 0x00 ;
+ UINT16 *rX = 0x0000;
+ UINT16 *nX = 0x0000;
switch(x)
{
- case 0x0: rX = &R0 ; nX = &N0 ; break ;
- case 0x1: rX = &R1 ; nX = &N1 ; break ;
- case 0x2: rX = &R2 ; nX = &N2 ; break ;
- case 0x3: rX = &R3 ; nX = &N3 ; break ;
+ case 0x0: rX = &R0; nX = &N0; break;
+ case 0x1: rX = &R1; nX = &N1; break;
+ case 0x2: rX = &R2; nX = &N2; break;
+ case 0x3: rX = &R3; nX = &N3; break;
}
switch(q)
@@ -3266,10 +3427,12 @@ static UINT16 execute_q_table(int x, UINT16 q)
case 0x1: (*rX)--; return (*rX); break; // This one is special - it's a *PRE-decrement*!
}
+ /* Should not get here */
exit(1);
return 0x00;
}
+#ifdef UNUSED_FUNCTION
static void execute_z_table(int x, UINT16 z)
{
UINT16 *rX = 0x00 ;
diff --git a/src/mame/drivers/plygonet.c b/src/mame/drivers/plygonet.c
index cf13fd6d08a..7ded9ca7261 100644
--- a/src/mame/drivers/plygonet.c
+++ b/src/mame/drivers/plygonet.c
@@ -64,6 +64,7 @@ static int init_eeprom_count;
static UINT32* shared_ram;
static UINT16* dsp56k_p_mirror;
+static UINT16* dsp56k_p_8000;
static const UINT16 dsp56k_bank00_size = 0x1000; static UINT16* dsp56k_bank00_ram;
static const UINT16 dsp56k_bank01_size = 0x1000; static UINT16* dsp56k_bank01_ram;
static const UINT16 dsp56k_bank02_size = 0x4000; static UINT16* dsp56k_bank02_ram;
@@ -286,6 +287,21 @@ static READ16_HANDLER( dsp56k_bootload_r )
return 0x7fff;
}
+static OPBASE_HANDLER( plygonet_dsp56k_opbase_handler )
+{
+ if (address >= 0x7000 && address <= 0x7fff)
+ {
+ opbase->rom = opbase->ram = (void*)(dsp56k_p_mirror - 0x7000);
+ return ~0;
+ }
+ else if (address >= 0x8000 && address <= 0x87ff)
+ {
+ opbase->rom = opbase->ram = (void*)(dsp56k_p_8000 - 0x8000);
+ return ~0;
+ }
+
+ return address;
+}
/* The dsp56k's Port C Data register (0xffe3) :
Program code (function 4e) configures it as general purpose output I/O pins (ffc1 = 0000 & ffc3 = 0fff).
@@ -465,6 +481,7 @@ static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 32 )
AM_RANGE(0x580000, 0x5807ff) AM_RAM
AM_RANGE(0x580800, 0x580803) AM_READWRITE(network_r, SMH_NOP)
AM_RANGE(0x580800, 0x580803) AM_RAM /* network RAM | registers? */
+// AM_RANGE(0x600000, 0x600000)
AM_RANGE(0x600004, 0x600007) AM_WRITE(sound_w)
AM_RANGE(0x600008, 0x60000b) AM_READ(sound_r)
AM_RANGE(0x640000, 0x640003) AM_WRITE(sound_irq_w)
@@ -477,15 +494,15 @@ ADDRESS_MAP_END
/**********************************************************************************/
static ADDRESS_MAP_START( dsp_program_map, ADDRESS_SPACE_PROGRAM, 16 )
- AM_RANGE(0x7000, 0x7fff) AM_RAM AM_BASE(&dsp56k_p_mirror) /* Unsure of size, but this corresponds to bank01 */
- AM_RANGE(0x8000, 0x87ff) AM_RAM
+ AM_RANGE(0x7000, 0x7fff) AM_RAM AM_BASE(&dsp56k_p_mirror) /* Unsure of size, but 0x1000 matches bank01 */
+ AM_RANGE(0x8000, 0x87ff) AM_RAM AM_BASE(&dsp56k_p_8000)
AM_RANGE(0xc000, 0xc000) AM_READ(dsp56k_bootload_r)
ADDRESS_MAP_END
static ADDRESS_MAP_START( dsp_data_map, ADDRESS_SPACE_DATA, 16 )
- AM_RANGE(0x0800, 0x5fff) AM_RAM /* Appears to not be affected by banking? */
+ AM_RANGE(0x0800, 0x5fff) AM_RAM /* Appears to not be affected by banking? */
AM_RANGE(0x6000, 0x6fff) AM_READWRITE(dsp56k_ram_bank00_read, dsp56k_ram_bank00_write)
- AM_RANGE(0x7000, 0x7fff) AM_READWRITE(dsp56k_ram_bank01_read, dsp56k_ram_bank01_write)
+ AM_RANGE(0x7000, 0x7fff) AM_READWRITE(dsp56k_ram_bank01_read, dsp56k_ram_bank01_write) /* Mirrored in program space @ 0x8000 */
AM_RANGE(0x8000, 0xbfff) AM_READWRITE(dsp56k_ram_bank02_read, dsp56k_ram_bank02_write)
AM_RANGE(0xc000, 0xdfff) AM_READWRITE(dsp56k_shared_ram_read, dsp56k_shared_ram_write)
AM_RANGE(0xe000, 0xffbf) AM_READWRITE(dsp56k_ram_bank04_read, dsp56k_ram_bank04_write)
@@ -569,7 +586,7 @@ static MACHINE_DRIVER_START( plygonet )
MDRV_CPU_PROGRAM_MAP(main_map, 0)
MDRV_CPU_VBLANK_INT_HACK(polygonet_interrupt, 2)
- MDRV_CPU_ADD("dsp", DSP56156, 10000000) /* should be 40.0 MHz/? */
+ MDRV_CPU_ADD("dsp", DSP56156, 10000000) /* xtal is 40.0 MHz */
MDRV_CPU_PROGRAM_MAP(dsp_program_map, 0)
MDRV_CPU_DATA_MAP(dsp_data_map, 0)
@@ -643,6 +660,9 @@ static DRIVER_INIT(polygonet)
memset(dsp56k_bank02_ram, 0, 2 * 8 * dsp56k_bank02_size * sizeof(UINT16));
memset(dsp56k_shared_ram_16, 0, 2 * 8 * dsp56k_shared_ram_16_size * sizeof(UINT16));
memset(dsp56k_bank04_ram, 0, 2 * 8 * dsp56k_bank04_size * sizeof(UINT16));
+
+ /* The dsp56k occasionally executes out of mapped memory */
+ memory_set_opbase_handler(1, plygonet_dsp56k_opbase_handler);
}
ROM_START( plygonet )