diff --git a/src/devices/sound/mas3507d.cpp b/src/devices/sound/mas3507d.cpp index cd04e163c6b..762fa4f02f1 100644 --- a/src/devices/sound/mas3507d.cpp +++ b/src/devices/sound/mas3507d.cpp @@ -30,7 +30,6 @@ void mas3507d_device::device_start() { current_rate = 44100; stream = stream_alloc(0, 2, current_rate); - mp3dec_init(&mp3_dec); cb_sample.resolve(); } @@ -42,7 +41,13 @@ void mas3507d_device::device_reset() i2c_bus_address = UNKNOWN; i2c_bus_curbit = -1; i2c_bus_curval = 0; - total_sample_count = 0; + + mp3dec_init(&mp3_dec); + memset(mp3data.data(), 0, mp3data.size()); + memset(samples.data(), 0, samples.size()); + mp3_count = 0; + sample_count = 0; + total_frame_count = 0; } void mas3507d_device::i2c_scl_w(bool line) @@ -284,6 +289,7 @@ void mas3507d_device::mem_write(int bank, uint32_t adr, uint32_t val) case 0x0032f: logerror("MAS3507D: OutputConfig = %05x\n", val); break; case 0x107f8: logerror("MAS3507D: left->left gain = %05x (%d dB, %f%%)\n", val, gain_to_db(val), gain_to_percentage(val)); + stream->set_output_gain(0, gain_to_percentage(val)); break; case 0x107f9: logerror("MAS3507D: left->right gain = %05x (%d dB, %f%%)\n", val, gain_to_db(val), gain_to_percentage(val)); @@ -293,6 +299,7 @@ void mas3507d_device::mem_write(int bank, uint32_t adr, uint32_t val) break; case 0x107fb: logerror("MAS3507D: right->right gain = %05x (%d dB, %f%%)\n", val, gain_to_db(val), gain_to_percentage(val)); + stream->set_output_gain(1, gain_to_percentage(val)); break; default: logerror("MAS3507D: %d:%04x = %05x\n", bank, adr, val); break; } @@ -321,7 +328,7 @@ void mas3507d_device::run_program(uint32_t adr) void mas3507d_device::fill_buffer() { - while(mp3_count < mp3data.size()) { + while(mp3_count + 2 < mp3data.size()) { u16 v = cb_sample(); mp3data[mp3_count++] = v >> 8; mp3data[mp3_count++] = v; @@ -343,15 +350,14 @@ void mas3507d_device::fill_buffer() std::copy(mp3data.begin() + mp3_info.frame_bytes, mp3data.end(), mp3data.begin()); mp3_count -= mp3_info.frame_bytes; - if(mp3_info.channels == 1) - sample_count = scount; - else - sample_count = scount; + sample_count = scount; if(mp3_info.hz != current_rate) { current_rate = mp3_info.hz; stream->set_sample_rate(current_rate); } + + total_frame_count += scount; } void mas3507d_device::append_buffer(stream_sample_t **outputs, int &pos, int scount) @@ -391,22 +397,30 @@ void mas3507d_device::append_buffer(stream_sample_t **outputs, int &pos, int sco sample_count -= s1; } -void mas3507d_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +void mas3507d_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int csamples) { int pos = 0; - total_sample_count += samples; - append_buffer(outputs, pos, samples); + + append_buffer(outputs, pos, csamples); for(;;) { - if(pos == samples) + if(pos == csamples) return; fill_buffer(); if(!sample_count) { - for(int i=pos; i != samples; i++) { + // In the case of a bad frame or no frames being around, reset the state of the decoder + mp3dec_init(&mp3_dec); + memset(mp3data.data(), 0, mp3data.size()); + memset(samples.data(), 0, samples.size()); + mp3_count = 0; + sample_count = 0; + total_frame_count = 0; + + for(int i=pos; i != csamples; i++) { outputs[0][i] = 0; outputs[1][i] = 0; } return; } - append_buffer(outputs, pos, samples); + append_buffer(outputs, pos, csamples); } } diff --git a/src/devices/sound/mas3507d.h b/src/devices/sound/mas3507d.h index d937e9c6414..44979ecc612 100644 --- a/src/devices/sound/mas3507d.h +++ b/src/devices/sound/mas3507d.h @@ -22,8 +22,7 @@ public: void i2c_scl_w(bool line); void i2c_sda_w(bool line); - void reset_sample_count() { total_sample_count = 0; } - u32 get_sample_count() const { return total_sample_count; } + u32 get_frame_count() const { return total_frame_count; } protected: virtual void device_start() override; @@ -36,13 +35,14 @@ private: enum { IDLE, STARTED, NAK, ACK, ACK2 } i2c_bus_state; enum { UNKNOWN, VALIDATED, WRONG } i2c_bus_address; - std::array mp3data; + std::array mp3data; std::array samples; bool i2c_scli, i2c_sclo, i2c_sdai, i2c_sdao; int i2c_bus_curbit; uint8_t i2c_bus_curval; int mp3_count, sample_count, current_rate; - u32 total_sample_count; + u32 total_frame_count; + bool playback_enabled, playback_waiting; mp3dec_t mp3_dec; mp3dec_frame_info_t mp3_info; @@ -54,7 +54,6 @@ private: void i2c_device_got_byte(uint8_t byte); void i2c_device_got_stop(); - enum { UNDEFINED, CONTROL, DATA_READ, DATA_WRITE, BAD } i2c_subdest; enum { CMD_BAD, CMD_RUN, CMD_READ_CTRL, CMD_WRITE_REG, CMD_WRITE_MEM, CMD_READ_REG, CMD_READ_MEM } i2c_command; int i2c_bytecount; diff --git a/src/mame/machine/k573dio.cpp b/src/mame/machine/k573dio.cpp index 370db9a2089..205ff7ec682 100644 --- a/src/mame/machine/k573dio.cpp +++ b/src/mame/machine/k573dio.cpp @@ -89,8 +89,8 @@ void k573dio_device::amap(address_map &map) map(0xb4, 0xb5).rw(FUNC(k573dio_device::ram_r), FUNC(k573dio_device::ram_w)); map(0xb6, 0xb7).w(FUNC(k573dio_device::ram_read_adr_high_w)); map(0xb8, 0xb9).w(FUNC(k573dio_device::ram_read_adr_low_w)); - map(0xca, 0xcb).rw(FUNC(k573dio_device::mp3_playback_high_r), FUNC(k573dio_device::mp3_playback_high_w)); - map(0xcc, 0xcd).rw(FUNC(k573dio_device::mp3_playback_low_r), FUNC(k573dio_device::mp3_playback_low_w)); + map(0xca, 0xcb).r(FUNC(k573dio_device::mp3_frame_count_high_r)); + map(0xcc, 0xcd).r(FUNC(k573dio_device::mp3_frame_count_low_r)); map(0xce, 0xcf).r(FUNC(k573dio_device::mp3_unk_r)); map(0xe0, 0xe1).w(FUNC(k573dio_device::output_1_w)); map(0xe2, 0xe3).w(FUNC(k573dio_device::output_0_w)); @@ -216,9 +216,9 @@ WRITE16_MEMBER(k573dio_device::mpeg_start_adr_low_w) { logerror("FPGA MPEG start address low %04x\n", data); k573fpga->set_mp3_cur_adr((k573fpga->get_mp3_cur_adr() & 0xffff0000) | data); // low + if(is_ddrsbm_fpga) k573fpga->set_crypto_key3(0); - mas3507d->reset_sample_count(); } WRITE16_MEMBER(k573dio_device::mpeg_end_adr_high_w) @@ -235,12 +235,14 @@ WRITE16_MEMBER(k573dio_device::mpeg_end_adr_low_w) READ16_MEMBER(k573dio_device::mpeg_key_1_r) { - return k573fpga->get_crypto_key1(); + // Dance Dance Revolution Solo Bass Mix reads this key before starting songs + return crypto_key1; } WRITE16_MEMBER(k573dio_device::mpeg_key_1_w) { logerror("FPGA MPEG key 1/3 %04x\n", data); + crypto_key1 = data; k573fpga->set_crypto_key1(data); } @@ -260,6 +262,11 @@ WRITE16_MEMBER(k573dio_device::mas_i2c_w) READ16_MEMBER(k573dio_device::mpeg_ctrl_r) { + if (k573fpga->get_mpeg_ctrl() == 0x1000 && !k573fpga->is_playing()) { + // Set the FPGA to stop mode so that data won't be sent anymore + k573fpga->set_mpeg_ctrl(0xa000); + } + return k573fpga->get_mpeg_ctrl(); } @@ -271,18 +278,18 @@ WRITE16_MEMBER(k573dio_device::mpeg_ctrl_w) WRITE16_MEMBER(k573dio_device::ram_write_adr_high_w) { // read and write address are shared - ram_adr = (ram_adr & 0x0000ffff) | (data << 16); + ram_adr = ((ram_adr & 0x0000ffff) | (data << 16)) & 0x1ffffff; } WRITE16_MEMBER(k573dio_device::ram_write_adr_low_w) { // read and write address are shared - ram_adr = (ram_adr & 0xffff0000) | data; + ram_adr = ((ram_adr & 0xffff0000) | data) & 0x1ffffff; } READ16_MEMBER(k573dio_device::ram_r) { - uint16_t res = ram[(ram_read_adr & 0x7fffff) >> 1]; + uint16_t res = ram[(ram_read_adr & 0x1ffffff) >> 1]; ram_read_adr += 2; return res; } @@ -296,37 +303,23 @@ WRITE16_MEMBER(k573dio_device::ram_w) WRITE16_MEMBER(k573dio_device::ram_read_adr_high_w) { // read and write address are shared - ram_read_adr = (ram_read_adr & 0x001fffff) | (data << 16); + ram_read_adr = ((ram_read_adr & 0x0000ffff) | (data << 16)) & 0x1ffffff; } WRITE16_MEMBER(k573dio_device::ram_read_adr_low_w) { // read and write address are shared - ram_read_adr = (ram_read_adr & 0xffff0000) | data; + ram_read_adr = ((ram_read_adr & 0xffff0000) | data) & 0x1ffffff; } -READ16_MEMBER(k573dio_device::mp3_playback_high_r) +READ16_MEMBER(k573dio_device::mp3_frame_count_high_r) { - //logerror("mp3_playback_high_r: %08x (%08x)\n", mp3_playback & 0xffff0000, mp3_playback); - return (mas3507d->get_sample_count() & 0xffff0000) >> 16; + return (mas3507d->get_frame_count() & 0xffff0000) >> 16; } -WRITE16_MEMBER(k573dio_device::mp3_playback_high_w) +READ16_MEMBER(k573dio_device::mp3_frame_count_low_r) { - //mp3_playback = (mp3_playback & 0x0000ffff) | (data << 16); - //logerror("mp3_playback_low_w: %08x\n", mp3_playback); -} - -READ16_MEMBER(k573dio_device::mp3_playback_low_r) -{ - //logerror("mp3_playback_low_r: %08x (%08x) %08x %08x\n", mp3_playback & 0x0000ffff, mp3_playback, m_samples->get_position(0), m_samples->get_position(1)); - return mas3507d->get_sample_count() & 0x0000ffff; -} - -WRITE16_MEMBER(k573dio_device::mp3_playback_low_w) -{ - //mp3_playback = (mp3_playback & 0xffff0000) | data; - //logerror("mp3_playback_low_w: %08x\n", mp3_playback & 0x0000ffff); + return mas3507d->get_frame_count() & 0x0000ffff; } WRITE16_MEMBER(k573dio_device::output_1_w) diff --git a/src/mame/machine/k573dio.h b/src/mame/machine/k573dio.h index 7f41088c515..2d2e44bac70 100644 --- a/src/mame/machine/k573dio.h +++ b/src/mame/machine/k573dio.h @@ -43,10 +43,8 @@ public: DECLARE_WRITE16_MEMBER(ram_w); DECLARE_WRITE16_MEMBER(ram_read_adr_high_w); DECLARE_WRITE16_MEMBER(ram_read_adr_low_w); - DECLARE_READ16_MEMBER(mp3_playback_high_r); - DECLARE_WRITE16_MEMBER(mp3_playback_high_w); - DECLARE_READ16_MEMBER(mp3_playback_low_r); - DECLARE_WRITE16_MEMBER(mp3_playback_low_w); + DECLARE_READ16_MEMBER(mp3_frame_count_high_r); + DECLARE_READ16_MEMBER(mp3_frame_count_low_r); DECLARE_WRITE16_MEMBER(output_0_w); DECLARE_WRITE16_MEMBER(output_1_w); DECLARE_WRITE16_MEMBER(output_7_w); @@ -82,6 +80,7 @@ private: void output(int offset, uint16_t data); bool is_ddrsbm_fpga; + u16 crypto_key1; }; DECLARE_DEVICE_TYPE(KONAMI_573_DIGITAL_IO_BOARD, k573dio_device) diff --git a/src/mame/machine/k573fpga.cpp b/src/mame/machine/k573fpga.cpp index 4c8dc5b1177..3ea14abae9b 100644 --- a/src/mame/machine/k573fpga.cpp +++ b/src/mame/machine/k573fpga.cpp @@ -140,10 +140,11 @@ u16 k573fpga_device::decrypt_ddrsbm(u16 data) u16 k573fpga_device::get_decrypted() { - if(mp3_cur_adr >= mp3_end_adr || (mpeg_ctrl_flag & 0xe000) != 0xe000) + if(mp3_cur_adr >= mp3_end_adr || (mpeg_ctrl_flag & 0xe000) != 0xe000) { return 0; + } - u16 src = ram[(mp3_cur_adr & 0x1ffffff) >> 1]; + u16 src = ram[mp3_cur_adr >> 1]; u16 result = use_ddrsbm_fpga ? decrypt_ddrsbm(src) : decrypt_default(src); mp3_cur_adr += 2; diff --git a/src/mame/machine/k573fpga.h b/src/mame/machine/k573fpga.h index 807c32b8d5d..bf6b6ba7671 100644 --- a/src/mame/machine/k573fpga.h +++ b/src/mame/machine/k573fpga.h @@ -23,9 +23,6 @@ public: void set_crypto_key1(u16 v) { crypto_key1 = v; } void set_crypto_key2(u16 v) { crypto_key2 = v; } void set_crypto_key3(u8 v) { crypto_key3 = v; } - u16 get_crypto_key1() const { return crypto_key1; } - u16 get_crypto_key2() const { return crypto_key2; } - u8 get_crypto_key3() const { return crypto_key3; } uint32_t get_mp3_cur_adr() { return mp3_cur_adr; } void set_mp3_cur_adr(u32 v) { mp3_cur_adr = v; } @@ -39,6 +36,8 @@ public: u16 get_mpeg_ctrl(); void set_mpeg_ctrl(u16 data); + bool is_playing() { return (mpeg_ctrl_flag & 0xe000) == 0xe000 && mp3_cur_adr < mp3_end_adr; } + protected: virtual void device_start() override; virtual void device_reset() override;