summaryrefslogtreecommitdiffstats
path: root/src/devices/sound/dave.h
blob: 61e26608f00198b63d54efb4e0ffc3339297aff1 (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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/**********************************************************************

    Intelligent Designs DAVE emulation

**********************************************************************/

#ifndef MAME_SOUND_DAVE_H
#define MAME_SOUND_DAVE_H

#pragma once


///*************************************************************************
//  MACROS / CONSTANTS
///*************************************************************************



///*************************************************************************
//  INTERFACE CONFIGURATION MACROS
///*************************************************************************

#define MCFG_DAVE_ADD(_tag, _clock, _program_map, _io_map) \
	SPEAKER(config, "lspeaker").front_left(); \
	SPEAKER(config, "rspeaker").front_right(); \
	MCFG_DEVICE_ADD(_tag, DAVE, _clock) \
	MCFG_SOUND_ROUTE(0, "lspeaker", 0.25) \
	MCFG_SOUND_ROUTE(1, "rspeaker", 0.25) \
	MCFG_DEVICE_ADDRESS_MAP(AS_PROGRAM, _program_map) \
	MCFG_DEVICE_ADDRESS_MAP(AS_IO, _io_map)


#define MCFG_DAVE_IRQ_CALLBACK(_write) \
	devcb = &downcast<dave_device &>(*device).set_irq_wr_callback(DEVCB_##_write);

#define MCFG_DAVE_LH_CALLBACK(_write) \
	devcb = &downcast<dave_device &>(*device).set_lh_wr_callback(DEVCB_##_write);

#define MCFG_DAVE_RH_CALLBACK(_write) \
	devcb = &downcast<dave_device &>(*device).set_rh_wr_callback(DEVCB_##_write);



///*************************************************************************
//  TYPE DEFINITIONS
///*************************************************************************

// ======================> dave_device

class dave_device : public device_t,
					public device_memory_interface,
					public device_sound_interface
{
public:
	dave_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	template <class Object> devcb_base &set_irq_wr_callback(Object &&cb) { return m_write_irq.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_lh_wr_callback(Object &&cb) { return m_write_lh.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_rh_wr_callback(Object &&cb) { return m_write_rh.set_callback(std::forward<Object>(cb)); }

	virtual void z80_program_map(address_map &map);
	virtual void z80_io_map(address_map &map);

	DECLARE_WRITE_LINE_MEMBER( int1_w );
	DECLARE_WRITE_LINE_MEMBER( int2_w );

	void io_map(address_map &map);
	void program_map(address_map &map);
protected:
	// device-level overrides
	virtual void device_start() override;
	virtual void device_reset() override;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;

	// device_memory_interface overrides
	virtual space_config_vector memory_space_config() const override;

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

	DECLARE_READ8_MEMBER( program_r );
	DECLARE_WRITE8_MEMBER( program_w );

	DECLARE_READ8_MEMBER( io_r );
	DECLARE_WRITE8_MEMBER( io_w );

private:
	enum
	{
		TIMER_1HZ,
		TIMER_50HZ
	};

	enum
	{
		IRQ_50HZ_DIVIDER    = 0x01,
		IRQ_50HZ_LATCH      = 0x02,
		IRQ_1HZ_DIVIDER     = 0x04,
		IRQ_1HZ_LATCH       = 0x08,
		IRQ_INT1            = 0x10,
		IRQ_INT1_LATCH      = 0x20,
		IRQ_INT2            = 0x40,
		IRQ_INT2_LATCH      = 0x80,
		IRQ_LATCH           = IRQ_INT2_LATCH | IRQ_INT1_LATCH | IRQ_1HZ_LATCH | IRQ_50HZ_LATCH
	};

	void update_interrupt();

	const address_space_config m_program_space_config;
	const address_space_config m_io_space_config;

	devcb_write_line m_write_irq;
	devcb_write8 m_write_lh;
	devcb_write8 m_write_rh;

	uint8_t m_segment[4];

	uint8_t m_irq_status;
	uint8_t m_irq_enable;

	emu_timer *m_timer_1hz;
	emu_timer *m_timer_50hz;

	/* SOUND SYNTHESIS */
	uint8_t m_regs[32];
	int m_period[4];
	int m_count[4];
	int m_level[4];

	/* these are used to force channels on/off */
	/* if one of the or values is 0x0ff, this means
	 the volume will be forced on,else it is dependant on
	 the state of the wave */
	int m_level_or[8];
	/* if one of the values is 0x00, this means the
	 volume is forced off, else it is dependant on the wave */
	int m_level_and[8];

	/* these are the current channel volumes in MAME form */
	int m_mame_volumes[8];

	/* update step */
	//int m_update_step;

	sound_stream *m_sound_stream_var;
};


// device type definition
DECLARE_DEVICE_TYPE(DAVE, dave_device)

#endif // MAME_SOUND_DAVE_H