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 )