1 // license:BSD-3-Clause
2 // copyright-holders:Hedley Rainnie, Aaron Giles, Couriersud, Paul Forgey
3 /***************************************************************************
4 
5     Atari Quantum hardware
6 
7     driver by Paul Forgey, with some help from Aaron Giles
8 
9     Games supported:
10         * Quantum
11 
12     Known bugs:
13         * none at this time
14 
15 NOTE: The Atari 136002-125 PROM in the sets below wasn't dumped from an actual
16       Quantum PCB. It is assumed all Atari 136002-125 PROMs are the same data.
17 
18 ****************************************************************************
19 
20     Memory map
21 
22 ****************************************************************************
23 
24     QUANTUM MEMORY MAP (per schem):
25 
26     000000-003FFF   ROM0
27     004000-004FFF   ROM1
28     008000-00BFFF   ROM2
29     00C000-00FFFF   ROM3
30     010000-013FFF   ROM4
31 
32     018000-01BFFF   RAM0
33     01C000-01CFFF   RAM1
34 
35     940000          TRACKBALL
36     948000          SWITCHES
37     950000          COLORRAM
38     958000          CONTROL (LED and coin control)
39     960000-970000   RECALL (nvram read)
40     968000          VGRST (vector reset)
41     970000          VGGO (vector go)
42     978000          WDCLR (watchdog)
43     900000          NVRAM (nvram write)
44     840000          I/OS (sound and dip switches)
45     800000-801FFF   VMEM (vector display list)
46     940000          I/O (shematic label really - covered above)
47     900000          DTACK1
48 
49 ***************************************************************************/
50 
51 #include "emu.h"
52 #include "cpu/m68000/m68000.h"
53 #include "video/vector.h"
54 #include "video/avgdvg.h"
55 #include "sound/pokey.h"
56 #include "sound/discrete.h"
57 #include "machine/watchdog.h"
58 #include "machine/x2212.h"
59 #include "screen.h"
60 #include "speaker.h"
61 
62 
63 class quantum_state : public driver_device
64 {
65 public:
quantum_state(const machine_config & mconfig,device_type type,const char * tag)66 	quantum_state(const machine_config &mconfig, device_type type, const char *tag) :
67 		driver_device(mconfig, type, tag),
68 		m_maincpu(*this, "maincpu"),
69 		m_avg(*this, "avg"),
70 		m_nvram(*this, "nvram"),
71 		m_leds(*this, "led%u", 0U)
72 	{ }
73 
74 	void quantum(machine_config &config);
75 
76 protected:
machine_start()77 	virtual void machine_start() override { m_leds.resolve(); }
78 
79 private:
80 	uint16_t trackball_r();
81 	void led_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
82 	void nvram_recall_w(uint16_t data);
83 	uint8_t input_1_r(offs_t offset);
84 	uint8_t input_2_r(offs_t offset);
85 	void main_map(address_map &map);
86 
87 	required_device<cpu_device> m_maincpu;
88 	required_device<avg_quantum_device> m_avg;
89 	required_device<x2212_device> m_nvram;
90 	output_finder<2> m_leds;
91 };
92 
93 
94 static constexpr XTAL MASTER_CLOCK = 12.096_MHz_XTAL;
95 static constexpr XTAL CLOCK_3KHZ   = MASTER_CLOCK / 4096;
96 
97 
98 /*************************************
99  *
100  *  Inputs
101  *
102  *************************************/
103 
trackball_r()104 uint16_t quantum_state::trackball_r()
105 {
106 	return (ioport("TRACKY")->read() << 4) | ioport("TRACKX")->read();
107 }
108 
109 
input_1_r(offs_t offset)110 uint8_t quantum_state::input_1_r(offs_t offset)
111 {
112 	return (ioport("DSW0")->read() << (7 - (offset - pokey_device::POT0_C))) & 0x80;
113 }
114 
115 
input_2_r(offs_t offset)116 uint8_t quantum_state::input_2_r(offs_t offset)
117 {
118 	return (ioport("DSW1")->read() << (7 - (offset - pokey_device::POT0_C))) & 0x80;
119 }
120 
121 
122 
123 /*************************************
124  *
125  *  LEDs/coin counters
126  *
127  *************************************/
128 
led_w(offs_t offset,uint16_t data,uint16_t mem_mask)129 void quantum_state::led_w(offs_t offset, uint16_t data, uint16_t mem_mask)
130 {
131 	if (ACCESSING_BITS_0_7)
132 	{
133 		/* bits 0 and 1 are coin counters */
134 		machine().bookkeeping().coin_counter_w(0, data & 2);
135 		machine().bookkeeping().coin_counter_w(1, data & 1);
136 
137 		m_nvram->store(BIT(data, 2));
138 
139 		/* bit 3 = select second trackball for cocktail mode? */
140 
141 		/* bits 4 and 5 are LED controls */
142 		m_leds[0] = BIT(data, 4);
143 		m_leds[1] = BIT(data, 5);
144 
145 		/* bits 6 and 7 flip screen */
146 		m_avg->set_flip_x(data & 0x40);
147 		m_avg->set_flip_y(data & 0x80);
148 	}
149 }
150 
nvram_recall_w(uint16_t data)151 void quantum_state::nvram_recall_w(uint16_t data)
152 {
153 	m_nvram->recall(1);
154 	m_nvram->recall(0);
155 }
156 
157 
158 
159 /*************************************
160  *
161  *  Main CPU memory handlers
162  *
163  *************************************/
164 
main_map(address_map & map)165 void quantum_state::main_map(address_map &map)
166 {
167 	map(0x000000, 0x013fff).rom();
168 	map(0x018000, 0x01cfff).ram();
169 	map(0x800000, 0x801fff).ram().share("avg:vectorram");
170 	map(0x840000, 0x84001f).rw("pokey1", FUNC(pokey_device::read), FUNC(pokey_device::write)).umask16(0x00ff);
171 	map(0x840020, 0x84003f).rw("pokey2", FUNC(pokey_device::read), FUNC(pokey_device::write)).umask16(0x00ff);
172 	map(0x900000, 0x9001ff).rw("nvram", FUNC(x2212_device::read), FUNC(x2212_device::write)).umask16(0x00ff);
173 	map(0x940000, 0x940001).r(FUNC(quantum_state::trackball_r)); /* trackball */
174 	map(0x948000, 0x948001).portr("SYSTEM");
175 	map(0x950000, 0x95001f).writeonly().share("avg:colorram");
176 	map(0x958000, 0x958001).w(FUNC(quantum_state::led_w));
177 	map(0x960000, 0x960001).w(FUNC(quantum_state::nvram_recall_w));
178 	map(0x968000, 0x968001).w(m_avg, FUNC(avg_quantum_device::reset_word_w));
179 	map(0x970000, 0x970001).w(m_avg, FUNC(avg_quantum_device::go_word_w));
180 	map(0x978000, 0x978001).nopr().w("watchdog", FUNC(watchdog_timer_device::reset16_w));
181 }
182 
183 
184 /*************************************
185  *
186  *  Port definitions
187  *
188  *************************************/
189 
190 static INPUT_PORTS_START( quantum )
191 	PORT_START("SYSTEM")
192 	/* YHALT here MUST BE ALWAYS 0  */
193 	PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("avg", avg_quantum_device, done_r) // vg YHALT
194 	PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_COIN3 )
195 	PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_START1 )
196 	PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_START2 )
197 	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_COIN2 )
198 	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_COIN1 )
199 	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
200 	PORT_SERVICE( 0x0080, IP_ACTIVE_LOW )
201 	PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
202 
203 	/* first POKEY is SW2, second is SW1 -- more confusion! */
204 	PORT_START("DSW0")
205 	PORT_DIPNAME( 0xc0, 0x00, DEF_STR( Coinage ) )
206 	PORT_DIPSETTING(    0x80, DEF_STR( 2C_1C ) )
207 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) )
208 	PORT_DIPSETTING(    0xc0, DEF_STR( 1C_2C ) )
209 	PORT_DIPSETTING(    0x40, DEF_STR( Free_Play ) )
210 	PORT_DIPNAME( 0x30, 0x00, "Right Coin" )
211 	PORT_DIPSETTING(    0x00, "*1" )
212 	PORT_DIPSETTING(    0x20, "*4" )
213 	PORT_DIPSETTING(    0x10, "*5" )
214 	PORT_DIPSETTING(    0x30, "*6" )
215 	PORT_DIPNAME( 0x08, 0x00, "Left Coin" )
216 	PORT_DIPSETTING(    0x00, "*1" )
217 	PORT_DIPSETTING(    0x08, "*2" )
218 	PORT_DIPNAME( 0x07, 0x00, "Bonus Coins" )
219 	PORT_DIPSETTING(    0x00, DEF_STR( None ) )
220 	PORT_DIPSETTING(    0x01, "1 each 5" )
221 	PORT_DIPSETTING(    0x02, "1 each 4" )
222 	PORT_DIPSETTING(    0x05, "1 each 3" )
223 	PORT_DIPSETTING(    0x06, "2 each 4" )
224 
225 	PORT_START("DSW1")
226 	PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNKNOWN )
227 
228 	PORT_START("TRACKX")
229 	PORT_BIT( 0x0f, 0, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(10) PORT_KEYDELTA(10) PORT_REVERSE
230 
231 	PORT_START("TRACKY")
232 	PORT_BIT( 0x0f, 0, IPT_TRACKBALL_X ) PORT_SENSITIVITY(10) PORT_KEYDELTA(10)
233 INPUT_PORTS_END
234 
235 
236 /*************************************
237  *
238  *  Discrete Sound Blocks
239  *
240  *************************************/
241 
242 static discrete_op_amp_filt_info pokey1_info = {
243 		RES_K(220), 0, 0, 0, /* r1 .. r4 */
244 		RES_K(220),          /* rF */
245 		CAP_U(0.022),        /* C1 */
246 		CAP_U(0.1),          /* C2 */
247 		0,                   /* C3 */
248 		0.0,                 /* vRef */
249 		15.0,                /* vP */
250 		-15.0,               /* vN */
251 };
252 
253 static discrete_mixer_desc quantum_mixer = {
254 		DISC_MIXER_IS_OP_AMP, /* type */
255 		{ RES_K(220), RES_K(220) }, /* r{} */
256 		{},                         /* r_node */
257 		{ CAP_U(0.1), CAP_U(0.1) }, /* c{} */
258 		0,                          /* rI  */
259 		RES_K(220),                 /* rF  */
260 		0,                          /* cF  */
261 		0,                          /* cAmp */
262 		0,                          /* vRef */
263 		1.0                         /* gain */
264 };
265 
266 static DISCRETE_SOUND_START(quantum_discrete)
267 
268 	/************************************************/
269 	/* FINAL MIX                                    */
270 	/************************************************/
271 
272 	/* Convert Pokey output to 5V Signal */
273 	DISCRETE_INPUTX_STREAM(NODE_100, 0, 5.0 / 32768, 5.0)   /* Add VRef again */
274 	DISCRETE_INPUTX_STREAM(NODE_110, 1, 5.0 / 32768, 5.0)   /* Add VRef again */
275 
276 	DISCRETE_OP_AMP_FILTER(NODE_150, 1, NODE_100, 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1, &pokey1_info)
277 
278 	DISCRETE_MIXER2(NODE_290, 1, NODE_150, NODE_110, &quantum_mixer)
279 	DISCRETE_OUTPUT(NODE_290, 8192)
280 
281 DISCRETE_SOUND_END
282 
283 
284 /*************************************
285  *
286  *  Machine driver
287  *
288  *************************************/
289 
quantum(machine_config & config)290 void quantum_state::quantum(machine_config &config)
291 {
292 	/* basic machine hardware */
293 	M68000(config, m_maincpu, MASTER_CLOCK / 2);
294 	m_maincpu->set_addrmap(AS_PROGRAM, &quantum_state::main_map);
295 	m_maincpu->set_periodic_int(FUNC(quantum_state::irq1_line_hold), attotime::from_hz(CLOCK_3KHZ / 12));
296 
297 	X2212(config, "nvram"); // "137288-001" in parts list and schematic diagram
298 
299 	WATCHDOG_TIMER(config, "watchdog");
300 
301 	/* video hardware */
302 	VECTOR(config, "vector");
303 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_VECTOR));
304 	screen.set_refresh_hz(60);
305 	screen.set_size(400, 300);
306 	screen.set_visarea(0, 900, 0, 600);
307 	screen.set_screen_update("vector", FUNC(vector_device::screen_update));
308 
309 	AVG_QUANTUM(config, m_avg, 0);
310 	m_avg->set_vector_tag("vector");
311 
312 	/* sound hardware */
313 	SPEAKER(config, "mono").front_center();
314 
315 	pokey_device &pokey1(POKEY(config, "pokey1", 600000));
316 	pokey1.pot_r<0>().set(FUNC(quantum_state::input_1_r));
317 	pokey1.pot_r<1>().set(FUNC(quantum_state::input_1_r));
318 	pokey1.pot_r<2>().set(FUNC(quantum_state::input_1_r));
319 	pokey1.pot_r<3>().set(FUNC(quantum_state::input_1_r));
320 	pokey1.pot_r<4>().set(FUNC(quantum_state::input_1_r));
321 	pokey1.pot_r<5>().set(FUNC(quantum_state::input_1_r));
322 	pokey1.pot_r<6>().set(FUNC(quantum_state::input_1_r));
323 	pokey1.pot_r<7>().set(FUNC(quantum_state::input_1_r));
324 	pokey1.set_output_opamp(RES_K(1), 0.0, 5.0);
325 	pokey1.add_route(0, "discrete", 1.0, 0);
326 
327 	pokey_device &pokey2(POKEY(config, "pokey2", 600000));
328 	pokey2.pot_r<0>().set(FUNC(quantum_state::input_2_r));
329 	pokey2.pot_r<1>().set(FUNC(quantum_state::input_2_r));
330 	pokey2.pot_r<2>().set(FUNC(quantum_state::input_2_r));
331 	pokey2.pot_r<3>().set(FUNC(quantum_state::input_2_r));
332 	pokey2.pot_r<4>().set(FUNC(quantum_state::input_2_r));
333 	pokey2.pot_r<5>().set(FUNC(quantum_state::input_2_r));
334 	pokey2.pot_r<6>().set(FUNC(quantum_state::input_2_r));
335 	pokey2.pot_r<7>().set(FUNC(quantum_state::input_2_r));
336 	pokey2.set_output_opamp(RES_K(1), 0.0, 5.0);
337 	pokey2.add_route(0, "discrete", 1.0, 1);
338 
339 	DISCRETE(config, "discrete", quantum_discrete).add_route(ALL_OUTPUTS, "mono", 0.50);
340 }
341 
342 
343 
344 /*************************************
345  *
346  *  ROM definition(s)
347  *
348  *************************************/
349 
350 ROM_START( quantum )
351 	ROM_REGION( 0x014000, "maincpu", 0 )
352 	ROM_LOAD16_BYTE( "136016.201",   0x000000, 0x002000, CRC(7e7be63a) SHA1(11b2d0168cdbaa7a48656b77abc0bcbe9408fe84) )
353 	ROM_LOAD16_BYTE( "136016.206",   0x000001, 0x002000, CRC(2d8f5759) SHA1(54b0388ef44b5d34e621b48b465566aa16887e8f) )
354 	ROM_LOAD16_BYTE( "136016.102",   0x004000, 0x002000, CRC(408d34f4) SHA1(9a30debd1240b9c103134701943c94d6b48b926d) )
355 	ROM_LOAD16_BYTE( "136016.107",   0x004001, 0x002000, CRC(63154484) SHA1(c098cdbc339c9ea291c4c4fb203c60b3284e894a) )
356 	ROM_LOAD16_BYTE( "136016.203",   0x008000, 0x002000, CRC(bdc52fad) SHA1(c8ede54a4f7f555adffa5b4bfea6bf646a0d02d4) )
357 	ROM_LOAD16_BYTE( "136016.208",   0x008001, 0x002000, CRC(dab4066b) SHA1(dbb82df8e6de4e0f9f6e7ddd5f07618864fce8f9) )
358 	ROM_LOAD16_BYTE( "136016.104",   0x00C000, 0x002000, CRC(bf271e5c) SHA1(012edb947f1437932b9283e49d025a7794c45669) )
359 	ROM_LOAD16_BYTE( "136016.109",   0x00C001, 0x002000, CRC(d2894424) SHA1(5390025136b677b66d948c8cf6ea5e20203a4bae) )
360 	ROM_LOAD16_BYTE( "136016.105",   0x010000, 0x002000, CRC(13ec512c) SHA1(22a0395135b83ba47eacb5129f34fc97aa1b70a1) )
361 	ROM_LOAD16_BYTE( "136016.110",   0x010001, 0x002000, CRC(acb50363) SHA1(9efa9ca88efdd2d5e212bd537903892b67b4fe53) )
362 	/* AVG PROM */
363 	ROM_REGION( 0x100, "avg:prom", 0 )
364 	ROM_LOAD( "136002-125.6h",   0x0000, 0x0100, CRC(5903af03) SHA1(24bc0366f394ad0ec486919212e38be0f08d0239) )
365 
366 	ROM_REGION( 0x200, "plds", 0 )
367 	ROM_LOAD( "cf2038n.1b",   0x0000, 0x00eb, CRC(b372fa4f) SHA1(a60b51849e9f691b412ae4c4afc834ff93d8a30f) ) /* Original chip is a 82S153, schematics refer to this chip as 137290-001 */
368 ROM_END
369 
370 
371 ROM_START( quantum1 )
372 	ROM_REGION( 0x014000, "maincpu", 0 )
373 	ROM_LOAD16_BYTE( "136016.101",   0x000000, 0x002000, CRC(5af0bd5b) SHA1(f6e46fbebbf52294e78ae240fe2628c6b29b8dea) )
374 	ROM_LOAD16_BYTE( "136016.106",   0x000001, 0x002000, CRC(f9724666) SHA1(1bb073135029c92bef9afc9ccd910e0ab3302c8a) )
375 	ROM_LOAD16_BYTE( "136016.102",   0x004000, 0x002000, CRC(408d34f4) SHA1(9a30debd1240b9c103134701943c94d6b48b926d) )
376 	ROM_LOAD16_BYTE( "136016.107",   0x004001, 0x002000, CRC(63154484) SHA1(c098cdbc339c9ea291c4c4fb203c60b3284e894a) )
377 	ROM_LOAD16_BYTE( "136016.103",   0x008000, 0x002000, CRC(948f228b) SHA1(878ac96173a793997cc88be469ec1ccdf833a7e8) )
378 	ROM_LOAD16_BYTE( "136016.108",   0x008001, 0x002000, CRC(e4c48e4e) SHA1(caaf9d20741fcb961d590b634250a44a166cc33a) )
379 	ROM_LOAD16_BYTE( "136016.104",   0x00C000, 0x002000, CRC(bf271e5c) SHA1(012edb947f1437932b9283e49d025a7794c45669) )
380 	ROM_LOAD16_BYTE( "136016.109",   0x00C001, 0x002000, CRC(d2894424) SHA1(5390025136b677b66d948c8cf6ea5e20203a4bae) )
381 	ROM_LOAD16_BYTE( "136016.105",   0x010000, 0x002000, CRC(13ec512c) SHA1(22a0395135b83ba47eacb5129f34fc97aa1b70a1) )
382 	ROM_LOAD16_BYTE( "136016.110",   0x010001, 0x002000, CRC(acb50363) SHA1(9efa9ca88efdd2d5e212bd537903892b67b4fe53) )
383 	/* AVG PROM */
384 	ROM_REGION( 0x100, "avg:prom", 0 )
385 	ROM_LOAD( "136002-125.6h",   0x0000, 0x0100, CRC(5903af03) SHA1(24bc0366f394ad0ec486919212e38be0f08d0239) )
386 
387 	ROM_REGION( 0x200, "plds", 0 )
388 	ROM_LOAD( "cf2038n.1b",   0x0000, 0x00eb, CRC(b372fa4f) SHA1(a60b51849e9f691b412ae4c4afc834ff93d8a30f) ) /* Original chip is a 82S153, schematics refer to this chip as 137290-001 */
389 ROM_END
390 
391 
392 ROM_START( quantump )
393 	ROM_REGION( 0x014000, "maincpu", 0 )
394 	ROM_LOAD16_BYTE( "quantump.2e",  0x000000, 0x002000, CRC(176d73d3) SHA1(b887ee50af5db6f6d43cc6ba57451173f996dedc) )
395 	ROM_LOAD16_BYTE( "quantump.3e",  0x000001, 0x002000, CRC(12fc631f) SHA1(327a44da897199536f43e5f792cb4a18d9055ac4) )
396 	ROM_LOAD16_BYTE( "quantump.2f",  0x004000, 0x002000, CRC(b64fab48) SHA1(d5a77a367d4f652261c381e6bdd55c2175ace857) )
397 	ROM_LOAD16_BYTE( "quantump.3f",  0x004001, 0x002000, CRC(a52a9433) SHA1(33787adb04864efebb04483353bbc96c966ec607) )
398 	ROM_LOAD16_BYTE( "quantump.2h",  0x008000, 0x002000, CRC(5b29cba3) SHA1(e83b68907bc397994ed51a39dfa241430a0adb0c) )
399 	ROM_LOAD16_BYTE( "quantump.3h",  0x008001, 0x002000, CRC(c64fc03a) SHA1(ab6cd710d01bc85432cc52021f27fd8f2a5e3168) )
400 	ROM_LOAD16_BYTE( "quantump.2k",  0x00C000, 0x002000, CRC(854f9c09) SHA1(d908b8c7f6837e511004cbd45a8883c6c7b155dd) )
401 	ROM_LOAD16_BYTE( "quantump.3k",  0x00C001, 0x002000, CRC(1aac576c) SHA1(28bdb5fcbd8cccc657d6e00ace3c083c21015564) )
402 	ROM_LOAD16_BYTE( "quantump.2l",  0x010000, 0x002000, CRC(1285b5e7) SHA1(0e01e361da2d9cf1fac1896f8f44c4c2e75a3061) )
403 	ROM_LOAD16_BYTE( "quantump.3l",  0x010001, 0x002000, CRC(e19de844) SHA1(cb4f9d80807b26d6b95405b2d830799984667f54) )
404 	/* AVG PROM */
405 	ROM_REGION( 0x100, "avg:prom", 0 )
406 	ROM_LOAD( "136002-125.6h",   0x0000, 0x0100, CRC(5903af03) SHA1(24bc0366f394ad0ec486919212e38be0f08d0239) )
407 
408 	ROM_REGION( 0x200, "plds", 0 )
409 	ROM_LOAD( "cf2038n.1b",   0x0000, 0x00eb, CRC(b372fa4f) SHA1(a60b51849e9f691b412ae4c4afc834ff93d8a30f) ) /* Original chip is a 82S153, schematics refer to this chip as 137290-001 */
410 ROM_END
411 
412 
413 
414 /*************************************
415  *
416  *  Game driver(s)
417  *
418  *************************************/
419 
420 GAME( 1982, quantum,  0,       quantum, quantum, quantum_state, empty_init, ROT270, "General Computer Corporation (Atari license)", "Quantum (rev 2)", MACHINE_SUPPORTS_SAVE )
421 GAME( 1982, quantum1, quantum, quantum, quantum, quantum_state, empty_init, ROT270, "General Computer Corporation (Atari license)", "Quantum (rev 1)", MACHINE_SUPPORTS_SAVE )
422 GAME( 1982, quantump, quantum, quantum, quantum, quantum_state, empty_init, ROT270, "General Computer Corporation (Atari license)", "Quantum (prototype)", MACHINE_SUPPORTS_SAVE )
423