summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/okim6376.h
blob: df5255291b116382f9797170762e8246e9d02ba1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// license:BSD-3-Clause
// copyright-holders:Mirko Buffoni, James Wallace
#pragma once

#ifndef __OKIM6376_H__
#define __OKIM6376_H__

/* an interface for the OKIM6376 and similar chips (CPU interface only) */

/* struct describing a single playing ADPCM voice */
struct ADPCMVoice
{
	UINT8 playing;          /* 1 if we are actively playing */

	UINT32 base_offset;     /* pointer to the base memory location */
	UINT32 sample;          /* current sample number */
	UINT32 count;           /* total samples to play */

	UINT32 volume;          /* output volume */
	INT32 signal;
	INT32 step;
};

class okim6376_device : public device_t,
									public device_sound_interface
{
public:
	okim6376_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
	~okim6376_device() {}

	DECLARE_WRITE8_MEMBER( write );

	DECLARE_WRITE_LINE_MEMBER( st_w );
	DECLARE_WRITE_LINE_MEMBER( ch2_w );

	DECLARE_READ_LINE_MEMBER( busy_r );
	DECLARE_READ_LINE_MEMBER( nar_r );

	void set_frequency(int frequency);


protected:
	// device-level overrides
	virtual void device_config_complete() override;
	virtual void device_start() override;
	virtual void device_reset() override;

	// sound stream update overrides
	virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;

private:
	// internal state
	required_region_ptr<UINT8> m_region_base;     /* pointer to the base of the region */

	#define OKIM6376_VOICES     2
	struct ADPCMVoice m_voice[OKIM6376_VOICES];
	INT32 m_command[OKIM6376_VOICES];
	INT32 m_latch;            /* Command data is held before transferring to either channel */
	UINT8 m_stage[OKIM6376_VOICES];/* If a sample is playing, flag that we have a command staged */
	sound_stream *m_stream;   /* which stream are we playing on? */
	UINT32 m_master_clock;    /* master clock frequency */
	UINT8 m_divisor;          /* can be 8,10,16, and is read out of ROM data */
	UINT8 m_channel;
	UINT8 m_nar;              /* Next Address Ready */
	UINT8 m_nartimer;
	UINT8 m_busy;
	UINT8 m_ch2;              /* 2CH pin - enables Channel 2 operation */
	UINT8 m_st;               /* STart */
	UINT8 m_st_pulses;        /* Keep track of attenuation */
	UINT8 m_ch2_update;       /* Pulse shape */
	UINT8 m_st_update;

	void oki_process(int channel, int command);
	void generate_adpcm(struct ADPCMVoice *voice, INT16 *buffer, int samples,int channel);
	void postload();
	void okim6376_state_save_register();
	void adpcm_state_save_register(struct ADPCMVoice *voice, int index);
};

extern const device_type OKIM6376;

#endif /* __OKIM6376_H__ */