1 // license:BSD-3-Clause
2 // copyright-holders:Nicola Salmoria
3 /*********************************************************/
4 /*    Konami PCM controller                              */
5 /*********************************************************/
6 
7 #ifndef MAME_SOUND_K007232_H
8 #define MAME_SOUND_K007232_H
9 
10 #pragma once
11 
12 class k007232_device : public device_t, public device_sound_interface, public device_memory_interface
13 {
14 public:
15 	k007232_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
16 
port_write()17 	auto port_write() { return m_port_write_handler.bind(); }
18 
19 	void write(offs_t offset, u8 data);
20 	u8 read(offs_t offset);
21 
22 	/*
23 	The 007232 has two channels and produces two outputs. The volume control
24 	is external, however to make it easier to use we handle that inside the
25 	emulation. You can control volume and panning: for each of the two channels
26 	you can set the volume of the two outputs. If panning is not required,
27 	then volumeB will be 0 for channel 0, and volumeA will be 0 for channel 1.
28 	Volume is in the range 0-255.
29 	*/
30 	void set_volume(int channel,int volumeA,int volumeB);
31 
32 	void set_bank( int chABank, int chBBank );
33 
34 protected:
35 	// device-level overrides
36 	virtual void device_start() override;
37 	virtual void device_clock_changed() override;
38 
39 	// sound stream update overrides
40 	virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
41 
42 	// device_memory_interface configuration
43 	virtual space_config_vector memory_space_config() const override;
44 
45 	address_space_config m_data_config;
46 
47 private:
48 	static constexpr unsigned KDAC_A_PCM_MAX = 2;      /* Channels per chip */
49 
50 	// internal state
51 	memory_access<17, 0, 0, ENDIANNESS_LITTLE>::cache m_cache;
52 	optional_region_ptr<u8> m_rom;
53 
54 	struct channel_t
55 	{
56 		u8           vol[2]; /* volume for the left and right channel */
57 		u32          addr;
58 		int          counter;
59 		u32          start;
60 		u16          step;
61 		u32          bank;
62 		bool         play;
63 	};
64 
read_rom_default(offs_t offset)65 	u8 read_rom_default(offs_t offset) { return m_rom[(m_bank + (offset & 0x1ffff)) & m_rom.mask()]; }
read_sample(int channel,u32 addr)66 	inline u8 read_sample(int channel, u32 addr) { m_bank = m_channel[channel].bank; return m_cache.read_byte(addr & 0x1ffff); }
67 
68 	channel_t     m_channel[KDAC_A_PCM_MAX]; // 2 channels
69 
70 	u8            m_wreg[0x10]; /* write data */
71 
72 	u32           m_pcmlimit;
73 	u32           m_bank;
74 
75 	sound_stream *m_stream;
76 	devcb_write8  m_port_write_handler;
77 };
78 
79 DECLARE_DEVICE_TYPE(K007232, k007232_device)
80 
81 #endif // MAME_SOUND_K007232_H
82