1 // license:BSD-3-Clause
2 // copyright-holders:Robbbert
3 /****************************************************************************************
4 
5     PINBALL
6     Atari Generation/System 2 and 3
7 
8     System 2 : Manuals and PinMAME used as references (couldn't find full schematics).
9     System 3 : PinMAME used as reference (couldn't find anything else).
10 
11     The only difference seems to be an extra bank of inputs (or something) at 2008-200B.
12 
13 ToDo:
14 - 4x4 not emulated yet, appears to be a different cpu and hardware.
15 - sounds to be verified against a real machine
16 - noise generator sounds like a loud barrrr instead of noise, fortunately it
17   doesn't seem to be used.
18 - inputs, outputs, dips vary per machine
19 - High score isn't saved or remembered
20 
21 
22 *****************************************************************************************/
23 
24 #include "emu.h"
25 #include "machine/genpin.h"
26 
27 #include "cpu/m6800/m6800.h"
28 #include "machine/timer.h"
29 #include "machine/watchdog.h"
30 #include "sound/dac.h"
31 #include "speaker.h"
32 
33 #include "atari_s2.lh"
34 
35 
36 class atari_s2_state : public genpin_class
37 {
38 public:
atari_s2_state(const machine_config & mconfig,device_type type,const char * tag)39 	atari_s2_state(const machine_config &mconfig, device_type type, const char *tag)
40 		: genpin_class(mconfig, type, tag)
41 		, m_maincpu(*this, "maincpu")
42 		, m_dac(*this, "dac")
43 		, m_dac1(*this, "dac1")
44 		, m_digits(*this, "digit%u", 0U)
45 	{ }
46 
47 	void atari_s2(machine_config &config);
48 	void atari_s3(machine_config &config);
49 
50 private:
51 	void sound0_w(uint8_t data);
52 	void sound1_w(uint8_t data);
lamp_w(uint8_t data)53 	void lamp_w(uint8_t data) { };
54 	void sol0_w(uint8_t data);
sol1_w(uint8_t data)55 	void sol1_w(uint8_t data) { };
56 	void intack_w(uint8_t data);
57 	void display_w(offs_t offset, uint8_t data);
58 	TIMER_DEVICE_CALLBACK_MEMBER(irq);
59 	TIMER_DEVICE_CALLBACK_MEMBER(timer_s);
60 
61 	void atari_s2_map(address_map &map);
62 	void atari_s3_map(address_map &map);
63 
64 	bool m_timer_sb;
65 	uint8_t m_timer_s[5];
66 	uint8_t m_sound0;
67 	uint8_t m_sound1;
68 	uint8_t m_vol;
69 	uint8_t m_t_c;
70 	uint8_t m_segment[7];
71 	uint8_t *m_p_prom;
72 	virtual void machine_reset() override;
machine_start()73 	virtual void machine_start() override { m_digits.resolve(); }
74 	required_device<cpu_device> m_maincpu;
75 	required_device<dac_4bit_binary_weighted_device> m_dac;
76 	required_device<dac_3bit_binary_weighted_device> m_dac1;
77 	output_finder<68> m_digits;
78 };
79 
80 
atari_s2_map(address_map & map)81 void atari_s2_state::atari_s2_map(address_map &map)
82 {
83 	map.global_mask(0x3fff);
84 	map(0x0000, 0x00ff).mirror(0x0700).ram();
85 	map(0x0800, 0x08ff).mirror(0x0700).ram().share("nvram"); // battery backed
86 	map(0x1000, 0x1000).mirror(0x07F8).portr("SWITCH.0");
87 	map(0x1001, 0x1001).mirror(0x07F8).portr("SWITCH.1");
88 	map(0x1002, 0x1002).mirror(0x07F8).portr("SWITCH.2");
89 	map(0x1003, 0x1003).mirror(0x07F8).portr("SWITCH.3");
90 	map(0x1004, 0x1004).mirror(0x07F8).portr("SWITCH.4");
91 	map(0x1005, 0x1005).mirror(0x07F8).portr("SWITCH.5");
92 	map(0x1006, 0x1006).mirror(0x07F8).portr("SWITCH.6");
93 	map(0x1007, 0x1007).mirror(0x07F8).portr("SWITCH.7");
94 	map(0x1800, 0x1800).mirror(0x071F).w(FUNC(atari_s2_state::sound0_w));
95 	map(0x1820, 0x1820).mirror(0x071F).w(FUNC(atari_s2_state::sound1_w));
96 	map(0x1840, 0x1847).mirror(0x0718).w(FUNC(atari_s2_state::display_w));
97 	map(0x1860, 0x1867).mirror(0x0718).w(FUNC(atari_s2_state::lamp_w));
98 	map(0x1880, 0x1880).mirror(0x071F).w(FUNC(atari_s2_state::sol0_w));
99 	map(0x18a0, 0x18a7).mirror(0x0718).w(FUNC(atari_s2_state::sol1_w));
100 	map(0x18c0, 0x18c0).mirror(0x071F).w("watchdog", FUNC(watchdog_timer_device::reset_w));
101 	map(0x18e0, 0x18e0).mirror(0x071F).w(FUNC(atari_s2_state::intack_w));
102 	map(0x2000, 0x2000).mirror(0x07FC).portr("DSW0");
103 	map(0x2001, 0x2001).mirror(0x07FC).portr("DSW1");
104 	map(0x2002, 0x2002).mirror(0x07FC).portr("DSW2");
105 	map(0x2003, 0x2003).mirror(0x07FC).portr("DSW3");
106 	map(0x2800, 0x3fff).rom();
107 }
108 
atari_s3_map(address_map & map)109 void atari_s2_state::atari_s3_map(address_map &map)
110 {
111 	map.global_mask(0x3fff);
112 	map(0x0000, 0x00ff).mirror(0x0700).ram();
113 	map(0x0800, 0x08ff).mirror(0x0700).ram().share("nvram"); // battery backed
114 	map(0x1000, 0x1000).mirror(0x07F8).portr("SWITCH.0");
115 	map(0x1001, 0x1001).mirror(0x07F8).portr("SWITCH.1");
116 	map(0x1002, 0x1002).mirror(0x07F8).portr("SWITCH.2");
117 	map(0x1003, 0x1003).mirror(0x07F8).portr("SWITCH.3");
118 	map(0x1004, 0x1004).mirror(0x07F8).portr("SWITCH.4");
119 	map(0x1005, 0x1005).mirror(0x07F8).portr("SWITCH.5");
120 	map(0x1006, 0x1006).mirror(0x07F8).portr("SWITCH.6");
121 	map(0x1007, 0x1007).mirror(0x07F8).portr("SWITCH.7");
122 	map(0x1800, 0x1800).mirror(0x071F).w(FUNC(atari_s2_state::sound0_w));
123 	map(0x1820, 0x1820).mirror(0x071F).w(FUNC(atari_s2_state::sound1_w));
124 	map(0x1840, 0x1847).mirror(0x0718).w(FUNC(atari_s2_state::display_w));
125 	map(0x1860, 0x1867).mirror(0x0718).w(FUNC(atari_s2_state::lamp_w));
126 	map(0x1880, 0x1880).mirror(0x071F).w(FUNC(atari_s2_state::sol0_w));
127 	map(0x18a0, 0x18a7).mirror(0x0718).w(FUNC(atari_s2_state::sol1_w));
128 	map(0x18c0, 0x18c0).mirror(0x071F).w("watchdog", FUNC(watchdog_timer_device::reset_w));
129 	map(0x18e0, 0x18e0).mirror(0x071F).w(FUNC(atari_s2_state::intack_w));
130 	map(0x2000, 0x2000).mirror(0x07F4).portr("DSW0");
131 	map(0x2001, 0x2001).mirror(0x07F4).portr("DSW1");
132 	map(0x2002, 0x2002).mirror(0x07F4).portr("DSW2");
133 	map(0x2003, 0x2003).mirror(0x07F4).portr("DSW3");
134 	map(0x2008, 0x2008).mirror(0x07F4).portr("DSW4");
135 	map(0x2009, 0x2009).mirror(0x07F4).portr("DSW5");
136 	map(0x200a, 0x200a).mirror(0x07F4).portr("DSW6");
137 	map(0x200b, 0x200b).mirror(0x07F4).portr("DSW7");
138 	map(0x2800, 0x3fff).rom();
139 }
140 
141 static INPUT_PORTS_START( atari_s2 )
142 	PORT_START("DSW0")
143 	PORT_DIPNAME( 0x07, 0x05, "Max Credits" )
144 	PORT_DIPSETTING(    0x00, "5" )
145 	PORT_DIPSETTING(    0x01, "10" )
146 	PORT_DIPSETTING(    0x02, "15" )
147 	PORT_DIPSETTING(    0x03, "20" )
148 	PORT_DIPSETTING(    0x04, "25" )
149 	PORT_DIPSETTING(    0x05, "30" )
150 	PORT_DIPSETTING(    0x06, "35" )
151 	PORT_DIPSETTING(    0x07, "40" )
152 	PORT_DIPNAME( 0x08, 0x00, "Balls" )
153 	PORT_DIPSETTING(    0x08, "5" )
154 	PORT_DIPSETTING(    0x00, "3" )
155 	PORT_DIPNAME( 0x50, 0x00, "Special" )
156 	PORT_DIPSETTING(    0x10, "Extra Ball" )
157 	PORT_DIPSETTING(    0x00, "Free Game" )
158 	PORT_DIPSETTING(    0x40, "50000 points" )
159 	PORT_DIPSETTING(    0x50, "60000 points" )
160 	PORT_DIPNAME( 0x20, 0x00, "Free Play" )
DEF_STR(Off)161 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
162 	PORT_DIPSETTING(    0x20, DEF_STR( On ) )
163 	PORT_DIPNAME( 0x80, 0x00, "Match" )
164 	PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
165 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
166 
167 	PORT_START("DSW1")
168 	PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_UNUSED )
169 	PORT_DIPNAME( 0x10, 0x00, "Upper Lanes" )
170 	PORT_DIPSETTING(    0x10, "Start only" )
171 	PORT_DIPSETTING(    0x00, "Start and Advance" )
172 	PORT_DIPNAME( 0x60, 0x00, "Extra Ball reward" )
173 	PORT_DIPSETTING(    0x00, "Extra Ball" )
174 	PORT_DIPSETTING(    0x20, "20000 points" )
175 	PORT_DIPSETTING(    0x60, "30000 points" )
176 
177 	PORT_START("DSW2")
178 	PORT_DIPNAME( 0x1f, 0x02, "Coinage L Chute" )
179 	PORT_DIPSETTING(    0x02, DEF_STR( 1C_1C ) )
180 	PORT_DIPSETTING(    0x04, DEF_STR( 1C_2C ) )
181 	PORT_DIPSETTING(    0x06, DEF_STR( 1C_3C ) )
182 	PORT_DIPSETTING(    0x08, DEF_STR( 1C_4C ) )
183 	PORT_DIPSETTING(    0x0a, DEF_STR( 1C_5C ) )
184 	PORT_DIPSETTING(    0x0c, DEF_STR( 1C_6C ) )
185 	PORT_DIPSETTING(    0x0e, DEF_STR( 1C_7C ) )
186 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_8C ) )
187 	PORT_DIPSETTING(    0x10, DEF_STR( 1C_9C ) )
188 	PORT_DIPSETTING(    0x11, "1 coin/10 credits" )
189 	PORT_DIPSETTING(    0x12, "1 coin/11 credits" )
190 	PORT_DIPSETTING(    0x13, "1 coin/12 credits" )
191 	PORT_DIPSETTING(    0x14, "1 coin/13 credits" )
192 	PORT_DIPSETTING(    0x15, "1 coin/14 credits" )
193 	PORT_DIPSETTING(    0x16, "1 coin/15 credits" )
194 	PORT_DIPSETTING(    0x03, DEF_STR( 2C_3C ) )
195 	PORT_DIPSETTING(    0x05, DEF_STR( 2C_5C ) )
196 	PORT_DIPSETTING(    0x07, DEF_STR( 2C_7C ) )
197 	PORT_DIPSETTING(    0x09, "2 coins/9 credits" )
198 	PORT_DIPSETTING(    0x0b, "2 coins/11 credits" )
199 	PORT_DIPSETTING(    0x0d, "2 coins/13 credits" )
200 	PORT_DIPSETTING(    0x0f, "2 coins/15 credits" )
201 	PORT_DIPSETTING(    0x01, DEF_STR( 2C_1C ) )
202 	PORT_BIT( 0x40, 0x00, IPT_UNUSED )
203 	PORT_DIPNAME( 0x80, 0x00, "High Score Display" )
204 	PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
205 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
206 
207 	PORT_START("DSW3")
208 	PORT_DIPNAME( 0x1f, 0x02, "Coinage R Chute" )
209 	PORT_DIPSETTING(    0x02, DEF_STR( 1C_1C ) )
210 	PORT_DIPSETTING(    0x04, DEF_STR( 1C_2C ) )
211 	PORT_DIPSETTING(    0x06, DEF_STR( 1C_3C ) )
212 	PORT_DIPSETTING(    0x08, DEF_STR( 1C_4C ) )
213 	PORT_DIPSETTING(    0x0a, DEF_STR( 1C_5C ) )
214 	PORT_DIPSETTING(    0x0c, DEF_STR( 1C_6C ) )
215 	PORT_DIPSETTING(    0x0e, DEF_STR( 1C_7C ) )
216 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_8C ) )
217 	PORT_DIPSETTING(    0x10, DEF_STR( 1C_9C ) )
218 	PORT_DIPSETTING(    0x11, "1 coin/10 credits" )
219 	PORT_DIPSETTING(    0x12, "1 coin/11 credits" )
220 	PORT_DIPSETTING(    0x13, "1 coin/12 credits" )
221 	PORT_DIPSETTING(    0x14, "1 coin/13 credits" )
222 	PORT_DIPSETTING(    0x15, "1 coin/14 credits" )
223 	PORT_DIPSETTING(    0x16, "1 coin/15 credits" )
224 	PORT_DIPSETTING(    0x03, DEF_STR( 2C_3C ) )
225 	PORT_DIPSETTING(    0x05, DEF_STR( 2C_5C ) )
226 	PORT_DIPSETTING(    0x07, DEF_STR( 2C_7C ) )
227 	PORT_DIPSETTING(    0x09, "2 coins/9 credits" )
228 	PORT_DIPSETTING(    0x0b, "2 coins/11 credits" )
229 	PORT_DIPSETTING(    0x0d, "2 coins/13 credits" )
230 	PORT_DIPSETTING(    0x0f, "2 coins/15 credits" )
231 	PORT_DIPSETTING(    0x01, DEF_STR( 2C_1C ) )
232 	PORT_DIPNAME( 0x20, 0x00, "Ladder Memory" )
233 	PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
234 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
235 	PORT_DIPNAME( 0xc0, 0x00, "Replays for High Score" )
236 	PORT_DIPSETTING(    0xc0, "1" )
237 	PORT_DIPSETTING(    0x00, "2" )
238 	PORT_DIPSETTING(    0x80, "3" )
239 
240 	PORT_START("DSW4")
241 	PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
242 
243 	PORT_START("DSW5")
244 	PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
245 
246 	PORT_START("DSW6")
247 	PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
248 
249 	PORT_START("DSW7")
250 	PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
251 
252 	PORT_START("SWITCH.0") // 1000
253 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Test") PORT_CODE(KEYCODE_0)
254 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Outhole") PORT_CODE(KEYCODE_X)
255 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START )
256 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN2 )
257 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 )
258 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER )
259 	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
260 
261 	PORT_START("SWITCH.1") // 1001
262 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER )
263 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER )
264 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER )
265 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER )
266 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_Q)
267 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_W)
268 	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
269 
270 	PORT_START("SWITCH.2") // 1002
271 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER )
272 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER )
273 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_E)
274 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_R)
275 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_Y)
276 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_U)
277 	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
278 
279 	PORT_START("SWITCH.3") // 1003
280 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_I)
281 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_O)
282 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_A)
283 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER )
284 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_S)
285 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_D)
286 	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
287 
288 	PORT_START("SWITCH.4") // 1004
289 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_F)
290 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_G)
291 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER )
292 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_H)
293 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_J)
294 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_K)
295 	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
296 
297 	PORT_START("SWITCH.5") // 1005
298 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_L)
299 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER )
300 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER )
301 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER )
302 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER )
303 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER )
304 	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
305 
306 	PORT_START("SWITCH.6") // 1006
307 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_TILT )
308 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER )
309 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER )
310 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER )
311 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_Z)
312 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_C)
313 	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
314 
315 	PORT_START("SWITCH.7") // 1007
316 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_V)
317 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_B)
318 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER )
319 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER )
320 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER )
321 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER )
322 	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
323 INPUT_PORTS_END
324 
325 /* solenoids hercules
326    4,5 = bumpers
327    8,9 = slings
328     15 = outhole
329    6,7 = coin counters
330     14 = total plays counter
331 
332    solenoids superman
333    4,5,8,11 = bumpers
334    9,10     = slings
335         15  = outhole
336        6,7  = coin counters
337         12  = drop target
338         13  = drop hole kicker
339         14  = total plays counter
340 */
341 
342 void atari_s2_state::sol0_w(uint8_t data)
343 {
344 	switch (data)
345 	{
346 		case 15:
347 			m_samples->start(0, 5);
348 			break;
349 		case 4:
350 		case 5:
351 			m_samples->start(1, 0);
352 			break;
353 		case 8:
354 		case 9:
355 			//m_samples->start(1, 7);
356 			break;
357 		//default:
358 			//if (data) printf("%X ",data);
359 	}
360 }
361 
display_w(offs_t offset,uint8_t data)362 void atari_s2_state::display_w(offs_t offset, uint8_t data)
363 {
364 	static constexpr uint8_t patterns[16] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7c, 0x07, 0x7f, 0x67, 0, 0, 0, 0, 0, 0 }; // 4511
365 	if (offset < 7)
366 	{
367 		m_segment[offset] = patterns[data&15];
368 	}
369 	else
370 	{
371 		data &= 7;
372 		for (uint8_t i = 0; i < 7; i++)
373 			m_digits[i * 10 + data] = m_segment[i];
374 	}
375 }
376 
intack_w(uint8_t data)377 void atari_s2_state::intack_w(uint8_t data)
378 {
379 	m_maincpu->set_input_line(M6800_IRQ_LINE, CLEAR_LINE);
380 }
381 
382 // Sound
383 // 4 frequencies (500k,250k,125k,62.5k) come from main clock circuits
384 // We choose one of these with SEL A,B
385 // Then presettable 74LS161 binary divider controlled by m_sound0:d4-7
386 // Then a 74LS393 to generate 5 address lines
387 // The address lines are merged with m_sound0:d0-3 to form a lookup on the prom
388 // Output of prom goes to a 4-bit DAC
389 // Volume is controlled by m_sound1:d0-3
390 // Noise is a pair of 74LS164 shift registers, connected to form a pseudo-random pattern
391 // Variables:
392 // m_timer_s[0] inc each timer cycle, bit 0 = 500k, bit 1 = 250k, bit 2 = 125k, bit 3 = 62.5k
393 // m_timer_s[1] count in 74LS161
394 // m_timer_s[2] count in 74LS393
395 // m_timer_s[3] shift register of 74LS164 P4
396 // m_timer_s[4] shift register of 74LS164 N4
397 // m_timer_sb   wanted output of m_timer_s[0]
TIMER_DEVICE_CALLBACK_MEMBER(atari_s2_state::timer_s)398 TIMER_DEVICE_CALLBACK_MEMBER( atari_s2_state::timer_s )
399 {
400 	m_timer_s[0]++;
401 	bool cs = BIT(m_timer_s[0], (m_sound0 & 0x30) >> 4); // select which frequency to work with by using SEL A,B
402 	if (cs != m_timer_sb)
403 	{
404 		m_timer_sb = cs;
405 		m_timer_s[1]++;
406 		if (m_timer_s[1] > 15)
407 		{
408 			// wave
409 			m_timer_s[1] = m_sound1; // set to preset value
410 			m_timer_s[2]++;
411 			offs_t offs = (m_timer_s[2] & 31) | ((m_sound0 & 15) << 5);
412 			if (BIT(m_sound0, 6))
413 				m_dac->write(m_p_prom[offs]);
414 			// noise
415 			if (BIT(m_sound0, 7))
416 			{
417 				bool ab0 = BIT(m_timer_s[3], 0) ^ BIT(m_timer_s[4], 6);
418 				bool ab1 = !BIT(m_timer_s[3], 1);
419 				m_timer_s[3] = (m_timer_s[3] << 1) | ab0;
420 				m_timer_s[4] = (m_timer_s[4] << 1) | ab1;
421 				m_dac1->write(m_timer_s[4] & 7);
422 			}
423 			else
424 			{
425 				m_timer_s[3] = 0;
426 				m_timer_s[4] = 0;
427 			}
428 		}
429 	}
430 }
431 
432 // d0-3 = sound data to prom
433 // d4-5 = select initial clock frequency
434 // d6 h = enable wave
435 // d7 h = enable noise
sound0_w(uint8_t data)436 void atari_s2_state::sound0_w(uint8_t data)
437 {
438 	m_sound0 = data;
439 	offs_t offs = (m_timer_s[2] & 31) | ((m_sound0 & 15) << 5);
440 	if (BIT(m_sound0, 6))
441 		m_dac->write(m_p_prom[offs]);
442 }
443 
444 // d0-3 = volume
445 // d4-7 = preset on 74LS161
sound1_w(uint8_t data)446 void atari_s2_state::sound1_w(uint8_t data)
447 {
448 	m_sound1 = data >> 4;
449 
450 	data &= 15;
451 
452 	if (data != m_vol)
453 	{
454 		// 4066  + r65-r68 (68k,33k,18k,8.2k)
455 		m_vol = data;
456 		float vol = m_vol/16.666+0.1;
457 		m_dac->set_output_gain(0, vol);
458 		m_dac1->set_output_gain(0, vol);
459 	}
460 }
461 
TIMER_DEVICE_CALLBACK_MEMBER(atari_s2_state::irq)462 TIMER_DEVICE_CALLBACK_MEMBER( atari_s2_state::irq )
463 {
464 	if (m_t_c > 0x40)
465 		m_maincpu->set_input_line(M6800_IRQ_LINE, HOLD_LINE);
466 	else
467 		m_t_c++;
468 }
469 
machine_reset()470 void atari_s2_state::machine_reset()
471 {
472 	m_p_prom = memregion("proms")->base();
473 	m_vol = 0;
474 	m_dac->set_output_gain(0,0);
475 	m_dac1->set_output_gain(0,0);
476 	m_sound0 = 0;
477 	m_sound1 = 0;
478 }
479 
480 
atari_s2(machine_config & config)481 void atari_s2_state::atari_s2(machine_config &config)
482 {
483 	/* basic machine hardware */
484 	M6800(config, m_maincpu, XTAL(4'000'000) / 4);
485 	m_maincpu->set_addrmap(AS_PROGRAM, &atari_s2_state::atari_s2_map);
486 	NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
487 	WATCHDOG_TIMER(config, "watchdog");
488 
489 	/* Sound */
490 	genpin_audio(config);
491 	SPEAKER(config, "speaker").front_center();
492 
493 	DAC_4BIT_BINARY_WEIGHTED(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.15); // r23-r26 (68k,33k,18k,8.2k)
494 	DAC_3BIT_BINARY_WEIGHTED(config, m_dac1, 0).add_route(ALL_OUTPUTS, "speaker", 0.15); // r18-r20 (100k,47k,100k)
495 
496 	/* Video */
497 	config.set_default_layout(layout_atari_s2);
498 
499 	TIMER(config, "irq").configure_periodic(FUNC(atari_s2_state::irq), attotime::from_hz(XTAL(4'000'000) / 8192));
500 	TIMER(config, "timer_s").configure_periodic(FUNC(atari_s2_state::timer_s), attotime::from_hz(150000));
501 }
502 
atari_s3(machine_config & config)503 void atari_s2_state::atari_s3(machine_config &config)
504 {
505 	atari_s2(config);
506 	m_maincpu->set_addrmap(AS_PROGRAM, &atari_s2_state::atari_s3_map);
507 }
508 
509 
510 /*-------------------------------------------------------------------
511 / Superman (03/1979)
512 /-------------------------------------------------------------------*/
513 ROM_START(supermap)
514 	ROM_REGION(0x10000, "maincpu", 0)
515 	ROM_LOAD("supmn_k.rom", 0x2800, 0x0800, CRC(a28091c2) SHA1(9f5e47db408da96a31cb2f3be0fa9fb1e79f8d85))
516 	ROM_LOAD("atari_m.rom", 0x3000, 0x0800, CRC(1bb6b72c) SHA1(dd24ed54de275aadf8dc0810a6af3ac97aea4026))
517 	ROM_LOAD("atari_j.rom", 0x3800, 0x0800, CRC(26521779) SHA1(2cf1c66441aee99b9d01859d495c12025b5ef094))
518 
519 	ROM_REGION(0x0200, "proms", 0)
520 	ROM_LOAD("82s130.bin", 0x0000, 0x0200, CRC(da1f77b4) SHA1(b21fdc1c6f196c320ec5404013d672c35f95890b))
521 ROM_END
522 
523 /*-------------------------------------------------------------------
524 / Hercules (05/1979)
525 /-------------------------------------------------------------------*/
526 ROM_START(hercules)
527 	ROM_REGION(0x10000, "maincpu", 0)
528 	ROM_LOAD("herc_k.rom",  0x2800, 0x0800, CRC(65e099b1) SHA1(83a06bc82e0f8f4c0655886c6a9962bb28d00c5e))
529 	ROM_LOAD("atari_m.rom", 0x3000, 0x0800, CRC(1bb6b72c) SHA1(dd24ed54de275aadf8dc0810a6af3ac97aea4026))
530 	ROM_LOAD("atari_j.rom", 0x3800, 0x0800, CRC(26521779) SHA1(2cf1c66441aee99b9d01859d495c12025b5ef094))
531 
532 	ROM_REGION(0x0200, "proms", 0)
533 	ROM_LOAD("82s130.bin", 0x0000, 0x0200, CRC(da1f77b4) SHA1(b21fdc1c6f196c320ec5404013d672c35f95890b))
534 ROM_END
535 
536 /*-------------------------------------------------------------------
537 / Road Runner (??/1979)
538 /-------------------------------------------------------------------*/
539 ROM_START(roadrunr)
540 	ROM_REGION(0x10000, "maincpu", 0)
541 	ROM_LOAD("0000.716", 0x2800, 0x0800, CRC(62f5f394) SHA1(ff91066d43d788119e3337788abd86e5c0bf2d92))
542 	ROM_LOAD("3000.716", 0x3000, 0x0800, CRC(2fc01359) SHA1(d3df20c764bb68a5316367bb18d34a03293e7fa6))
543 	ROM_LOAD("3800.716", 0x3800, 0x0800, CRC(77262408) SHA1(3045a732c39c96002f495f64ed752279f7d43ee7))
544 
545 	ROM_REGION(0x0200, "proms", 0)
546 	ROM_LOAD("82s130.bin", 0x0000, 0x0200, CRC(da1f77b4) SHA1(b21fdc1c6f196c320ec5404013d672c35f95890b))
547 ROM_END
548 
549 /*-------------------------------------------------------------------
550 / 4x4 (10/1982)
551 /-------------------------------------------------------------------*/
552 ROM_START(fourx4)
553 	ROM_REGION(0x10000, "maincpu", 0)
554 	ROM_LOAD("8000ce65.bin", 0x8000, 0x2000, CRC(27341155) SHA1(c0da1fbf64f93ab163b2ea6bfbfc7b778cea819f)) \
555 	ROM_LOAD("a0004c37.bin", 0xa000, 0x2000, CRC(6f93102f) SHA1(d6520987ed5805b0e6b5da5653fc7cb063e86dda)) \
556 	ROM_LOAD("c000a70c.bin", 0xc000, 0x2000, CRC(c31ca8d3) SHA1(53f20eff0084771dc61d19db7ddae52e4423e75e)) \
557 	ROM_RELOAD(0xe000, 0x2000)
558 
559 	ROM_REGION(0x0200, "proms", 0)
560 	ROM_LOAD("82s130.bin", 0x0000, 0x0200, CRC(da1f77b4) SHA1(b21fdc1c6f196c320ec5404013d672c35f95890b))
561 ROM_END
562 
563 GAME( 1979, supermap, 0, atari_s2, atari_s2, atari_s2_state, empty_init, ROT0, "Atari", "Superman (Pinball)", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
564 GAME( 1979, hercules, 0, atari_s2, atari_s2, atari_s2_state, empty_init, ROT0, "Atari", "Hercules",           MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
565 GAME( 1979, roadrunr, 0, atari_s3, atari_s2, atari_s2_state, empty_init, ROT0, "Atari", "Road Runner",        MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
566 GAME( 1982, fourx4,   0, atari_s3, atari_s2, atari_s2_state, empty_init, ROT0, "Atari", "4x4",                MACHINE_IS_SKELETON_MECHANICAL)
567