summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/asc.h
blob: 582f7ce5e931cc7e1739241661235a8de95d2b51 (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
// license:BSD-3-Clause
// copyright-holders:R. Belmont
/***************************************************************************

    asc.h

    Apple Sound Chip (ASC) 344S0063
    Enhanced Apple Sound Chip (EASC) 343S1063

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

#ifndef MAME_SOUND_ASC_H
#define MAME_SOUND_ASC_H

#pragma once



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

#define MCFG_ASC_ADD(_tag, _clock, _type, _irqf) \
	MCFG_DEVICE_ADD(_tag, ASC, _clock) \
	MCFG_ASC_TYPE(_type) \
	MCFG_IRQ_FUNC(_irqf)

#define MCFG_ASC_REPLACE(_tag, _clock, _type, _irqf) \
	MCFG_DEVICE_REPLACE(_tag, ASC, _clock) \
	MCFG_ASC_TYPE(_type) \
	MCFG_IRQ_FUNC(_irqf)

#define MCFG_ASC_TYPE(_type) \
	downcast<asc_device &>(*device).set_type(asc_device::asc_type::_type);

#define MCFG_IRQ_FUNC(_irqf) \
	downcast<asc_device *>(device)->set_irqf(DEVCB_##_irqf);


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

// ======================> asc_device

class asc_device : public device_t, public device_sound_interface
{
public:
	// chip behavior types
	enum class asc_type : uint8_t
	{
		ASC = 0,    // original discrete Apple Sound Chip
		EASC = 1,   // discrete Enhanced Apple Sound Chip
		V8 = 2,     // Subset of ASC included in the V8 ASIC (LC/LCII)
		EAGLE = 3,  // Subset of ASC included in the Eagle ASIC (Classic II)
		SPICE = 4,  // Subset of ASC included in the Spice ASIC (Color Classic)
		SONORA = 5, // Subset of ASC included in the Sonora ASIC (LCIII)
		VASP = 6,   // Subset of ASC included in the VASP ASIC  (IIvx/IIvi)
		ARDBEG = 7  // Subset of ASC included in the Ardbeg ASIC (LC520)
	};

	asc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, asc_type type)
		: asc_device(mconfig, tag, owner, clock)
	{
		set_type(type);
	}

	asc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	void set_type(asc_type type) { m_chip_type = type; }
	template <class Write> devcb_base &set_irqf(Write &&wr)
	{
		return write_irq.set_callback(std::forward<Write>(wr));
	}
	auto irqf_callback() { return write_irq.bind(); }

	DECLARE_READ8_MEMBER(read);
	DECLARE_WRITE8_MEMBER(write);

protected:
	enum
	{
		R_VERSION = 0x800,
		R_MODE,
		R_CONTROL,
		R_FIFOMODE,
		R_FIFOSTAT,
		R_WTCONTROL,
		R_VOLUME,
		R_CLOCK,
		R_REG8,
		R_REG9,
		R_PLAYRECA,
		R_REGB,
		R_REGC,
		R_REGD,
		R_REGE,
		R_TEST
	};

	// 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;

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

	devcb_write_line write_irq;

	sound_stream *m_stream;

	// inline data
	asc_type  m_chip_type;

	uint8_t   m_fifo_a[0x400];
	uint8_t   m_fifo_b[0x400];

	uint8_t   m_regs[0x800];

	uint32_t  m_phase[4], m_incr[4];

	int m_fifo_a_rdptr, m_fifo_b_rdptr;
	int m_fifo_a_wrptr, m_fifo_b_wrptr;
	int     m_fifo_cap_a, m_fifo_cap_b;

	emu_timer *m_timer;
};


// device type definition
DECLARE_DEVICE_TYPE(ASC, asc_device)

#endif // MAME_SOUND_ASC_H