summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/sound/okim6295.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/sound/okim6295.h')
-rw-r--r--src/emu/sound/okim6295.h192
1 files changed, 167 insertions, 25 deletions
diff --git a/src/emu/sound/okim6295.h b/src/emu/sound/okim6295.h
index f5b5b566eff..b0ead224399 100644
--- a/src/emu/sound/okim6295.h
+++ b/src/emu/sound/okim6295.h
@@ -1,44 +1,186 @@
+/***************************************************************************
+
+ okim6295.h
+
+ OKIM 6295 ADCPM sound chip.
+
+***************************************************************************/
+
#pragma once
#ifndef __OKIM6295_H__
#define __OKIM6295_H__
-/* an interface for the OKIM6295 and similar chips */
+#include "streams.h"
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
-/*
- Note about the playback frequency: the external clock is internally divided,
- depending on pin 7, by 132 (high) or 165 (low).
-*/
-typedef struct _okim6295_interface okim6295_interface;
-struct _okim6295_interface
+enum
{
- int pin7;
+ OKIM6295_PIN7_LOW = 0,
+ OKIM6295_PIN7_HIGH = 1
};
-extern const okim6295_interface okim6295_interface_pin7high;
-extern const okim6295_interface okim6295_interface_pin7low;
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
-void okim6295_set_bank_base(running_device *device, int base);
-void okim6295_set_pin7(running_device *device, int pin7);
+#define MDRV_OKIM6295_ADD(_tag, _clock, _pin7) \
+ MDRV_DEVICE_ADD(_tag, SOUND_OKIM6295, _clock) \
+ MDRV_OKIM6295_PIN7(_pin7)
-READ8_DEVICE_HANDLER( okim6295_r );
-WRITE8_DEVICE_HANDLER( okim6295_w );
+#define MDRV_OKIM6295_REPLACE(_tag, _clock, _pin7) \
+ MDRV_DEVICE_REPLACE(_tag, SOUND_OKIM6295, _clock) \
+ MDRV_OKIM6295_PIN7(_pin7)
+
+#define MDRV_OKIM6295_PIN7(_pin7) \
+ MDRV_DEVICE_INLINE_DATA16(okim6295_device_config::INLINE_PIN7, _pin7)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
-/*
- To help the various custom ADPCM generators out there,
- the following routines may be used.
-*/
-struct adpcm_state
+
+// ======================> adpcm_state
+
+// Internal ADPCM state, used by external ADPCM generators with compatible specs to the OKIM 6295.
+class adpcm_state
{
- INT32 signal;
- INT32 step;
+public:
+ adpcm_state() { compute_tables(); reset(); }
+
+ void reset();
+ INT16 clock(UINT8 nibble);
+
+ INT32 m_signal;
+ INT32 m_step;
+
+private:
+ static const INT8 s_index_shift[8];
+ static int s_diff_lookup[49*16];
+
+ static void compute_tables();
+ static bool s_tables_computed;
};
-void reset_adpcm(struct adpcm_state *state);
-INT16 clock_adpcm(struct adpcm_state *state, UINT8 nibble);
-DEVICE_GET_INFO( okim6295 );
-#define SOUND_OKIM6295 DEVICE_GET_INFO_NAME( okim6295 )
+
+
+// ======================> okim6295_device_config
+
+class okim6295_device_config : public device_config,
+ public device_config_sound_interface,
+ public device_config_memory_interface
+{
+ friend class okim6295_device;
+
+ // construction/destruction
+ okim6295_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
+
+public:
+ // allocators
+ static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
+ virtual device_t *alloc_device(running_machine &machine) const;
+
+ // basic information getters
+ virtual const char *name() const { return "OKI6295"; }
+
+ // inline configuration indexes
+ enum
+ {
+ INLINE_PIN7
+ };
+
+protected:
+ // device_config overrides
+ virtual void device_config_complete();
+ virtual const address_space_config *memory_space_config(int spacenum = 0) const;
+
+ // internal state
+ const address_space_config m_space_config;
+ UINT8 m_pin7;
+};
+
+
+
+// ======================> okim6295_device
+
+class okim6295_device : public device_t,
+ public device_sound_interface,
+ public device_memory_interface
+{
+ friend class okim6295_device_config;
+
+ // construction/destruction
+ okim6295_device(running_machine &_machine, const okim6295_device_config &config);
+
+public:
+ void set_bank_base(offs_t base);
+ void set_pin7(int pin7);
+
+ UINT8 status_read();
+ void data_write(UINT8 data);
+
+protected:
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+ virtual void device_post_load();
+ virtual void device_clock_changed();
+
+ // internal callbacks
+ static STREAM_UPDATE( static_stream_generate );
+ virtual void stream_generate(stream_sample_t **inputs, stream_sample_t **outputs, int samples);
+
+ // a single voice
+ class okim_voice
+ {
+ public:
+ okim_voice();
+ void generate_adpcm(const address_space *space, stream_sample_t *buffer, int samples);
+
+ adpcm_state m_adpcm; // current ADPCM state
+ bool m_playing;
+ offs_t m_base_offset; // pointer to the base memory location
+ UINT32 m_sample; // current sample number
+ UINT32 m_count; // total samples to play
+ INT8 m_volume; // output volume
+ };
+
+ // internal state
+ static const int OKIM6295_VOICES = 4;
+
+ const okim6295_device_config &m_config;
+
+ okim_voice m_voice[OKIM6295_VOICES];
+ INT32 m_command;
+ bool m_bank_installed;
+ offs_t m_bank_offs;
+ sound_stream * m_stream;
+ UINT8 m_pin7_state;
+
+ static const UINT8 s_volume_table[16];
+};
+
+
+// device type definition
+const device_type SOUND_OKIM6295 = okim6295_device_config::static_alloc_device_config;
+
+
+
+//**************************************************************************
+// READ/WRITE HANDLERS
+//**************************************************************************
+
+READ8_DEVICE_HANDLER( okim6295_r );
+WRITE8_DEVICE_HANDLER( okim6295_w );
+
#endif /* __OKIM6295_H__ */