1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4 
5     Commodore 2040/3040/4040 Disk Drive emulation
6 
7 **********************************************************************/
8 
9 /*
10 
11     2040/3040 disk initialization
12     -----------------------------
13     You need to initialize each diskette before trying to access it
14     or you will get a DISK ID MISMATCH error upon disk commands.
15     On the 4040 this is done automatically by the DOS.
16 
17     open 15,8,15:print 15,"i":close 15
18 
19     List directory
20     --------------
21     directory / diR
22 
23     Format disk
24     -----------
25     header "label,id",d0,i01
26 
27     Load file
28     ---------
29     dload "name" / dL"name
30 
31     Save file
32     ---------
33     dsave "name" / dS"name
34 
35 */
36 
37 /*
38 
39     TODO:
40 
41     - 2040/3040/4040 have a Shugart SA390 drive (FLOPPY_525_SSSD_35T)
42 
43     - 2040 DOS 1 FDC rom (jumps to 104d while getting block header)
44 
45         FE70: jsr  $104D
46         104D: m6502_brk#$00
47 
48 */
49 
50 #include "emu.h"
51 #include "c2040.h"
52 
53 
54 
55 //**************************************************************************
56 //  MACROS / CONSTANTS
57 //**************************************************************************
58 
59 #define M6502_TAG       "un1"
60 #define M6532_0_TAG     "uc1"
61 #define M6532_1_TAG     "ue1"
62 #define M6504_TAG       "uh3"
63 #define M6522_TAG       "um3"
64 #define M6530_TAG       "uk3"
65 #define FDC_TAG         "fdc"
66 
67 
68 
69 //**************************************************************************
70 //  DEVICE DEFINITIONS
71 //**************************************************************************
72 
73 DEFINE_DEVICE_TYPE(C2040, c2040_device, "c2040", "Commodore 2040")
74 DEFINE_DEVICE_TYPE(C3040, c3040_device, "c3040", "Commodore 3040")
75 DEFINE_DEVICE_TYPE(C4040, c4040_device, "c4040", "Commodore 4040")
76 
77 
78 //-------------------------------------------------
79 //  ROM( c2040 )
80 //-------------------------------------------------
81 
ROM_START(c2040)82 ROM_START( c2040 ) // schematic 320806, DOS 1.0
83 	ROM_REGION( 0x3000, M6502_TAG, 0 )
84 	ROM_LOAD( "901468-xx.ul1", 0x1000, 0x1000, NO_DUMP )
85 	ROM_LOAD( "901468-xx.uh1", 0x2000, 0x1000, NO_DUMP )
86 
87 	ROM_REGION( 0x400, M6504_TAG, 0 )
88 	ROM_LOAD( "901466-01.uk3", 0x000, 0x400, CRC(9d1e25ce) SHA1(d539858f839f96393f218307df7394362a84a26a) )
89 
90 	ROM_REGION( 0x800, "gcr", 0)
91 	ROM_LOAD( "901467.uk6",    0x000, 0x800, CRC(a23337eb) SHA1(97df576397608455616331f8e837cb3404363fa2) )
92 ROM_END
93 
94 
95 //-------------------------------------------------
96 //  rom_region - device-specific ROM region
97 //-------------------------------------------------
98 
99 const tiny_rom_entry *c2040_device::device_rom_region() const
100 {
101 	return ROM_NAME( c2040 );
102 }
103 
104 
105 //-------------------------------------------------
106 //  ROM( c3040 )
107 //-------------------------------------------------
108 
109 ROM_START( c3040 ) // schematic 320806, DOS 1.2
110 	ROM_REGION( 0x3000, M6502_TAG, 0 )
111 	ROM_LOAD( "901468-06.ul1", 0x1000, 0x1000, CRC(25b5eed5) SHA1(4d9658f2e6ff3276e5c6e224611a66ce44b16fc7) )
112 	ROM_LOAD( "901468-07.uh1", 0x2000, 0x1000, CRC(9b09ae83) SHA1(6a51c7954938439ca8342fc295bda050c06e1791) )
113 
114 	ROM_REGION( 0x400, M6504_TAG, 0 )
115 	ROM_LOAD( "901466-02.uk3", 0x000, 0x400, CRC(9d1e25ce) SHA1(d539858f839f96393f218307df7394362a84a26a) )
116 
117 	ROM_REGION( 0x800, "gcr", 0)
CRC(a23337eb)118 	ROM_LOAD( "901467.uk6",    0x000, 0x800, CRC(a23337eb) SHA1(97df576397608455616331f8e837cb3404363fa2) )
119 ROM_END
120 
121 
122 //-------------------------------------------------
123 //  rom_region - device-specific ROM region
124 //-------------------------------------------------
125 
126 const tiny_rom_entry *c3040_device::device_rom_region() const
127 {
128 	return ROM_NAME( c3040 );
129 }
130 
131 
132 //-------------------------------------------------
133 //  ROM( c4040 )
134 //-------------------------------------------------
135 
136 ROM_START( c4040 ) // schematic ?
137 	ROM_REGION( 0x3000, M6502_TAG, 0 )
138 	ROM_DEFAULT_BIOS("dos20r2")
139 	ROM_SYSTEM_BIOS( 0, "dos20r1", "DOS 2.0 Revision 1" )
CRC(b7157458)140 	ROMX_LOAD( "901468-11.uj1", 0x0000, 0x1000, CRC(b7157458) SHA1(8415f3159dea73161e0cef7960afa6c76953b6f8), ROM_BIOS(0) )
141 	ROMX_LOAD( "901468-12.ul1", 0x1000, 0x1000, CRC(02c44ff9) SHA1(e8a94f239082d45f64f01b2d8e488d18fe659cbb), ROM_BIOS(0) )
142 	ROMX_LOAD( "901468-13.uh1", 0x2000, 0x1000, CRC(cbd785b3) SHA1(6ada7904ac9d13c3f1c0a8715f9c4be1aa6eb0bb), ROM_BIOS(0) )
143 	ROM_SYSTEM_BIOS( 1, "dos20r2", "DOS 2.0 Revision 2" )
144 	ROMX_LOAD( "901468-14.uj1", 0x0000, 0x1000, CRC(bc4d4872) SHA1(ffb992b82ec913ddff7be964d7527aca3e21580c), ROM_BIOS(1) )
145 	ROMX_LOAD( "901468-15.ul1", 0x1000, 0x1000, CRC(b6970533) SHA1(f702d6917fe8a798740ba4d467b500944ae7b70a), ROM_BIOS(1) )
146 	ROMX_LOAD( "901468-16.uh1", 0x2000, 0x1000, CRC(1f5eefb7) SHA1(04b918cf4adeee8015b43383d3cea7288a7d0aa8), ROM_BIOS(1) )
147 
148 	ROM_REGION( 0x400, M6504_TAG, 0 )
149 	// RIOT DOS 2
150 	ROM_LOAD( "901466-04.uk3", 0x000, 0x400, CRC(0ab338dc) SHA1(6645fa40b81be1ff7d1384e9b52df06a26ab0bfb) )
151 
152 	ROM_REGION( 0x800, "gcr", 0)
153 	ROM_LOAD( "901467.uk6",    0x000, 0x800, CRC(a23337eb) SHA1(97df576397608455616331f8e837cb3404363fa2) )
154 ROM_END
155 
156 
157 //-------------------------------------------------
158 //  rom_region - device-specific ROM region
159 //-------------------------------------------------
160 
161 const tiny_rom_entry *c4040_device::device_rom_region() const
162 {
163 	return ROM_NAME( c4040 );
164 }
165 
166 
167 //-------------------------------------------------
168 //  ADDRESS_MAP( c2040_main_mem )
169 //-------------------------------------------------
170 
c2040_main_mem(address_map & map)171 void c2040_device::c2040_main_mem(address_map &map)
172 {
173 	map.global_mask(0x7fff);
174 	map(0x0000, 0x007f).mirror(0x0100).m(M6532_0_TAG, FUNC(mos6532_new_device::ram_map));
175 	map(0x0080, 0x00ff).mirror(0x0100).m(M6532_1_TAG, FUNC(mos6532_new_device::ram_map));
176 	map(0x0200, 0x021f).mirror(0x0d60).m(M6532_0_TAG, FUNC(mos6532_new_device::io_map));
177 	map(0x0280, 0x029f).mirror(0x0d60).m(M6532_1_TAG, FUNC(mos6532_new_device::io_map));
178 	map(0x1000, 0x13ff).mirror(0x0c00).ram().share("share1");
179 	map(0x2000, 0x23ff).mirror(0x0c00).ram().share("share2");
180 	map(0x3000, 0x33ff).mirror(0x0c00).ram().share("share3");
181 	map(0x4000, 0x43ff).mirror(0x0c00).ram().share("share4");
182 	map(0x5000, 0x7fff).rom().region(M6502_TAG, 0);
183 }
184 
185 
186 //-------------------------------------------------
187 //  ADDRESS_MAP( c2040_fdc_mem )
188 //-------------------------------------------------
189 
c2040_fdc_mem(address_map & map)190 void c2040_device::c2040_fdc_mem(address_map &map)
191 {
192 	map.global_mask(0x1fff);
193 	map(0x0000, 0x003f).mirror(0x0300).m(M6530_TAG, FUNC(mos6530_new_device::ram_map));
194 	map(0x0040, 0x004f).mirror(0x0330).m(M6522_TAG, FUNC(via6522_device::map));
195 	map(0x0080, 0x008f).mirror(0x0330).m(M6530_TAG, FUNC(mos6530_new_device::io_map));
196 	map(0x0400, 0x07ff).ram().share("share1");
197 	map(0x0800, 0x0bff).ram().share("share2");
198 	map(0x0c00, 0x0fff).ram().share("share3");
199 	map(0x1000, 0x13ff).ram().share("share4");
200 	map(0x1c00, 0x1fff).rom().region(M6504_TAG, 0);
201 }
202 
203 
204 //-------------------------------------------------
205 //  riot6532 uc1
206 //-------------------------------------------------
207 
dio_r()208 uint8_t c2040_device::dio_r()
209 {
210 	/*
211 
212 	    bit     description
213 
214 	    PA0     DI0
215 	    PA1     DI1
216 	    PA2     DI2
217 	    PA3     DI3
218 	    PA4     DI4
219 	    PA5     DI5
220 	    PA6     DI6
221 	    PA7     DI7
222 
223 	*/
224 
225 	return m_bus->dio_r();
226 }
227 
dio_w(uint8_t data)228 void c2040_device::dio_w(uint8_t data)
229 {
230 	/*
231 
232 	    bit     description
233 
234 	    PB0     DO0
235 	    PB1     DO1
236 	    PB2     DO2
237 	    PB3     DO3
238 	    PB4     DO4
239 	    PB5     DO5
240 	    PB6     DO6
241 	    PB7     DO7
242 
243 	*/
244 
245 	m_bus->dio_w(this, data);
246 }
247 
248 
249 //-------------------------------------------------
250 //  riot6532 ue1
251 //-------------------------------------------------
252 
riot1_pa_r()253 uint8_t c2040_device::riot1_pa_r()
254 {
255 	/*
256 
257 	    bit     description
258 
259 	    PA0     ATNA
260 	    PA1     DACO
261 	    PA2     RFDO
262 	    PA3     EOIO
263 	    PA4     DAVO
264 	    PA5     EOII
265 	    PA6     DAVI
266 	    PA7     _ATN
267 
268 	*/
269 
270 	uint8_t data = 0;
271 
272 	// end or identify in
273 	data |= m_bus->eoi_r() << 5;
274 
275 	// data valid in
276 	data |= m_bus->dav_r() << 6;
277 
278 	// attention
279 	data |= !m_bus->atn_r() << 7;
280 
281 	return data;
282 }
283 
riot1_pa_w(uint8_t data)284 void c2040_device::riot1_pa_w(uint8_t data)
285 {
286 	/*
287 
288 	    bit     description
289 
290 	    PA0     ATNA
291 	    PA1     DACO
292 	    PA2     RFDO
293 	    PA3     EOIO
294 	    PA4     DAVO
295 	    PA5     EOII
296 	    PA6     DAVI
297 	    PA7     _ATN
298 
299 	*/
300 
301 	// attention acknowledge
302 	m_atna = BIT(data, 0);
303 
304 	// data accepted out
305 	m_daco = BIT(data, 1);
306 
307 	// not ready for data out
308 	m_rfdo = BIT(data, 2);
309 
310 	// end or identify out
311 	m_bus->eoi_w(this, BIT(data, 3));
312 
313 	// data valid out
314 	m_bus->dav_w(this, BIT(data, 4));
315 
316 	update_ieee_signals();
317 }
318 
riot1_pb_r()319 uint8_t c2040_device::riot1_pb_r()
320 {
321 	/*
322 
323 	    bit     description
324 
325 	    PB0     DEVICE NUMBER SELECTION
326 	    PB1     DEVICE NUMBER SELECTION
327 	    PB2     DEVICE NUMBER SELECTION
328 	    PB3
329 	    PB4
330 	    PB5
331 	    PB6     DACI
332 	    PB7     RFDI
333 
334 	*/
335 
336 	uint8_t data = 0;
337 
338 	// device number selection
339 	data |= m_slot->get_address() - 8;
340 
341 	// data accepted in
342 	data |= m_bus->ndac_r() << 6;
343 
344 	// ready for data in
345 	data |= m_bus->nrfd_r() << 7;
346 
347 	return data;
348 }
349 
riot1_pb_w(uint8_t data)350 void c2040_device::riot1_pb_w(uint8_t data)
351 {
352 	/*
353 
354 	    bit     description
355 
356 	    PB0
357 	    PB1
358 	    PB2
359 	    PB3     ACT LED 1
360 	    PB4     ACT LED 0
361 	    PB5     ERR LED
362 	    PB6
363 	    PB7
364 
365 	*/
366 
367 	// activity led 1
368 	m_leds[LED_ACT1] = BIT(data, 3);
369 
370 	// activity led 0
371 	m_leds[LED_ACT0] = BIT(data, 4);
372 
373 	// error led
374 	m_leds[LED_ERR] = BIT(data, 5);
375 }
376 
377 
via_pb_w(uint8_t data)378 void c2040_device::via_pb_w(uint8_t data)
379 {
380 	/*
381 
382 	    bit     description
383 
384 	    PB0     S1A
385 	    PB1     S1B
386 	    PB2     S0A
387 	    PB3     S0B
388 	    PB4     MTR1
389 	    PB5     MTR0
390 	    PB6
391 	    PB7
392 
393 	*/
394 
395 	// spindle motor 1
396 	m_fdc->mtr1_w(BIT(data, 4));
397 
398 	// spindle motor 0
399 	m_fdc->mtr0_w(BIT(data, 5));
400 
401 	// stepper motor 1
402 	m_fdc->stp1_w(data & 0x03);
403 
404 	// stepper motor 0
405 	m_fdc->stp0_w((data >> 2) & 0x03);
406 }
407 
408 
409 //-------------------------------------------------
410 //  SLOT_INTERFACE( c2040_floppies )
411 //-------------------------------------------------
412 
c2040_floppies(device_slot_interface & device)413 static void c2040_floppies(device_slot_interface &device)
414 {
415 	device.option_add("525ssqd", FLOPPY_525_SSQD);
416 }
417 
418 
419 //-------------------------------------------------
420 //  FLOPPY_FORMATS( floppy_formats )
421 //-------------------------------------------------
422 
FLOPPY_FORMATS_MEMBER(c2040_device::floppy_formats)423 FLOPPY_FORMATS_MEMBER( c2040_device::floppy_formats )
424 	FLOPPY_C3040_FORMAT,
425 	FLOPPY_G64_FORMAT
426 FLOPPY_FORMATS_END
427 
428 
429 //-------------------------------------------------
430 //  FLOPPY_FORMATS( floppy_formats )
431 //-------------------------------------------------
432 
433 FLOPPY_FORMATS_MEMBER( c3040_device::floppy_formats )
434 	FLOPPY_C3040_FORMAT,
435 	FLOPPY_G64_FORMAT
436 FLOPPY_FORMATS_END
437 
438 
439 //-------------------------------------------------
440 //  FLOPPY_FORMATS( floppy_formats )
441 //-------------------------------------------------
442 
443 FLOPPY_FORMATS_MEMBER( c4040_device::floppy_formats )
444 	FLOPPY_C4040_FORMAT,
445 	FLOPPY_G64_FORMAT
446 FLOPPY_FORMATS_END
447 
448 
449 //-------------------------------------------------
450 //  device_add_mconfig - add device configuration
451 //-------------------------------------------------
452 
453 void c2040_device::add_common_devices(machine_config &config)
454 {
455 	// DOS
456 	M6502(config, m_maincpu, XTAL(16'000'000)/16);
457 	m_maincpu->set_addrmap(AS_PROGRAM, &c2040_device::c2040_main_mem);
458 
459 	MOS6532_NEW(config, m_riot0, XTAL(16'000'000)/16);
460 	m_riot0->pa_rd_callback().set(FUNC(c2040_device::dio_r));
461 	m_riot0->pb_wr_callback().set(FUNC(c2040_device::dio_w));
462 
463 	MOS6532_NEW(config, m_riot1, XTAL(16'000'000)/16);
464 	m_riot1->pa_rd_callback().set(FUNC(c2040_device::riot1_pa_r));
465 	m_riot1->pa_wr_callback().set(FUNC(c2040_device::riot1_pa_w));
466 	m_riot1->pb_rd_callback().set(FUNC(c2040_device::riot1_pb_r));
467 	m_riot1->pb_wr_callback().set(FUNC(c2040_device::riot1_pb_w));
468 	m_riot1->irq_wr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
469 
470 	// controller
471 	M6504(config, m_fdccpu, XTAL(16'000'000)/16);
472 	m_fdccpu->set_addrmap(AS_PROGRAM, &c2040_device::c2040_fdc_mem);
473 
474 	VIA6522(config, m_via, XTAL(16'000'000)/16);
475 	m_via->readpa_handler().set(m_fdc, FUNC(c2040_fdc_device::read));
476 	m_via->writepb_handler().set(FUNC(c2040_device::via_pb_w));
477 	m_via->ca2_handler().set(m_fdc, FUNC(c2040_fdc_device::mode_sel_w));
478 	m_via->cb2_handler().set(m_fdc, FUNC(c2040_fdc_device::rw_sel_w));
479 
480 	MOS6530_NEW(config, m_miot, XTAL(16'000'000)/16);
481 	m_miot->pa_wr_callback().set(m_fdc, FUNC(c2040_fdc_device::write));
482 	m_miot->pb_wr_callback<0>().set(m_fdc, FUNC(c2040_fdc_device::drv_sel_w));
483 	m_miot->pb_wr_callback<1>().set(m_fdc, FUNC(c2040_fdc_device::ds0_w));
484 	m_miot->pb_wr_callback<2>().set(m_fdc, FUNC(c2040_fdc_device::ds1_w));
485 	m_miot->pb_wr_callback<7>().set_inputline(m_fdccpu, M6502_IRQ_LINE);
486 	m_miot->pb_rd_callback<3>().set(m_fdc, FUNC(c2040_fdc_device::wps_r));
487 
488 	C2040_FDC(config, m_fdc, XTAL(16'000'000));
489 	m_fdc->sync_wr_callback().set(m_miot, FUNC(mos6530_new_device::pb6_w));
490 	m_fdc->ready_wr_callback().set(m_via, FUNC(via6522_device::write_ca1));
491 	m_fdc->error_wr_callback().set(m_via, FUNC(via6522_device::write_cb1));
492 }
493 
device_add_mconfig(machine_config & config)494 void c2040_device::device_add_mconfig(machine_config &config)
495 {
496 	add_common_devices(config);
497 	FLOPPY_CONNECTOR(config, FDC_TAG":0", c2040_floppies, "525ssqd", c2040_device::floppy_formats, true);
498 	FLOPPY_CONNECTOR(config, FDC_TAG":1", c2040_floppies, "525ssqd", c2040_device::floppy_formats, true);
499 }
500 
device_add_mconfig(machine_config & config)501 void c3040_device::device_add_mconfig(machine_config &config)
502 {
503 	add_common_devices(config);
504 	FLOPPY_CONNECTOR(config, FDC_TAG":0", c2040_floppies, "525ssqd", c3040_device::floppy_formats, true);
505 	FLOPPY_CONNECTOR(config, FDC_TAG":1", c2040_floppies, "525ssqd", c3040_device::floppy_formats, true);
506 }
507 
device_add_mconfig(machine_config & config)508 void c4040_device::device_add_mconfig(machine_config &config)
509 {
510 	add_common_devices(config);
511 	FLOPPY_CONNECTOR(config, FDC_TAG":0", c2040_floppies, "525ssqd", c4040_device::floppy_formats, true);
512 	FLOPPY_CONNECTOR(config, FDC_TAG":1", c2040_floppies, "525ssqd", c4040_device::floppy_formats, true);
513 }
514 
515 
516 //-------------------------------------------------
517 //  INPUT_PORTS( c2040 )
518 //-------------------------------------------------
519 
520 static INPUT_PORTS_START( c2040 )
521 	PORT_START("ADDRESS")
522 	PORT_DIPNAME( 0x07, 0x00, "Device Address" )
523 	PORT_DIPSETTING(    0x00, "8" )
524 	PORT_DIPSETTING(    0x01, "9" )
525 	PORT_DIPSETTING(    0x02, "10" )
526 	PORT_DIPSETTING(    0x03, "11" )
527 	PORT_DIPSETTING(    0x04, "12" )
528 	PORT_DIPSETTING(    0x05, "13" )
529 	PORT_DIPSETTING(    0x06, "14" )
530 	PORT_DIPSETTING(    0x07, "15" )
531 INPUT_PORTS_END
532 
533 
534 //-------------------------------------------------
535 //  input_ports - device-specific input ports
536 //-------------------------------------------------
537 
device_input_ports() const538 ioport_constructor c2040_device::device_input_ports() const
539 {
540 	return INPUT_PORTS_NAME( c2040 );
541 }
542 
543 
544 
545 //**************************************************************************
546 //  INLINE HELPERS
547 //**************************************************************************
548 
549 //-------------------------------------------------
550 //  update_ieee_signals -
551 //-------------------------------------------------
552 
update_ieee_signals()553 inline void c2040_device::update_ieee_signals()
554 {
555 	int atn = m_bus->atn_r();
556 	int nrfd = !(!(!(atn && m_atna) && m_rfdo) || !(atn || m_atna));
557 	int ndac = !(m_daco || !(atn || m_atna));
558 
559 	m_bus->nrfd_w(this, nrfd);
560 	m_bus->ndac_w(this, ndac);
561 }
562 
563 
564 
565 //**************************************************************************
566 //  LIVE DEVICE
567 //**************************************************************************
568 
569 //-------------------------------------------------
570 //  c2040_device - constructor
571 //-------------------------------------------------
572 
c2040_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock)573 c2040_device::c2040_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
574 	device_t(mconfig, type, tag, owner, clock),
575 	device_ieee488_interface(mconfig, *this),
576 	m_maincpu(*this, M6502_TAG),
577 	m_fdccpu(*this, M6504_TAG),
578 	m_riot0(*this, M6532_0_TAG),
579 	m_riot1(*this, M6532_1_TAG),
580 	m_miot(*this, M6530_TAG),
581 	m_via(*this, M6522_TAG),
582 	m_floppy0(*this, FDC_TAG":0:525ssqd"),
583 	m_floppy1(*this, FDC_TAG":1:525ssqd"),
584 	m_fdc(*this, FDC_TAG),
585 	m_gcr(*this, "gcr"),
586 	m_address(*this, "ADDRESS"),
587 	m_leds(*this, "led%u", 0U),
588 	m_rfdo(1),
589 	m_daco(1),
590 	m_atna(1),
591 	m_ifc(0)
592 {
593 }
594 
c2040_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)595 c2040_device::c2040_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
596 	c2040_device(mconfig, C2040, tag, owner, clock)
597 {
598 }
599 
600 
601 //-------------------------------------------------
602 //  c3040_device - constructor
603 //-------------------------------------------------
604 
c3040_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)605 c3040_device::c3040_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
606 	c2040_device(mconfig, C3040, tag, owner, clock)
607 {
608 }
609 
610 
611 //-------------------------------------------------
612 //  c4040_device - constructor
613 //-------------------------------------------------
614 
c4040_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)615 c4040_device::c4040_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
616 	c2040_device(mconfig, C4040, tag, owner, clock)
617 {
618 }
619 
620 
621 //-------------------------------------------------
622 //  device_start - device-specific startup
623 //-------------------------------------------------
624 
device_start()625 void c2040_device::device_start()
626 {
627 	m_leds.resolve();
628 	// install image callbacks
629 	m_fdc->set_floppy(m_floppy0, m_floppy1);
630 
631 	// register for state saving
632 	save_item(NAME(m_rfdo));
633 	save_item(NAME(m_daco));
634 	save_item(NAME(m_atna));
635 	save_item(NAME(m_ifc));
636 }
637 
638 
639 //-------------------------------------------------
640 //  device_reset - device-specific reset
641 //-------------------------------------------------
642 
device_reset()643 void c2040_device::device_reset()
644 {
645 	m_maincpu->reset();
646 
647 	// toggle M6502 SO
648 	m_maincpu->set_input_line(M6502_SET_OVERFLOW, ASSERT_LINE);
649 	m_maincpu->set_input_line(M6502_SET_OVERFLOW, CLEAR_LINE);
650 
651 	m_fdccpu->reset();
652 
653 	m_riot0->reset();
654 	m_riot1->reset();
655 	m_miot->reset();
656 	m_via->reset();
657 
658 	m_riot1->pa7_w(0);
659 
660 	// turn off spindle motors
661 	m_fdc->mtr0_w(1);
662 	m_fdc->mtr1_w(1);
663 }
664 
665 
666 //-------------------------------------------------
667 //  ieee488_atn -
668 //-------------------------------------------------
669 
ieee488_atn(int state)670 void c2040_device::ieee488_atn(int state)
671 {
672 	update_ieee_signals();
673 
674 	m_riot1->pa7_w(!state);
675 }
676 
677 
678 //-------------------------------------------------
679 //  ieee488_ifc -
680 //-------------------------------------------------
681 
ieee488_ifc(int state)682 void c2040_device::ieee488_ifc(int state)
683 {
684 	if (!m_ifc && state)
685 	{
686 		device_reset();
687 	}
688 
689 	m_ifc = state;
690 }
691