diff options
author | 2019-08-06 17:00:59 -0400 | |
---|---|---|
committer | 2019-08-06 17:02:37 -0400 | |
commit | e7e165b44aa57dd43ad7d5aa945a931699033f6e (patch) | |
tree | e37cfba4cc9dc68c776e2fddd83e7b239c115832 /src/devices | |
parent | c750b8efd5b340f81ff30375ce566dc47569df12 (diff) |
trocana: Add preliminary MSM6650 device and some test inputs
okim6376: Use device_rom_interface; convert logging calls to logmacro.h (nw)
Diffstat (limited to 'src/devices')
-rw-r--r-- | src/devices/sound/okim6376.cpp | 86 | ||||
-rw-r--r-- | src/devices/sound/okim6376.h | 28 |
2 files changed, 89 insertions, 25 deletions
diff --git a/src/devices/sound/okim6376.cpp b/src/devices/sound/okim6376.cpp index e04f051b0f5..2170bd5e898 100644 --- a/src/devices/sound/okim6376.cpp +++ b/src/devices/sound/okim6376.cpp @@ -19,8 +19,8 @@ #define MAX_SAMPLE_CHUNK 10000 //#define MAX_WORDS 111 -#define OKIVERBOSE 0 -#define MSM6376LOG(...) do { if (OKIVERBOSE) logerror(__VA_ARGS__); } while (0) +//#define VERBOSE 1 +#include "logmacro.h" /* step size index shift table */ static const int index_shift[8] = { -1, -1, -1, -1, 2, 4, 6, 8 }; @@ -111,11 +111,12 @@ void okim6376_device::ADPCMVoice::reset() DEFINE_DEVICE_TYPE(OKIM6376, okim6376_device, "okim6376", "OKI MSM6376 ADPCM") +DEFINE_DEVICE_TYPE(OKIM6650, okim6650_device, "okim6650", "OKI MSM6650 ADPCM") -okim6376_device::okim6376_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, OKIM6376, tag, owner, clock), +okim6376_device::okim6376_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int addrbits) + : device_t(mconfig, type, tag, owner, clock), device_sound_interface(mconfig, *this), - m_region_base(*this, DEVICE_SELF), + device_rom_interface(mconfig, *this, addrbits, ENDIANNESS_BIG, 8), //m_command[OKIM6376_VOICES], m_latch(0), //m_stage[OKIM6376_VOICES], @@ -133,6 +134,16 @@ okim6376_device::okim6376_device(const machine_config &mconfig, const char *tag, { } +okim6376_device::okim6376_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : okim6376_device(mconfig, OKIM6376, tag, owner, clock, 21) +{ +} + +okim6650_device::okim6650_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : okim6376_device(mconfig, OKIM6650, tag, owner, clock, 23) +{ +} + //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- @@ -184,6 +195,11 @@ void okim6376_device::device_reset() } +void okim6376_device::rom_bank_updated() +{ +} + + /********************************************************************************************** clock_adpcm -- clock the next ADPCM byte @@ -212,13 +228,34 @@ int16_t okim6376_device::ADPCMVoice::clock(uint8_t nibble) } +offs_t okim6376_device::get_start_position(int channel) +{ + offs_t base = m_command[channel] * 4; + + // max address space is 16Mbit + return (read_byte(base+0) << 16 | read_byte(base+1) << 8 | read_byte(base+2)) & 0x1fffff; +} + + +offs_t okim6650_device::get_start_position(int channel) +{ + offs_t base = 0x000800 + m_command[channel] * 4; + + // determine sampling frequency for phrase + uint8_t data = read_byte(base); + m_divisor = ((data & 3) == 2 ? 5 : 8 - (data & 3) * 2) * (BIT(data, 2) ? 2 : 1); + notify_clock_changed(); + + // max address space is 64Mbit + return (read_byte(base+1) << 16 | read_byte(base+2) << 8 | read_byte(base+3)) & 0x7fffff; +} + + void okim6376_device::oki_process(int channel, int command) { /* if a command is pending, process the second half */ if ((command != -1) && (command != 0)) //process silence separately { - int start; - unsigned char *base/*, *base_end*/; /* update the stream */ m_stream->update(); @@ -226,10 +263,8 @@ void okim6376_device::oki_process(int channel, int command) { struct ADPCMVoice *voice = &m_voice[channel]; - /* determine the start position, max address space is 16Mbit */ - base = &m_region_base[m_command[channel] * 4]; - //base_end = &m_region_base[(MAX_WORDS+1) * 4]; - start = ((base[0] << 16) + (base[1] << 8) + base[2]) & 0x1fffff; + // determine the start position + offs_t start = get_start_position(channel); if (start == 0) { @@ -293,7 +328,7 @@ void okim6376_device::generate_adpcm(struct ADPCMVoice *voice, int16_t *buffer, /* if this voice is active */ if (voice->playing) { - uint8_t *base = m_region_base + voice->base_offset; + offs_t base = voice->base_offset; int sample = voice->sample; int count = voice->count; @@ -305,7 +340,7 @@ void okim6376_device::generate_adpcm(struct ADPCMVoice *voice, int16_t *buffer, if (count == 0) { /* get the number of samples to play */ - count = (base[sample / 2] & 0x7f) << 1; + count = (read_byte(base + sample / 2) & 0x7f) << 1; /* end of voice marker */ if (count == 0) @@ -321,7 +356,7 @@ void okim6376_device::generate_adpcm(struct ADPCMVoice *voice, int16_t *buffer, } /* compute the new amplitude and update the current step */ - nibble = base[sample / 2] >> (((sample & 1) << 2) ^ 4); + nibble = read_byte(base + sample / 2) >> (((sample & 1) << 2) ^ 4); /* output to the buffer, scaling by the volume */ /* signal in range -4096..4095, volume in range 2..16 => signal * volume / 2 in range -32768..32767 */ @@ -400,6 +435,11 @@ void okim6376_device::device_clock_changed() m_stream->set_sample_rate(clock() / m_divisor); } +void okim6650_device::device_clock_changed() +{ + m_stream->set_sample_rate(clock() / 64 / m_divisor); +} + /********************************************************************************************** @@ -425,14 +465,14 @@ READ_LINE_MEMBER( okim6376_device::busy_r ) READ_LINE_MEMBER( okim6376_device::nar_r ) { - MSM6376LOG("OKIM6376: NAR %x\n",m_nar); + LOG("OKIM6376: NAR %x\n",m_nar); return m_nar; } WRITE_LINE_MEMBER( okim6376_device::ch2_w ) { m_ch2_update = 0;//Clear flag - MSM6376LOG("OKIM6376: CH2 %x\n",state); + LOG("OKIM6376: CH2 %x\n",state); if (m_ch2 != state) { @@ -445,7 +485,7 @@ WRITE_LINE_MEMBER( okim6376_device::ch2_w ) struct ADPCMVoice *voice0 = &m_voice[0]; struct ADPCMVoice *voice1 = &m_voice[1]; // We set to channel 2 - MSM6376LOG("OKIM6376: Channel 1\n"); + LOG("OKIM6376: Channel 1\n"); m_channel = 1; if ((voice0->playing)&&(m_st)) @@ -460,7 +500,7 @@ WRITE_LINE_MEMBER( okim6376_device::ch2_w ) { m_stage[1]=0; oki_process(1, m_command[1]); - MSM6376LOG("OKIM6376: Channel 0\n"); + LOG("OKIM6376: Channel 0\n"); m_channel = 0; } } @@ -471,7 +511,7 @@ WRITE_LINE_MEMBER( okim6376_device::st_w ) //As in STart, presumably, this triggers everything m_st_update = 0;//Clear flag - MSM6376LOG("OKIM6376: ST %x\n",state); + LOG("OKIM6376: ST %x\n",state); if (m_st != state) { @@ -483,7 +523,7 @@ WRITE_LINE_MEMBER( okim6376_device::st_w ) struct ADPCMVoice *voice = &m_voice[m_channel]; { m_st_pulses ++; - MSM6376LOG("OKIM6376: ST pulses %x\n",m_st_pulses); + LOG("OKIM6376: ST pulses %x\n",m_st_pulses); if (m_st_pulses > 3) { m_st_pulses = 3; //undocumented behaviour beyond 3 pulses @@ -507,6 +547,12 @@ WRITE_LINE_MEMBER( okim6376_device::st_w ) } } + +WRITE_LINE_MEMBER( okim6650_device::cmd_w ) +{ + // TODO +} + /********************************************************************************************** okim6376_data_w -- write to the data port of an OKIM6376-compatible chip diff --git a/src/devices/sound/okim6376.h b/src/devices/sound/okim6376.h index 91cb3acf7e6..361a9d2ccb0 100644 --- a/src/devices/sound/okim6376.h +++ b/src/devices/sound/okim6376.h @@ -7,8 +7,7 @@ /* an interface for the OKIM6376 and similar chips (CPU interface only) */ -class okim6376_device : public device_t, - public device_sound_interface +class okim6376_device : public device_t, public device_sound_interface, public device_rom_interface { public: okim6376_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -22,6 +21,8 @@ public: DECLARE_READ_LINE_MEMBER( nar_r ); protected: + okim6376_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int addrbits); + // device-level overrides virtual void device_start() override; virtual void device_reset() override; @@ -31,7 +32,11 @@ protected: // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; -private: + // device_rom_interface overrides + virtual void rom_bank_updated() override; + + virtual offs_t get_start_position(int channel); + /* struct describing a single playing ADPCM voice */ struct ADPCMVoice { @@ -50,8 +55,6 @@ private: }; // internal state - required_region_ptr<uint8_t> m_region_base; /* pointer to the base of the region */ - static constexpr unsigned OKIM6376_VOICES = 2; struct ADPCMVoice m_voice[OKIM6376_VOICES]; int32_t m_command[OKIM6376_VOICES]; @@ -75,6 +78,21 @@ private: void adpcm_state_save_register(struct ADPCMVoice *voice, int index); }; +class okim6650_device : public okim6376_device +{ +public: + okim6650_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_WRITE_LINE_MEMBER( cmd_w ); + +protected: + // device-level overrides + virtual void device_clock_changed() override; + + virtual offs_t get_start_position(int channel) override; +}; + DECLARE_DEVICE_TYPE(OKIM6376, okim6376_device) +DECLARE_DEVICE_TYPE(OKIM6650, okim6650_device) #endif // MAME_SOUND_OKIM6376_H |