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
|
#pragma once
#ifndef __YMF271_H__
#define __YMF271_H__
#include "emu.h"
#define MCFG_YMF271_IRQ_HANDLER(_devcb) \
devcb = &ymf271_device::set_irq_handler(*device, DEVCB2_##_devcb);
#define MCFG_YMF271_EXT_READ_HANDLER(_devcb) \
devcb = &ymf271_device::set_ext_read_handler(*device, DEVCB2_##_devcb);
#define MCFG_YMF271_EXT_WRITE_HANDLER(_devcb) \
devcb = &ymf271_device::set_ext_write_handler(*device, DEVCB2_##_devcb);
class ymf271_device : public device_t,
public device_sound_interface
{
public:
ymf271_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
// static configuration helpers
template<class _Object> static devcb2_base &set_irq_handler(device_t &device, _Object object) { return downcast<ymf271_device &>(device).m_irq_handler.set_callback(object); }
template<class _Object> static devcb2_base &set_ext_read_handler(device_t &device, _Object object) { return downcast<ymf271_device &>(device).m_ext_read_handler.set_callback(object); }
template<class _Object> static devcb2_base &set_ext_write_handler(device_t &device, _Object object) { return downcast<ymf271_device &>(device).m_ext_write_handler.set_callback(object); }
DECLARE_READ8_MEMBER( read );
DECLARE_WRITE8_MEMBER( write );
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
private:
struct YMF271Slot
{
INT8 ext_en;
INT8 ext_out;
UINT8 lfoFreq;
INT8 lfowave;
INT8 pms, ams;
INT8 detune;
INT8 multiple;
INT8 tl;
INT8 keyscale;
INT8 ar;
INT8 decay1rate, decay2rate;
INT8 decay1lvl;
INT8 relrate;
INT32 fns;
INT8 block;
INT8 feedback;
INT8 waveform;
INT8 accon;
INT8 algorithm;
INT8 ch0_level, ch1_level, ch2_level, ch3_level;
UINT32 startaddr;
UINT32 loopaddr;
UINT32 endaddr;
INT8 altloop;
INT8 fs, srcnote, srcb;
INT64 step;
INT64 stepptr;
INT8 active;
INT8 bits;
// envelope generator
INT32 volume;
INT32 env_state;
INT32 env_attack_step; // volume increase step in attack state
INT32 env_decay1_step;
INT32 env_decay2_step;
INT32 env_release_step;
INT64 feedback_modulation0;
INT64 feedback_modulation1;
INT32 lfo_phase, lfo_step;
INT32 lfo_amplitude;
double lfo_phasemod;
};
struct YMF271Group
{
INT8 sync, pfm;
};
void init_state();
void calculate_step(YMF271Slot *slot);
void update_envelope(YMF271Slot *slot);
void init_envelope(YMF271Slot *slot);
void init_lfo(YMF271Slot *slot);
void update_lfo(YMF271Slot *slot);
int calculate_slot_volume(YMF271Slot *slot);
void update_pcm(int slotnum, INT32 *mixp, int length);
INT32 calculate_2op_fm_0(int slotnum1, int slotnum2);
INT32 calculate_2op_fm_1(int slotnum1, int slotnum2);
INT32 calculate_1op_fm_0(int slotnum, int phase_modulation);
INT32 calculate_1op_fm_1(int slotnum);
void write_register(int slotnum, int reg, int data);
void ymf271_write_fm(int grp, int adr, int data);
void ymf271_write_pcm(int data);
UINT8 ymf271_read_ext_memory(UINT32 address);
void ymf271_write_ext_memory(UINT32 address, UINT8 data);
void ymf271_write_timer(int data);
// internal state
YMF271Slot m_slots[48];
YMF271Group m_groups[12];
INT32 m_timerA;
INT32 m_timerB;
INT32 m_timerAVal;
INT32 m_timerBVal;
INT32 m_irqstate;
INT8 m_status;
INT8 m_enable;
INT8 m_reg0;
INT8 m_reg1;
INT8 m_reg2;
INT8 m_reg3;
INT8 m_pcmreg;
INT8 m_timerreg;
UINT32 m_ext_address;
UINT8 m_ext_read;
const UINT8 *m_rom;
UINT32 m_clock;
emu_timer *m_timA, *m_timB;
sound_stream *m_stream;
devcb2_write_line m_irq_handler;
devcb2_read8 m_ext_read_handler;
devcb2_write8 m_ext_write_handler;
};
extern const device_type YMF271;
#endif /* __YMF271_H__ */
|