1 // license:BSD-3-Clause
2 // copyright-holders:Ariane Fugmann
3 
4 /*
5 N-Sub Oscillator 97271-P
6 -----------------------------
7 for the time being this is a simple sample player based on the work by MASH.
8 */
9 
10 #include "emu.h"
11 #include "speaker.h"
12 #include "audio/vicdual-97271p.h"
13 
14 #define S97271P_TAG     "s97271p"
15 
16 //**************************************************************************
17 //  GLOBAL VARIABLES
18 //**************************************************************************
19 
20 DEFINE_DEVICE_TYPE(S97271P, s97271p_device, "s97271p", "N-Sub Oscillator 97271-P")
21 
22 /* bit definitions - sound effect drive outputs */
23 #define S97271P_WARNING      0x01
24 #define S97271P_SONAR        0x02
25 #define S97271P_LAUNCH       0x04
26 #define S97271P_EXPL_L       0x08
27 #define S97271P_EXPL_S       0x10
28 #define S97271P_BONUS        0x20
29 #define S97271P_CODE         0x40
30 #define S97271P_BOAT         0x80
31 
32 /* sample file names */
33 static const char *const nsub_sample_names[] =
34 {
35 	"*nsub",
36 	"SND_EXPL_L0",
37 	"SND_EXPL_L1",
38 	"SND_SONAR",
39 	"SND_LAUNCH0",
40 	"SND_LAUNCH1",
41 	"SND_WARNING0",
42 	"SND_WARNING1",
43 	"SND_EXPL_S0",
44 	"SND_EXPL_S1",
45 	"SND_BONUS0",
46 	"SND_BONUS1",
47 	"SND_CODE",
48 	"SND_BOAT",
49 	nullptr
50 };
51 
52 /* sample ids - must match sample file name table above */
53 enum
54 {
55 	SND_EXPL_L0 = 0,
56 	SND_EXPL_L1,
57 	SND_SONAR,
58 	SND_LAUNCH0,
59 	SND_LAUNCH1,
60 	SND_WARNING0,
61 	SND_WARNING1,
62 	SND_EXPL_S0,
63 	SND_EXPL_S1,
64 	SND_BONUS0,
65 	SND_BONUS1,
66 	SND_CODE,
67 	SND_BOAT
68 };
69 
70 
71 //**************************************************************************
72 //  LIVE DEVICE
73 //**************************************************************************
74 
75 //-------------------------------------------------
76 //  s97271p_device - constructor
77 //-------------------------------------------------
78 
s97271p_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)79 s97271p_device::s97271p_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
80 	device_t(mconfig, S97271P, tag, owner, clock),
81 	m_samples(*this, "samples")
82 {
83 }
84 
85 //-------------------------------------------------
86 // device_add_mconfig - add device configuration
87 //-------------------------------------------------
88 
device_add_mconfig(machine_config & config)89 void s97271p_device::device_add_mconfig(machine_config &config)
90 {
91 	SPEAKER(config, "mono").front_center();
92 
93 	/* samples */
94 	SAMPLES(config, m_samples);
95 	m_samples->set_channels(13);
96 	m_samples->set_samples_names(nsub_sample_names);
97 	m_samples->add_route(ALL_OUTPUTS, "mono", 0.5);
98 }
99 
100 //-------------------------------------------------
101 //  device_start - device-specific startup
102 //-------------------------------------------------
103 
device_start()104 void s97271p_device::device_start()
105 {
106 	save_item(NAME(m_state));
107 }
108 
109 //-------------------------------------------------
110 //  device_reset - device-specific reset
111 //-------------------------------------------------
112 
device_reset()113 void s97271p_device::device_reset()
114 {
115 	m_state = 0xff;
116 }
117 
port_w(uint8_t data)118 void s97271p_device::port_w(uint8_t data)
119 {
120 	uint8_t bitsChanged = m_state ^ data;
121 	uint8_t bitsGoneHigh = bitsChanged & data;
122 	uint8_t bitsGoneLow = bitsChanged & ~data;
123 	m_state = data;
124 
125 	if (bitsGoneLow & S97271P_WARNING)
126 	{
127 		m_samples->start(SND_WARNING0, SND_WARNING0, 1);
128 		m_samples->stop(SND_WARNING1);
129 	} else if (bitsGoneHigh & S97271P_WARNING)
130 	{
131 		m_samples->start(SND_WARNING1, SND_WARNING1, 0);
132 		m_samples->stop(SND_WARNING0);
133 	}
134 
135 	if (bitsGoneLow & S97271P_SONAR)
136 	{
137 		m_samples->start(SND_SONAR, SND_SONAR, 1);
138 	} else if (bitsGoneHigh & S97271P_SONAR)
139 	{
140 		m_samples->stop(SND_SONAR);
141 	}
142 
143 	if (bitsGoneLow & S97271P_LAUNCH)
144 	{
145 		m_samples->start(SND_LAUNCH0, SND_LAUNCH0, 1);
146 		m_samples->stop(SND_LAUNCH1);
147 	} else if (bitsGoneHigh & S97271P_LAUNCH)
148 	{
149 		m_samples->start(SND_LAUNCH1, SND_LAUNCH1, 0);
150 		m_samples->stop(SND_LAUNCH0);
151 	}
152 
153 	if (bitsGoneLow & S97271P_EXPL_L)
154 	{
155 		m_samples->start(SND_EXPL_L0, SND_EXPL_L0, 1);
156 		m_samples->stop(SND_EXPL_L1);
157 	} else if (bitsGoneHigh & S97271P_EXPL_L)
158 	{
159 		m_samples->start(SND_EXPL_L1, SND_EXPL_L1, 0);
160 		m_samples->stop(SND_EXPL_L0);
161 	}
162 
163 	if (bitsGoneLow & S97271P_EXPL_S)
164 	{
165 		m_samples->start(SND_EXPL_S0, SND_EXPL_S0, 1);
166 		m_samples->stop(SND_EXPL_S1);
167 	} else if (bitsGoneHigh & S97271P_EXPL_S)
168 	{
169 		m_samples->start(SND_EXPL_S1, SND_EXPL_S1, 0);
170 		m_samples->stop(SND_EXPL_S0);
171 	}
172 
173 	if (bitsGoneLow & S97271P_BONUS)
174 	{
175 		m_samples->start(SND_BONUS0, SND_BONUS0, 1);
176 		m_samples->stop(SND_BONUS1);
177 	} else if (bitsGoneHigh & S97271P_BONUS)
178 	{
179 		m_samples->start(SND_BONUS1, SND_BONUS1, 0);
180 		m_samples->stop(SND_BONUS0);
181 	}
182 
183 	if (bitsGoneLow & S97271P_CODE)
184 	{
185 		m_samples->start(SND_CODE, SND_CODE, 1);
186 	} else if (bitsGoneHigh & S97271P_CODE)
187 	{
188 		m_samples->stop(SND_CODE);
189 	}
190 
191 	if (bitsGoneLow & S97271P_BOAT)
192 	{
193 		m_samples->start(SND_BOAT, SND_BOAT, 1);
194 	} else if (bitsGoneHigh & S97271P_BOAT)
195 	{
196 		m_samples->stop(SND_BOAT);
197 	}
198 }
199