summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Windy Fairy <39211915+windyfairy@users.noreply.github.com>2019-06-05 22:46:14 +0900
committer R. Belmont <rb6502@users.noreply.github.com>2019-06-05 09:46:14 -0400
commit060378ca9a31328de0dc8c4ff7934251293bd8a1 (patch)
tree0fe946a4c3664589b9369bda172b232d5e331b1c
parent59f6afab3f0379ef71868b16086162bbc5e654a4 (diff)
Fix regressions in k573dio/k573fpga/mas3507d (#5133)
* Fix memory address stuff (fixes graphics, random glitches, games not booting, etc) * Handle playback flag * Add volume control * This doesn't do anything * Fix transitioning between two MP3 files * Revert change * Fix the way playback time is reported which should fix looping * Fix audio decoding * Fix timing issue * Small cleanup * Store the original key1 in k573dio, not k573fpga * Restore masks for RAM addresses to avoid overflows * Rework how starting and stopping the MAS3507D works as well as reporting playback time
-rw-r--r--src/devices/sound/mas3507d.cpp40
-rw-r--r--src/devices/sound/mas3507d.h9
-rw-r--r--src/mame/machine/k573dio.cpp47
-rw-r--r--src/mame/machine/k573dio.h7
-rw-r--r--src/mame/machine/k573fpga.cpp5
-rw-r--r--src/mame/machine/k573fpga.h5
6 files changed, 59 insertions, 54 deletions
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<u8, 8000> mp3data;
+ std::array<u8, 0xe00> mp3data;
std::array<mp3d_sample_t, MINIMP3_MAX_SAMPLES_PER_FRAME> 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;
-}
-
-READ16_MEMBER(k573dio_device::mp3_playback_high_r)
-{
- //logerror("mp3_playback_high_r: %08x (%08x)\n", mp3_playback & 0xffff0000, mp3_playback);
- return (mas3507d->get_sample_count() & 0xffff0000) >> 16;
-}
-
-WRITE16_MEMBER(k573dio_device::mp3_playback_high_w)
-{
- //mp3_playback = (mp3_playback & 0x0000ffff) | (data << 16);
- //logerror("mp3_playback_low_w: %08x\n", mp3_playback);
+ ram_read_adr = ((ram_read_adr & 0xffff0000) | data) & 0x1ffffff;
}
-READ16_MEMBER(k573dio_device::mp3_playback_low_r)
+READ16_MEMBER(k573dio_device::mp3_frame_count_high_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;
+ return (mas3507d->get_frame_count() & 0xffff0000) >> 16;
}
-WRITE16_MEMBER(k573dio_device::mp3_playback_low_w)
+READ16_MEMBER(k573dio_device::mp3_frame_count_low_r)
{
- //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;