summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/odyssey2/voice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/odyssey2/voice.cpp')
-rw-r--r--src/devices/bus/odyssey2/voice.cpp102
1 files changed, 73 insertions, 29 deletions
diff --git a/src/devices/bus/odyssey2/voice.cpp b/src/devices/bus/odyssey2/voice.cpp
index 927b8fcc05e..28911004c47 100644
--- a/src/devices/bus/odyssey2/voice.cpp
+++ b/src/devices/bus/odyssey2/voice.cpp
@@ -12,18 +12,58 @@ Hardware notes:
Cartridge pins A,B,E,1,10,11 are repurposed for the extra speech ROM. This means
that (European) cartridges using extra I/O won't work on it.
+TODO:
+- bees sound at level complete "MORE MORE MORE CHK CHK CHK" should be more rapid
+- turtlesu usually doesn't detect the voice cartridge
+
******************************************************************************/
#include "emu.h"
#include "voice.h"
+
+#include "sound/sp0256.h"
+
#include "speaker.h"
-DEFINE_DEVICE_TYPE(O2_ROM_VOICE, o2_voice_device, "o2_voice", "Odyssey 2 The Voice Passthrough Cart")
+namespace {
//-------------------------------------------------
-// o2_voice_device - constructor
+// initialization
//-------------------------------------------------
+class o2_voice_device : public device_t, public device_o2_cart_interface
+{
+public:
+ o2_voice_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ virtual void cart_init() override;
+
+ virtual u8 read_rom04(offs_t offset) override { return (m_subslot->exists()) ? m_subslot->read_rom04(offset) : 0xff; }
+ virtual u8 read_rom0c(offs_t offset) override { return (m_subslot->exists()) ? m_subslot->read_rom0c(offset) : 0xff; }
+
+ virtual void write_p1(u8 data) override { m_control = data; if (m_subslot->exists()) m_subslot->write_p1(data & 3); }
+ virtual void write_p2(u8 data) override { if (m_subslot->exists()) m_subslot->write_p2(data & ~4); }
+ virtual void bus_write(u8 data) override { if (m_subslot->exists()) m_subslot->bus_write(data); }
+ virtual u8 bus_read() override { return (m_subslot->exists()) ? m_subslot->bus_read() : 0xff; }
+
+ virtual void io_write(offs_t offset, u8 data) override;
+ virtual int t0_read() override;
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+private:
+ required_device<sp0256_device> m_speech;
+ required_device<o2_cart_slot_device> m_subslot;
+
+ u8 m_control = 0;
+ bool m_reset = false;
+};
+
o2_voice_device::o2_voice_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
device_t(mconfig, O2_ROM_VOICE, tag, owner, clock),
device_o2_cart_interface(mconfig, *this),
@@ -33,8 +73,8 @@ o2_voice_device::o2_voice_device(const machine_config &mconfig, const char *tag,
void o2_voice_device::device_start()
{
- save_item(NAME(m_lrq_state));
save_item(NAME(m_control));
+ save_item(NAME(m_reset));
}
void o2_voice_device::cart_init()
@@ -60,6 +100,34 @@ void o2_voice_device::device_reset()
//-------------------------------------------------
+// mapper specific handlers
+//-------------------------------------------------
+
+int o2_voice_device::t0_read()
+{
+ return m_speech->lrq_r() ? 0 : 1;
+}
+
+void o2_voice_device::io_write(offs_t offset, u8 data)
+{
+ if (offset & 0x80 && ~m_control & 0x10)
+ {
+ // D5: 7474 to SP0256B reset
+ bool reset = !(data & 0x20);
+ if (reset)
+ m_speech->reset();
+ else if (!m_reset)
+ {
+ // A0-A6: SP0256B A1-A7 (A8 to GND)
+ m_speech->ald_w(offset & 0x7f);
+ }
+
+ m_reset = reset;
+ }
+}
+
+
+//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
@@ -68,7 +136,6 @@ void o2_voice_device::device_add_mconfig(machine_config &config)
SPEAKER(config, "mono").front_center();
SP0256(config, m_speech, 3.12_MHz_XTAL);
- m_speech->data_request_callback().set(FUNC(o2_voice_device::lrq_callback));
// The Voice uses a speaker with its own volume control so the relative volumes to use are subjective, these sound good
m_speech->add_route(ALL_OUTPUTS, "mono", 1.00);
@@ -84,30 +151,7 @@ const tiny_rom_entry *o2_voice_device::device_rom_region() const
return ROM_NAME( o2voice );
}
+} // anonymous namespace
-//-------------------------------------------------
-// mapper specific handlers
-//-------------------------------------------------
-
-WRITE_LINE_MEMBER(o2_voice_device::lrq_callback)
-{
- m_lrq_state = state;
-}
-
-READ_LINE_MEMBER(o2_voice_device::t0_read)
-{
- return m_speech->lrq_r() ? 0 : 1;
-}
-void o2_voice_device::io_write(offs_t offset, u8 data)
-{
- if (offset & 0x80 && ~m_control & 0x10)
- {
- // A0-A6: SP0256B A1-A7 (A8 to GND)
- // D5: 7474 to SP0256B reset
- if (data & 0x20)
- m_speech->ald_w(offset & 0x7f);
- else
- m_speech->reset();
- }
-}
+DEFINE_DEVICE_TYPE_PRIVATE(O2_ROM_VOICE, device_o2_cart_interface, o2_voice_device, "o2_voice", "Odyssey 2 The Voice Cartridge")