summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/sound.lua10
-rw-r--r--src/devices/sound/okim6588.cpp225
-rw-r--r--src/devices/sound/okim6588.h88
-rw-r--r--src/devices/video/hd61603.cpp2
-rw-r--r--src/devices/video/hd61603.h2
5 files changed, 324 insertions, 3 deletions
diff --git a/scripts/src/sound.lua b/scripts/src/sound.lua
index fe1b86137cd..522aff46042 100644
--- a/scripts/src/sound.lua
+++ b/scripts/src/sound.lua
@@ -692,11 +692,12 @@ end
--@src/devices/sound/msm5232.h,SOUNDS["MSM5232"] = true
--@src/devices/sound/okim6376.h,SOUNDS["OKIM6376"] = true
--@src/devices/sound/okim6295.h,SOUNDS["OKIM6295"] = true
+--@src/devices/sound/okim6588.h,SOUNDS["OKIM6588"] = true
--@src/devices/sound/okim9810.h,SOUNDS["OKIM9810"] = true
--@src/devices/sound/okiadpcm.h,SOUNDS["OKIADPCM"] = true
---------------------------------------------------
-if (SOUNDS["OKIM6258"]~=null or SOUNDS["OKIM6295"]~=null or SOUNDS["OKIM9810"]~=null or SOUNDS["I5000_SND"]~=null or SOUNDS["OKIADPCM"]~=null) then
+if (SOUNDS["OKIM6258"]~=null or SOUNDS["OKIM6295"]~=null or SOUNDS["OKIM6588"]~=null or SOUNDS["OKIM9810"]~=null or SOUNDS["I5000_SND"]~=null or SOUNDS["OKIADPCM"]~=null) then
files {
MAME_DIR .. "src/devices/sound/okiadpcm.cpp",
MAME_DIR .. "src/devices/sound/okiadpcm.h",
@@ -738,6 +739,13 @@ if (SOUNDS["OKIM6258"]~=null) then
}
end
+if (SOUNDS["OKIM6588"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/sound/okim6588.cpp",
+ MAME_DIR .. "src/devices/sound/okim6588.h",
+ }
+end
+
if (SOUNDS["OKIM9810"]~=null) then
files {
MAME_DIR .. "src/devices/sound/okim9810.cpp",
diff --git a/src/devices/sound/okim6588.cpp b/src/devices/sound/okim6588.cpp
new file mode 100644
index 00000000000..7704c61d315
--- /dev/null
+++ b/src/devices/sound/okim6588.cpp
@@ -0,0 +1,225 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+OKI MSM6588 ADPCM Recorder
+
+TODO:
+- it only supports MCU mode EXT playback, nothing else emulated yet
+- status register read (eg. BUSY flag)
+
+*/
+
+#include "emu.h"
+#include "okim6588.h"
+
+
+DEFINE_DEVICE_TYPE(OKIM6588, okim6588_device, "okim6588", "OKI MSM6588 ADPCM Recorder")
+
+//-------------------------------------------------
+// constructor
+//-------------------------------------------------
+
+okim6588_device::okim6588_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, OKIM6588, tag, owner, clock),
+ device_sound_interface(mconfig, *this),
+ m_write_mon(*this),
+ m_chip_mode(CHIP_MODE_STANDALONE)
+{ }
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+// allow save_item on a non-fundamental type
+ALLOW_SAVE_TYPE(okim6588_device::chip_mode);
+ALLOW_SAVE_TYPE(okim6588_device::command_state);
+ALLOW_SAVE_TYPE(okim6588_device::run_state);
+
+void okim6588_device::device_start()
+{
+ // initialize
+ m_stream = stream_alloc(0, 1, clock() / 128);
+
+ m_adpcm_timer = timer_alloc(FUNC(okim6588_device::clock_adpcm), this);
+ m_mon_timer = timer_alloc(FUNC(okim6588_device::set_mon), this);
+
+ m_command_state = COMMAND_READY;
+ m_run_state = RUN_STOP;
+ m_adpcm_data = 0;
+
+ m_vds_bit = (m_chip_mode == CHIP_MODE_MCU) ? 1 : 0;
+ m_samp_fdiv = 512;
+ m_rec_mode = false;
+
+ // register for savestates
+ save_item(NAME(m_chip_mode));
+ save_item(NAME(m_command_state));
+ save_item(NAME(m_run_state));
+ save_item(NAME(m_adpcm_data));
+ save_item(NAME(m_adpcm.m_signal));
+ save_item(NAME(m_adpcm.m_step));
+ save_item(NAME(m_rec_mode));
+ save_item(NAME(m_samp_fdiv));
+ save_item(NAME(m_vds_bit));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void okim6588_device::device_reset()
+{
+ m_command_state = COMMAND_READY;
+ m_run_state = RUN_STOP;
+ reset_adpcm();
+
+ m_adpcm_timer->adjust(attotime::never);
+ m_mon_timer->adjust(attotime::never);
+ m_write_mon(0);
+}
+
+
+//-------------------------------------------------
+// internal handlers
+//-------------------------------------------------
+
+void okim6588_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
+{
+ // simply fill the buffer with the current sample
+ outputs[0].fill(m_adpcm.output() / 2048.0);
+}
+
+TIMER_CALLBACK_MEMBER(okim6588_device::clock_adpcm)
+{
+ switch (m_run_state)
+ {
+ case RUN_STOP:
+ reset_adpcm();
+ break;
+
+ case RUN_PLAY_EXT:
+ // strobe MON
+ m_write_mon(1);
+ m_mon_timer->adjust(attotime::from_ticks(m_samp_fdiv / 4, clock()));
+ m_command_state = COMMAND_EXT;
+
+ m_stream->update();
+ get_adpcm_sample(m_adpcm_data);
+ break;
+
+ default:
+ break;
+ }
+
+ if (m_run_state != RUN_STOP && m_run_state != RUN_PAUSE)
+ m_adpcm_timer->adjust(attotime::from_ticks(m_samp_fdiv, clock()));
+}
+
+TIMER_CALLBACK_MEMBER(okim6588_device::set_mon)
+{
+ m_write_mon(param ? 1 : 0);
+}
+
+s32 okim6588_device::get_adpcm_sample(u8 data)
+{
+ u8 mask = m_vds_bit ? 0xf : 0xe;
+ return m_adpcm.clock(data & mask);
+}
+
+void okim6588_device::reset_adpcm()
+{
+ m_stream->update();
+ m_adpcm_data = 0;
+ m_adpcm.reset();
+}
+
+
+//-------------------------------------------------
+// public handlers
+//-------------------------------------------------
+
+u8 okim6588_device::data_r()
+{
+ if (m_chip_mode != CHIP_MODE_MCU)
+ return 0;
+
+ return 0;
+}
+
+void okim6588_device::data_w(u8 data)
+{
+ if (m_chip_mode != CHIP_MODE_MCU)
+ return;
+
+ data &= 0xf;
+
+ switch (m_command_state)
+ {
+ case COMMAND_READY:
+ switch (data & 0xf)
+ {
+ // NOP
+ case 0x0:
+ break;
+
+ // PLAY/REC
+ case 0x2: case 0x3:
+ m_rec_mode = bool(data & 1);
+ break;
+
+ // STOP
+ case 0x5:
+ m_run_state = RUN_STOP;
+ break;
+
+ // SAMP
+ case 0x6:
+ m_command_state = COMMAND_SAMP;
+ break;
+
+ // VDS
+ case 0xc:
+ m_command_state = COMMAND_VDS;
+ break;
+
+ // EXT
+ case 0xb:
+ m_run_state = m_rec_mode ? RUN_RECORD_EXT : RUN_PLAY_EXT;
+ reset_adpcm();
+
+ // minimum delay is 1 sample
+ m_adpcm_timer->adjust(attotime::from_ticks(m_samp_fdiv, clock()));
+ m_command_state = COMMAND_EXT;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case COMMAND_SAMP:
+ {
+ static const u16 div[4] = { 1024, 768, 640, 512 };
+ m_samp_fdiv = div[data & 3];
+ m_command_state = COMMAND_READY;
+ break;
+ }
+
+ case COMMAND_EXT:
+ m_adpcm_data = data;
+ m_command_state = COMMAND_READY;
+ break;
+
+ case COMMAND_VDS:
+ m_vds_bit = BIT(data, 2);
+ m_command_state = COMMAND_READY;
+ break;
+
+ default:
+ // shouldn't get here
+ break;
+ }
+}
diff --git a/src/devices/sound/okim6588.h b/src/devices/sound/okim6588.h
new file mode 100644
index 00000000000..7382902c3d8
--- /dev/null
+++ b/src/devices/sound/okim6588.h
@@ -0,0 +1,88 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ OKI MSM6588 ADPCM Recorder
+
+*/
+
+#ifndef MAME_SOUND_OKIM6588_H
+#define MAME_SOUND_OKIM6588_H
+
+#pragma once
+
+#include "sound/okiadpcm.h"
+
+
+class okim6588_device : public device_t, public device_sound_interface
+{
+public:
+ okim6588_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ // configuration helpers
+ auto write_mon() { return m_write_mon.bind(); }
+ void set_mcum_pin(int state) { m_chip_mode = state ? CHIP_MODE_MCU : CHIP_MODE_STANDALONE; }
+
+ // D0-D3 (MCU mode)
+ void data_w(u8 data);
+ u8 data_r();
+
+protected:
+ // device_t implementation
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
+
+private:
+ enum chip_mode : u8
+ {
+ CHIP_MODE_STANDALONE = 0,
+ CHIP_MODE_MCU
+ };
+
+ enum command_state : u8
+ {
+ COMMAND_READY = 0,
+ COMMAND_SAMP,
+ COMMAND_EXT,
+ COMMAND_VDS
+ };
+
+ enum run_state : u8
+ {
+ RUN_STOP = 0,
+ RUN_PAUSE,
+ RUN_PLAY_SERIAL,
+ RUN_PLAY_EXT,
+ RUN_RECORD_SERIAL,
+ RUN_RECORD_EXT,
+ };
+
+ devcb_write_line m_write_mon;
+
+ chip_mode m_chip_mode;
+ command_state m_command_state;
+ run_state m_run_state;
+
+ sound_stream *m_stream;
+
+ u8 m_adpcm_data;
+ oki_adpcm_state m_adpcm;
+ bool m_rec_mode;
+ u16 m_samp_fdiv;
+ u8 m_vds_bit;
+
+ emu_timer *m_adpcm_timer;
+ emu_timer *m_mon_timer;
+
+ TIMER_CALLBACK_MEMBER(clock_adpcm);
+ TIMER_CALLBACK_MEMBER(set_mon);
+ s32 get_adpcm_sample(u8 data);
+ void reset_adpcm();
+};
+
+
+DECLARE_DEVICE_TYPE(OKIM6588, okim6588_device)
+
+#endif // MAME_SOUND_OKIM6588_H
diff --git a/src/devices/video/hd61603.cpp b/src/devices/video/hd61603.cpp
index bdc2cd7aa66..d9187fd78fa 100644
--- a/src/devices/video/hd61603.cpp
+++ b/src/devices/video/hd61603.cpp
@@ -14,7 +14,7 @@ TODO:
*/
#include "emu.h"
-#include "video/hd61603.h"
+#include "hd61603.h"
DEFINE_DEVICE_TYPE(HD61603, hd61603_device, "hd61603", "Hitachi HD61603 LCD Driver")
diff --git a/src/devices/video/hd61603.h b/src/devices/video/hd61603.h
index 8de7c879761..bffb2b73848 100644
--- a/src/devices/video/hd61603.h
+++ b/src/devices/video/hd61603.h
@@ -45,7 +45,7 @@ public:
void data_w(u8 data);
protected:
- // device-level overrides
+ // device_t implementation
virtual void device_start() override;
virtual void device_reset() override;