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
|
// license:BSD-3-Clause
// copyright-holders:R. Belmont
#pragma once
#ifndef __C352_H__
#define __C352_H__
//**************************************************************************
// CONSTANTS
//**************************************************************************
enum
{
C352_DIVIDER_228 = 0,
C352_DIVIDER_288 = 1,
C352_DIVIDER_332 = 2
};
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_C352_ADD(_tag, _clock, _setting) \
MCFG_DEVICE_ADD(_tag, C352, _clock) \
MCFG_C352_DIVIDER(_setting)
#define MCFG_C352_DIVIDER(_setting) \
c352_device::static_set_divider(*device, _setting);
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> asc_device
class c352_device : public device_t,
public device_sound_interface,
public device_memory_interface
{
public:
// construction/destruction
c352_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
// inline configuration helpers
static void static_set_divider(device_t &device, int setting);
DECLARE_READ16_MEMBER(read);
DECLARE_WRITE16_MEMBER(write);
sound_stream *m_stream;
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
// device_sound_interface overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
// device_memory_interface overrides
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
const address_space_config m_space_config;
private:
enum {
C352_FLG_BUSY = 0x8000, // channel is busy
C352_FLG_KEYON = 0x4000, // Keyon
C352_FLG_KEYOFF = 0x2000, // Keyoff
C352_FLG_LOOPTRG = 0x1000, // Loop Trigger
C352_FLG_LOOPHIST = 0x0800, // Loop History
C352_FLG_FM = 0x0400, // Frequency Modulation
C352_FLG_PHASERL = 0x0200, // Rear Left invert phase 180 degrees
C352_FLG_PHASEFL = 0x0100, // Front Left invert phase 180 degrees
C352_FLG_PHASEFR = 0x0080, // invert phase 180 degrees (e.g. flip sign of sample)
C352_FLG_LDIR = 0x0040, // loop direction
C352_FLG_LINK = 0x0020, // "long-format" sample (can't loop, not sure what else it means)
C352_FLG_NOISE = 0x0010, // play noise instead of sample
C352_FLG_MULAW = 0x0008, // sample is mulaw instead of linear 8-bit PCM
C352_FLG_FILTER = 0x0004, // don't apply filter
C352_FLG_REVLOOP = 0x0003, // loop backwards
C352_FLG_LOOP = 0x0002, // loop forward
C352_FLG_REVERSE = 0x0001 // play sample backwards
};
struct c352_ch_t
{
UINT8 vol_l;
UINT8 vol_r;
UINT8 vol_l2;
UINT8 vol_r2;
UINT8 bank;
INT16 noise;
INT16 noisebuf;
UINT16 noisecnt;
UINT16 pitch;
UINT16 start_addr;
UINT16 end_addr;
UINT16 repeat_addr;
UINT32 flag;
UINT16 start;
UINT16 repeat;
UINT32 current_addr;
UINT32 pos;
};
c352_ch_t m_c352_ch[32];
int m_sample_rate_base;
int m_divider;
long m_channel_l[2048*2];
long m_channel_r[2048*2];
long m_channel_l2[2048*2];
long m_channel_r2[2048*2];
short m_mulaw_table[256];
unsigned int m_mseq_reg;
direct_read_data *m_direct;
// private functions
int get_mseq_bit(void);
void mix_one_channel(unsigned long ch, long sample_count);
unsigned short read_reg16(unsigned long address);
void write_reg16(unsigned long address, unsigned short val);
};
// device type definition
extern const device_type C352;
#endif /* __C352_H__ */
|