/********************************************************************** Commodore 1540/1541/1541C/1541-II Single Disk Drive emulation Copyright MESS Team. Visit http://mamedev.org for licensing and usage restrictions. **********************************************************************/ /* TODO: - c1540 fails to load the directory intermittently - hardware extensions - Dolphin-DOS 2.0 - Dolphin-DOS 3.0 - Professional-DOS - Prologic-DOS */ /* 1540/1541/1541A/SX-64 Parts Location Part Number Description 2016 2K x 8 bit Static RAM (short board) UA2-UB3 2114 (4) 1K x 4 bit Static RAM (long board) 325572-01 64H105 40 pin Gate Array (short board) 325302-01 2364-130 ROM DOS 2.6 C000-DFFF 325303-01 2364-131 ROM DOS 2.6 (1540) E000-FFFF 901229-01 2364-173 ROM DOS 2.6 rev. 0 E000-FFFF 901229-03 2364-197 ROM DOS 2.6 rev. 1 E000-FFFF 901229-05 8K ROM DOS 2.6 rev. 2 E000-FFFF 6502 CPU 6522 (2) VIA drive Alps DFB111M25A drive Alps FDM2111-B2 drive Newtronics D500 1541B/1541C Parts Location Part Number Description UA3 2016 2K x 8 bit Static RAM UC2 6502 CPU UC1, UC3 6522 (2) CIA UC4 251828-02 64H156 42 pin Gate Array UC5 251829-01 64H157 20 pin Gate Array UD1 * 251853-01 R/W Hybrid UD1 * 251853-02 R/W Hybrid UA2 251968-01 27128 EPROM DOS 2.6 rev. 3 C000-FFFF drive Newtronics D500 * Not interchangeable. 1541-II Parts Location Part Number Description U5 2016-15 2K x 8 bit Static RAM U12 SONY CX20185 R/W Amp. U3 6502A CPU U6, U8 6522 (2) CIA U10 251828-01 64H156 40 pin Gate Array U4 251968-03 16K ROM DOS 2.6 rev. 4 C000-FFFF drive Chinon FZ-501M REV A drive Digital System DS-50F drive Newtronics D500 drive Safronic DS-50F ... PCB Assy # 1540008-01 Schematic # 1540001 Original "Long" Board Has 4 discreet 2114 RAMs ALPS Drive only PCB Assy # 1540048 Schematic # 1540049 Referred to as the CR board Changed to 2048 x 8 bit RAM pkg. A 40 pin Gate Array is used Alps Drive (-01) Newtronics Drive (-03) PCB Assy # 250442-01 Schematic # 251748 Termed the 1541 A Just one jumper change to accommodate both types of drive PCB Assy # 250446-01 Schematic # 251748 (See Notes) Termed the 1541 A-2 Just one jumper change to accommodate both types of drive ... VIC1541 1540001-01 Very early version, long board. 1540001-03 As above, only the ROMs are different. 1540008-01 1541 1540048-01 Shorter board with a 40 pin gate array, Alps mech. 1540048-03 As above, but Newtronics mech. 1540049 Similar to above 1540050 Similar to above, Alps mechanism. SX64 250410-01 Design most similar to 1540048-01, Alps mechanism. 1541 251777 Function of bridge rects. reversed, Newtronics mech. 251830 Same as above 1541A 250442-01 Alps or Newtronics drive selected by a jumper. 1541A2 250446-01 A 74LS123 replaces the 9602 at UD4. 1541B 250448-01 Same as the 1541C, but in a case like the 1541. 1541C 250448-01 Short board, new 40/42 pin gate array, 20 pin gate array and a R/W hybrid chip replace many components. Uses a Newtronics drive with optical trk 0 sensor. 1541C 251854 As above, single DOS ROM IC, trk 0 sensor, 30 pin IC for R/W ampl & stepper motor control (like 1541). 1541-II A complete redesign using the 40 pin gate array from the 1451C and a Sony R/W hybrid, but not the 20 pin gate array, single DOS ROM IC. NOTE: These system boards are the 60 Hz versions. The -02 and -04 boards are probably the 50 Hz versions. The ROMs appear to be completely interchangeable. For instance, the first version of ROM for the 1541-II contained the same code as the last version of the 1541. I copy the last version of the 1541-II ROM into two 68764 EPROMs and use them in my original 1541 (long board). Not only do they work, but they work better than the originals. http://www.amiga-stuff.com/hardware/cbmboards.html */ #include "c1541.h" //************************************************************************** // MACROS / CONSTANTS //************************************************************************** #define M6502_TAG "ucd5" #define M6522_0_TAG "uab1" #define M6522_1_TAG "ucd4" #define C64H156_TAG "uc4" #define C64H157_TAG "uc5" #define MC6821_TAG "pia" #define CENTRONICS_TAG "centronics" enum { LED_POWER = 0, LED_ACT }; //************************************************************************** // DEVICE DEFINITIONS //************************************************************************** const device_type C1540 = &device_creator; const device_type C1541 = &device_creator; const device_type C1541C = &device_creator; const device_type C1541II = &device_creator; const device_type SX1541 = &device_creator; const device_type FSD2 = &device_creator; const device_type CSD1 = &device_creator; const device_type C1541_DOLPHIN_DOS = &device_creator; const device_type C1541_PROFESSIONAL_DOS_V1 = &device_creator; const device_type C1541_PROLOGIC_DOS_CLASSIC = &device_creator; //------------------------------------------------- // ROM( c1540 ) //------------------------------------------------- ROM_START( c1540 ) ROM_REGION( 0x4000, M6502_TAG, 0 ) ROM_LOAD( "325302-01.uab4", 0x0000, 0x2000, CRC(29ae9752) SHA1(8e0547430135ba462525c224e76356bd3d430f11) ) ROM_LOAD( "325303-01.uab5", 0x2000, 0x2000, CRC(10b39158) SHA1(56dfe79b26f50af4e83fd9604857756d196516b9) ) ROM_END //------------------------------------------------- // ROM( c1541 ) //------------------------------------------------- ROM_START( c1541 ) ROM_REGION( 0x8000, M6502_TAG, 0 ) ROM_LOAD( "325302-01.uab4", 0x0000, 0x2000, CRC(29ae9752) SHA1(8e0547430135ba462525c224e76356bd3d430f11) ) ROM_DEFAULT_BIOS("r6") ROM_SYSTEM_BIOS( 0, "r1", "Revision 1" ) ROMX_LOAD( "901229-01.uab5", 0x2000, 0x2000, CRC(9a48d3f0) SHA1(7a1054c6156b51c25410caec0f609efb079d3a77), ROM_BIOS(1) ) ROM_SYSTEM_BIOS( 1, "r2", "Revision 2" ) ROMX_LOAD( "901229-02.uab5", 0x2000, 0x2000, CRC(b29bab75) SHA1(91321142e226168b1139c30c83896933f317d000), ROM_BIOS(2) ) ROM_SYSTEM_BIOS( 2, "r3", "Revision 3" ) ROMX_LOAD( "901229-03.uab5", 0x2000, 0x2000, CRC(9126e74a) SHA1(03d17bd745066f1ead801c5183ac1d3af7809744), ROM_BIOS(3) ) ROM_SYSTEM_BIOS( 3, "r4", "Revision 4" ) ROMX_LOAD( "901229-04.uab5", 0x2000, 0x2000, NO_DUMP, ROM_BIOS(4) ) ROM_SYSTEM_BIOS( 4, "r5", "Revision 5" ) ROMX_LOAD( "901229-05 ae.uab5", 0x2000, 0x2000, CRC(361c9f37) SHA1(f5d60777440829e46dc91285e662ba072acd2d8b), ROM_BIOS(5) ) ROM_SYSTEM_BIOS( 5, "r6", "Revision 6" ) ROMX_LOAD( "901229-06 aa.uab5", 0x2000, 0x2000, CRC(3a235039) SHA1(c7f94f4f51d6de4cdc21ecbb7e57bb209f0530c0), ROM_BIOS(6) ) ROM_SYSTEM_BIOS( 6, "jiffydos", "JiffyDOS v6.01" ) ROMX_LOAD( "jiffydos 1541.uab5", 0x2000, 0x2000, CRC(bc7e4aeb) SHA1(db6cfaa6d9b78d58746c811de29f3b1f44d99ddf), ROM_BIOS(7) ) ROM_SYSTEM_BIOS( 7, "speeddos", "SpeedDOS-Plus+" ) ROMX_LOAD( "speed-dosplus.uab5", 0x0000, 0x4000, CRC(f9db1eac) SHA1(95407e59a9c1d26a0e4bcf2c244cfe8942576e2c), ROM_BIOS(8) ) ROM_SYSTEM_BIOS( 8, "rolo27", "Rolo DOS v2.7" ) ROMX_LOAD( "rolo27.uab5", 0x0000, 0x2000, CRC(171c7962) SHA1(04c892c4b3d7c74750576521fa081f07d8ca8557), ROM_BIOS(9) ) ROM_SYSTEM_BIOS( 9, "tt34", "TurboTrans v3.4" ) ROMX_LOAD( "ttd34.uab5", 0x0000, 0x8000, CRC(518d34a1) SHA1(4d6ffdce6ab122e9627b0a839861687bcd4e03ec), ROM_BIOS(10) ) ROM_SYSTEM_BIOS( 10, "digidos", "DigiDOS" ) ROMX_LOAD( "digidos.uab5", 0x0000, 0x2000, CRC(b3f05ea3) SHA1(99d3d848344c68410b686cda812f3788b41fead3), ROM_BIOS(11) ) ROM_END //------------------------------------------------- // ROM( c1541c ) //------------------------------------------------- ROM_START( c1541c ) ROM_REGION( 0x4000, M6502_TAG, 0 ) ROM_DEFAULT_BIOS("r2") ROM_SYSTEM_BIOS( 0, "r1", "Revision 1" ) ROMX_LOAD( "251968-01.ua2", 0x0000, 0x4000, CRC(1b3ca08d) SHA1(8e893932de8cce244117fcea4c46b7c39c6a7765), ROM_BIOS(1) ) ROM_SYSTEM_BIOS( 1, "r2", "Revision 2" ) ROMX_LOAD( "251968-02.ua2", 0x0000, 0x4000, CRC(2d862d20) SHA1(38a7a489c7bbc8661cf63476bf1eb07b38b1c704), ROM_BIOS(2) ) ROM_END //------------------------------------------------- // ROM( c1541ii ) //------------------------------------------------- ROM_START( c1541ii ) ROM_REGION( 0x8000, M6502_TAG, 0 ) ROM_LOAD( "251968-03.u4", 0x0000, 0x4000, CRC(899fa3c5) SHA1(d3b78c3dbac55f5199f33f3fe0036439811f7fb3) ) ROM_DEFAULT_BIOS("r1") ROM_SYSTEM_BIOS( 0, "r1", "Revision 1" ) ROMX_LOAD( "355640-01.u4", 0x0000, 0x4000, CRC(57224cde) SHA1(ab16f56989b27d89babe5f89c5a8cb3da71a82f0), ROM_BIOS(1) ) ROM_SYSTEM_BIOS( 1, "jiffydos", "JiffyDOS v6.01" ) ROMX_LOAD( "jiffydos 1541-ii.u4", 0x0000, 0x4000, CRC(dd409902) SHA1(b1a5b826304d3df2a27d7163c6a81a532e040d32), ROM_BIOS(2) ) ROM_END //------------------------------------------------- // ROM( sx1541 ) //------------------------------------------------- ROM_START( sx1541 ) ROM_REGION( 0x4000, M6502_TAG, 0 ) ROM_LOAD( "325302-01.uab4", 0x0000, 0x2000, CRC(29ae9752) SHA1(8e0547430135ba462525c224e76356bd3d430f11) ) ROM_DEFAULT_BIOS("r5") ROM_SYSTEM_BIOS( 0, "r5", "Revision 5" ) ROMX_LOAD( "901229-05 ae.uab5", 0x2000, 0x2000, CRC(361c9f37) SHA1(f5d60777440829e46dc91285e662ba072acd2d8b), ROM_BIOS(1) ) ROM_SYSTEM_BIOS( 1, "jiffydos", "JiffyDOS v6.01" ) ROMX_LOAD( "jiffydos sx1541", 0x0000, 0x4000, CRC(783575f6) SHA1(36ccb9ff60328c4460b68522443ecdb7f002a234), ROM_BIOS(2) ) ROM_SYSTEM_BIOS( 2, "flash", "1541 FLASH!" ) ROMX_LOAD( "1541 flash.uab5", 0x2000, 0x2000, CRC(22f7757e) SHA1(86a1e43d3d22b35677064cca400a6bd06767a3dc), ROM_BIOS(3) ) ROM_END //------------------------------------------------- // ROM( fsd2 ) //------------------------------------------------- ROM_START( fsd2 ) ROM_REGION( 0x4000, M6502_TAG, 0 ) // data lines D3 and D4 are swapped ROM_DEFAULT_BIOS("fsd2") ROM_SYSTEM_BIOS( 0, "ra", "Revision A" ) ROMX_LOAD( "fsd2a.u3", 0x0000, 0x4000, CRC(edf18265) SHA1(47a7c4bdcc20ecc5e59d694b151f493229becaea), ROM_BIOS(1) ) ROM_SYSTEM_BIOS( 1, "rb", "Revision B" ) ROMX_LOAD( "fsd2b.u3", 0x0000, 0x4000, CRC(b39e4600) SHA1(991132fcc6e70e9a428062ae76055a150f2f7ac6), ROM_BIOS(2) ) ROM_SYSTEM_BIOS( 2, "jiffydos", "JiffyDOS v5.0" ) ROMX_LOAD( "jiffydos v5.0.u3", 0x0000, 0x4000, CRC(46c3302c) SHA1(e3623658cb7af30c9d3bce2ba3b6ad5ee89ac1b8), ROM_BIOS(3) ) ROM_END //------------------------------------------------- // ROM( csd1 ) //------------------------------------------------- ROM_START( csd1 ) ROM_REGION( 0x4000, M6502_TAG, 0 ) ROM_LOAD( "ic14", 0x0000, 0x2000, CRC(adb6980e) SHA1(13051587dfe43b04ce1bf354b89438ddf6d8d76b) ) ROM_LOAD( "ic15", 0x2000, 0x2000, CRC(b0cecfa1) SHA1(c67e79a7ffefc9e9eafc238cb6ff6bb718f19afb) ) ROM_END //------------------------------------------------- // ROM( c1541dd ) //------------------------------------------------- ROM_START( c1541dd ) ROM_REGION( 0x8000, M6502_TAG, 0 ) ROM_LOAD( "dd20.bin", 0x0000, 0x8000, CRC(94c7fe19) SHA1(e4d5b9ad6b719dd988276214aa4536d3525d313c) ) ROM_END //------------------------------------------------- // ROM( c1541pd ) //------------------------------------------------- ROM_START( c1541pd ) ROM_REGION( 0x6000, M6502_TAG, 0 ) ROM_LOAD( "325302-01.uab4", 0x0000, 0x2000, CRC(29ae9752) SHA1(8e0547430135ba462525c224e76356bd3d430f11) ) ROM_LOAD( "professionaldos-v1-floppy-expansion-eprom-27128.bin", 0x2000, 0x4000, CRC(c9abf072) SHA1(2b26adc1f4192b6ca1514754f73c929087b24426) ) ROM_END //------------------------------------------------- // ROM( c1541pdc ) //------------------------------------------------- ROM_START( c1541pdc ) ROM_REGION( 0x8000, M6502_TAG, 0 ) ROM_LOAD( "325302-01.uab4", 0x0000, 0x2000, CRC(29ae9752) SHA1(8e0547430135ba462525c224e76356bd3d430f11) ) ROM_LOAD( "901229-06 aa.uab5", 0x2000, 0x2000, CRC(3a235039) SHA1(c7f94f4f51d6de4cdc21ecbb7e57bb209f0530c0) ) ROM_LOAD( "kernal.bin", 0x4000, 0x4000, CRC(79032ed5) SHA1(0ca4d5ef41c7e3d18d8945476d1481573af3e27c) ) ROM_REGION( 0x2000, "mmu", 0 ) ROM_LOAD( "mmu.bin", 0x0000, 0x2000, CRC(4c41392c) SHA1(78846af2ee6a56fceee44f9246659685ab2cbb7e) ) ROM_END //------------------------------------------------- // rom_region - device-specific ROM region //------------------------------------------------- const rom_entry *base_c1541_device::device_rom_region() const { switch (m_variant) { case TYPE_1540: return ROM_NAME( c1540 ); default: case TYPE_1541: return ROM_NAME( c1541 ); case TYPE_1541C: return ROM_NAME( c1541c ); case TYPE_1541II: return ROM_NAME( c1541ii ); case TYPE_SX1541: return ROM_NAME( sx1541 ); case TYPE_FSD2: // aka Excelerator PLUS / Oceanic OC-118N return ROM_NAME( fsd2 ); case TYPE_CSD1: return ROM_NAME( csd1 ); case TYPE_1541_DOLPHIN_DOS: return ROM_NAME( c1541dd ); case TYPE_1541_PROFESSIONAL_DOS_V1: return ROM_NAME( c1541pd ); case TYPE_1541_PROLOGIC_DOS_CLASSIC: return ROM_NAME( c1541pdc ); } } //------------------------------------------------- // read - //------------------------------------------------- READ8_MEMBER( c1541_prologic_dos_classic_device::read ) { return 0; } //------------------------------------------------- // write - //------------------------------------------------- WRITE8_MEMBER( c1541_prologic_dos_classic_device::write ) { } //------------------------------------------------- // ADDRESS_MAP( c1541_mem ) //------------------------------------------------- static ADDRESS_MAP_START( c1541_mem, AS_PROGRAM, 8, base_c1541_device ) AM_RANGE(0x0000, 0x07ff) AM_MIRROR(0x6000) AM_RAM AM_RANGE(0x1800, 0x180f) AM_MIRROR(0x63f0) AM_DEVREADWRITE(M6522_0_TAG, via6522_device, read, write) AM_RANGE(0x1c00, 0x1c0f) AM_MIRROR(0x63f0) AM_DEVREADWRITE(M6522_1_TAG, via6522_device, read, write) AM_RANGE(0x8000, 0xbfff) AM_MIRROR(0x4000) AM_ROM AM_REGION(M6502_TAG, 0) ADDRESS_MAP_END //------------------------------------------------- // ADDRESS_MAP( c1541dd_mem ) //------------------------------------------------- static ADDRESS_MAP_START( c1541dd_mem, AS_PROGRAM, 8, base_c1541_device ) AM_RANGE(0x0000, 0x07ff) AM_MIRROR(0x6000) AM_RAM AM_RANGE(0x1800, 0x180f) AM_MIRROR(0x63f0) AM_DEVREADWRITE(M6522_0_TAG, via6522_device, read, write) AM_RANGE(0x1c00, 0x1c0f) AM_MIRROR(0x63f0) AM_DEVREADWRITE(M6522_1_TAG, via6522_device, read, write) AM_RANGE(0x8000, 0x9fff) AM_RAM AM_RANGE(0xa000, 0xffff) AM_ROM AM_REGION(M6502_TAG, 0x2000) ADDRESS_MAP_END //------------------------------------------------- // ADDRESS_MAP( c1541pd_mem ) //------------------------------------------------- static ADDRESS_MAP_START( c1541pd_mem, AS_PROGRAM, 8, base_c1541_device ) AM_RANGE(0x0000, 0x07ff) AM_MIRROR(0x6000) AM_RAM AM_RANGE(0x1800, 0x180f) AM_MIRROR(0x63f0) AM_DEVREADWRITE(M6522_0_TAG, via6522_device, read, write) AM_RANGE(0x1c00, 0x1c0f) AM_MIRROR(0x63f0) AM_DEVREADWRITE(M6522_1_TAG, via6522_device, read, write) AM_RANGE(0x8000, 0x9fff) AM_ROM AM_REGION(M6502_TAG, 0x4000) AM_RANGE(0xa000, 0xbfff) AM_RAM AM_RANGE(0xc000, 0xffff) AM_ROM AM_REGION(M6502_TAG, 0x0000) AM_RANGE(0xe000, 0xffff) AM_ROM AM_REGION(M6502_TAG, 0x2000) ADDRESS_MAP_END //------------------------------------------------- // ADDRESS_MAP( c1541pdc_mem ) //------------------------------------------------- static ADDRESS_MAP_START( c1541pdc_mem, AS_PROGRAM, 8, c1541_prologic_dos_classic_device ) AM_RANGE(0x0000, 0xffff) AM_READWRITE(read, write) /* AM_RANGE(0x0000, 0x07ff) AM_MIRROR(0x6000) AM_RAM AM_SHARE("share1") AM_RANGE(0x1800, 0x180f) AM_MIRROR(0x63f0) AM_DEVREADWRITE(M6522_0_TAG, via6522_device, read, write) AM_RANGE(0x1c00, 0x1c0f) AM_MIRROR(0x63f0) AM_DEVREADWRITE(M6522_1_TAG, via6522_device, read, write) AM_RANGE(0x8000, 0x87ff) AM_RAM AM_SHARE("share1") AM_RANGE(0x8800, 0x9fff) AM_RAM AM_RANGE(0xa000, 0xb7ff) AM_ROM AM_REGION(M6502_TAG, 0x0000) AM_RANGE(0xb800, 0xb80f) AM_READWRITE(pia_r, pia_w) AM_RANGE(0xf000, 0xffff) AM_ROM AM_REGION(M6502_TAG, 0x2000)*/ ADDRESS_MAP_END //------------------------------------------------- // via6522_interface via0_intf //------------------------------------------------- WRITE_LINE_MEMBER( base_c1541_device::via0_irq_w ) { m_via0_irq = state; m_maincpu->set_input_line(INPUT_LINE_IRQ0, (m_via0_irq || m_via1_irq) ? ASSERT_LINE : CLEAR_LINE); } READ8_MEMBER( base_c1541_device::via0_pa_r ) { // dummy read to acknowledge ATN IN interrupt return m_parallel_data; } WRITE8_MEMBER( base_c1541_device::via0_pa_w ) { if (m_other != NULL) { m_other->parallel_data_w(data); } } READ8_MEMBER( base_c1541_device::via0_pb_r ) { /* bit description PB0 DATA IN PB1 PB2 CLK IN PB3 PB4 PB5 J1 PB6 J2 PB7 ATN IN */ UINT8 data = 0; // data in data = !m_bus->data_r() && !m_ga->atn_r(); // clock in data |= !m_bus->clk_r() << 2; // serial bus address data |= (m_address - 8) << 5; // attention in data |= !m_bus->atn_r() << 7; return data; } WRITE8_MEMBER( base_c1541_device::via0_pb_w ) { /* bit description PB0 PB1 DATA OUT PB2 PB3 CLK OUT PB4 ATNA PB5 PB6 PB7 */ // data out m_data_out = BIT(data, 1); // attention acknowledge m_ga->atna_w(BIT(data, 4)); // clock out m_bus->clk_w(this, !BIT(data, 3)); } READ_LINE_MEMBER( base_c1541_device::atn_in_r ) { return !m_bus->atn_r(); } WRITE_LINE_MEMBER( base_c1541_device::via0_ca2_w ) { if (m_other != NULL) { m_other->parallel_strobe_w(state); } } static const via6522_interface c1541_via0_intf = { DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, base_c1541_device, via0_pa_r), DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, base_c1541_device, via0_pb_r), DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, base_c1541_device, atn_in_r), DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, base_c1541_device, via0_pa_w), DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, base_c1541_device, via0_pb_w), DEVCB_NULL, DEVCB_NULL, DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, base_c1541_device, via0_ca2_w), DEVCB_NULL, DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, base_c1541_device, via0_irq_w) }; //------------------------------------------------- // via6522_interface c1541c_via0_intf //------------------------------------------------- READ8_MEMBER( c1541c_device::via0_pa_r ) { /* bit description PA0 TR00 SENCE PA1 PA2 PA3 PA4 PA5 PA6 PA7 */ return !floppy_tk00_r(m_image); } static const via6522_interface c1541c_via0_intf = { DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, c1541c_device, via0_pa_r), DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, base_c1541_device, via0_pb_r), DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, base_c1541_device, atn_in_r), DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, base_c1541_device, via0_pb_w), DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, base_c1541_device, via0_irq_w) }; //------------------------------------------------- // via6522_interface via1_intf //------------------------------------------------- WRITE_LINE_MEMBER( base_c1541_device::via1_irq_w ) { m_via1_irq = state; m_maincpu->set_input_line(INPUT_LINE_IRQ0, (m_via0_irq || m_via1_irq) ? ASSERT_LINE : CLEAR_LINE); } READ8_MEMBER( base_c1541_device::via1_pb_r ) { /* bit signal description PB0 PB1 PB2 PB3 PB4 WPS write protect sense PB5 PB6 PB7 SYNC SYNC detect line */ UINT8 data = 0; // write protect sense data |= !floppy_wpt_r(m_image) << 4; // SYNC detect line data |= m_ga->sync_r() << 7; return data; } WRITE8_MEMBER( base_c1541_device::via1_pb_w ) { /* bit signal description PB0 STP0 stepping motor bit 0 PB1 STP1 stepping motor bit 1 PB2 MTR motor ON/OFF PB3 ACT drive 0 LED PB4 PB5 DS0 density select 0 PB6 DS1 density select 1 PB7 SYNC SYNC detect line */ // spindle motor m_ga->mtr_w(BIT(data, 2)); // stepper motor m_ga->stp_w(data & 0x03); // activity LED output_set_led_value(LED_ACT, BIT(data, 3)); // density select m_ga->ds_w((data >> 5) & 0x03); } static const via6522_interface c1541_via1_intf = { DEVCB_DEVICE_MEMBER(C64H156_TAG, c64h156_device, yb_r), DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, base_c1541_device, via1_pb_r), DEVCB_DEVICE_LINE_MEMBER(C64H156_TAG, c64h156_device, byte_r), DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DEVICE_MEMBER(C64H156_TAG, c64h156_device, yb_w), DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, base_c1541_device, via1_pb_w), DEVCB_NULL, DEVCB_NULL, DEVCB_DEVICE_LINE_MEMBER(C64H156_TAG, c64h156_device, soe_w), DEVCB_DEVICE_LINE_MEMBER(C64H156_TAG, c64h156_device, oe_w), DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, base_c1541_device, via1_irq_w) }; //------------------------------------------------- // C64H156_INTERFACE( ga_intf ) //------------------------------------------------- WRITE_LINE_MEMBER( base_c1541_device::atn_w ) { set_iec_data(); } WRITE_LINE_MEMBER( base_c1541_device::byte_w ) { m_maincpu->set_input_line(M6502_SET_OVERFLOW, state); m_via1->write_ca1(state); } static C64H156_INTERFACE( ga_intf ) { DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, base_c1541_device, atn_w), DEVCB_NULL, DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, base_c1541_device, byte_w) }; //------------------------------------------------- // LEGACY_FLOPPY_OPTIONS( c1541 ) //------------------------------------------------- LEGACY_FLOPPY_OPTIONS_START( c1541 ) LEGACY_FLOPPY_OPTION( c1541, "g64", "Commodore 1541 GCR Disk Image", g64_dsk_identify, g64_dsk_construct, NULL, NULL ) LEGACY_FLOPPY_OPTION( c1541, "d64", "Commodore 1541 Disk Image", d64_dsk_identify, d64_dsk_construct, NULL, NULL ) LEGACY_FLOPPY_OPTIONS_END //------------------------------------------------- // floppy_interface c1541_floppy_interface //------------------------------------------------- const floppy_interface c1541_floppy_interface = { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, FLOPPY_STANDARD_5_25_SSDD, LEGACY_FLOPPY_OPTIONS_NAME(c1541), "floppy_5_25", NULL }; //------------------------------------------------- // pia6821_interface pia0_intf //------------------------------------------------- READ8_MEMBER( c1541_prologic_dos_classic_device::pia_r ) { return m_pia->read(space, (offset >> 2) & 0x03); } WRITE8_MEMBER( c1541_prologic_dos_classic_device::pia_w ) { m_pia->write(space, (offset >> 2) & 0x03, data); } WRITE8_MEMBER( c1541_prologic_dos_classic_device::pia_pa_w ) { /* bit description 0 1/2 MHz 1 2 3 35/40 tracks 4 5 6 7 Hi */ } READ8_MEMBER( c1541_prologic_dos_classic_device::pia_pb_r ) { return m_parallel_data; } WRITE8_MEMBER( c1541_prologic_dos_classic_device::pia_pb_w ) { m_parallel_data = data; m_centronics->write(space, 0, data); } static const pia6821_interface pia_intf = { DEVCB_NULL, DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, c1541_prologic_dos_classic_device, pia_pb_r), DEVCB_DEVICE_LINE_MEMBER(CENTRONICS_TAG, centronics_device, ack_r), DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, c1541_prologic_dos_classic_device, pia_pa_w), DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, c1541_prologic_dos_classic_device, pia_pb_w), DEVCB_DEVICE_LINE_MEMBER(CENTRONICS_TAG, centronics_device, strobe_w), DEVCB_NULL, DEVCB_NULL, DEVCB_NULL }; //------------------------------------------------- // MACHINE_DRIVER( c1541 ) //------------------------------------------------- static MACHINE_CONFIG_FRAGMENT( c1541 ) MCFG_CPU_ADD(M6502_TAG, M6502, XTAL_16MHz/16) MCFG_CPU_PROGRAM_MAP(c1541_mem) MCFG_QUANTUM_PERFECT_CPU(M6502_TAG) MCFG_VIA6522_ADD(M6522_0_TAG, XTAL_16MHz/16, c1541_via0_intf) MCFG_VIA6522_ADD(M6522_1_TAG, XTAL_16MHz/16, c1541_via1_intf) MCFG_LEGACY_FLOPPY_DRIVE_ADD(FLOPPY_0, c1541_floppy_interface) MCFG_64H156_ADD(C64H156_TAG, XTAL_16MHz, ga_intf) MACHINE_CONFIG_END //------------------------------------------------- // MACHINE_DRIVER( c1541c ) //------------------------------------------------- static MACHINE_CONFIG_FRAGMENT( c1541c ) MCFG_FRAGMENT_ADD(c1541) MCFG_DEVICE_MODIFY(M6522_0_TAG) MCFG_DEVICE_CONFIG(c1541c_via0_intf) MACHINE_CONFIG_END //------------------------------------------------- // MACHINE_DRIVER( c1541dd ) //------------------------------------------------- static MACHINE_CONFIG_FRAGMENT( c1541dd ) MCFG_FRAGMENT_ADD(c1541) MCFG_CPU_MODIFY(M6502_TAG) MCFG_CPU_PROGRAM_MAP(c1541dd_mem) MACHINE_CONFIG_END //------------------------------------------------- // MACHINE_DRIVER( c1541pd ) //------------------------------------------------- static MACHINE_CONFIG_FRAGMENT( c1541pd ) MCFG_FRAGMENT_ADD(c1541) MCFG_CPU_MODIFY(M6502_TAG) MCFG_CPU_PROGRAM_MAP(c1541pd_mem) MACHINE_CONFIG_END //------------------------------------------------- // MACHINE_DRIVER( c1541pdc ) //------------------------------------------------- static MACHINE_CONFIG_FRAGMENT( c1541pdc ) MCFG_FRAGMENT_ADD(c1541) MCFG_CPU_MODIFY(M6502_TAG) MCFG_CPU_PROGRAM_MAP(c1541pdc_mem) MCFG_PIA6821_ADD(MC6821_TAG, pia_intf) MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, standard_centronics) MACHINE_CONFIG_END //------------------------------------------------- // machine_config_additions - device-specific // machine configurations //------------------------------------------------- machine_config_constructor base_c1541_device::device_mconfig_additions() const { switch (m_variant) { default: return MACHINE_CONFIG_NAME( c1541 ); case TYPE_1541C: return MACHINE_CONFIG_NAME( c1541c ); case TYPE_1541_DOLPHIN_DOS: return MACHINE_CONFIG_NAME( c1541dd ); case TYPE_1541_PROFESSIONAL_DOS_V1: return MACHINE_CONFIG_NAME( c1541pd ); case TYPE_1541_PROLOGIC_DOS_CLASSIC: return MACHINE_CONFIG_NAME( c1541pdc ); } } //************************************************************************** // INLINE HELPERS //************************************************************************** //------------------------------------------------- // set_iec_data - //------------------------------------------------- inline void base_c1541_device::set_iec_data() { int data = !m_data_out && !m_ga->atn_r(); m_bus->data_w(this, data); } //************************************************************************** // LIVE DEVICE //************************************************************************** //------------------------------------------------- // base_c1541_device - constructor //------------------------------------------------- base_c1541_device:: base_c1541_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT32 variant, const char *shortname, const char *source) : device_t(mconfig, type, name, tag, owner, clock, shortname, source), device_cbm_iec_interface(mconfig, *this), device_c64_floppy_parallel_interface(mconfig, *this), m_maincpu(*this, M6502_TAG), m_via0(*this, M6522_0_TAG), m_via1(*this, M6522_1_TAG), m_ga(*this, C64H156_TAG), m_image(*this, FLOPPY_0), m_data_out(1), m_via0_irq(CLEAR_LINE), m_via1_irq(CLEAR_LINE), m_variant(variant) { } //------------------------------------------------- // c1540_device - constructor //------------------------------------------------- c1540_device::c1540_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : base_c1541_device(mconfig, C1540, "C1540", tag, owner, clock, TYPE_1540, "c1540", __FILE__) { } //------------------------------------------------- // c1541_device - constructor //------------------------------------------------- c1541_device::c1541_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : base_c1541_device(mconfig, C1541, "C1541", tag, owner, clock, TYPE_1541, "c1541", __FILE__) { } //------------------------------------------------- // c1541c_device - constructor //------------------------------------------------- c1541c_device::c1541c_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : base_c1541_device(mconfig, C1541C, "C1541C", tag, owner, clock, TYPE_1541C, "c1541c", __FILE__) { } //------------------------------------------------- // c1541ii_device - constructor //------------------------------------------------- c1541ii_device::c1541ii_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : base_c1541_device(mconfig, C1541II, "C1541-II", tag, owner, clock, TYPE_1541II, "c1541ii", __FILE__) { } //------------------------------------------------- // sx1541_device - constructor //------------------------------------------------- sx1541_device::sx1541_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : base_c1541_device(mconfig, SX1541, "SX1541", tag, owner, clock, TYPE_SX1541, "sx1541", __FILE__) { } //------------------------------------------------- // fsd2_device - constructor //------------------------------------------------- fsd2_device::fsd2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : base_c1541_device(mconfig, FSD2, "FSD-2", tag, owner, clock, TYPE_FSD2, "fsd2", __FILE__) { } //------------------------------------------------- // csd1_device - constructor //------------------------------------------------- csd1_device::csd1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : base_c1541_device(mconfig, CSD1, "CSD-1", tag, owner, clock, TYPE_CSD1, "csd1", __FILE__) { } //------------------------------------------------- // c1541_dolphin_dos_device - constructor //------------------------------------------------- c1541_dolphin_dos_device::c1541_dolphin_dos_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : base_c1541_device(mconfig, C1541_DOLPHIN_DOS, "C1541 Dolphin-DOS 2.0", tag, owner, clock, TYPE_1541_DOLPHIN_DOS, "c1541dd", __FILE__) { } //------------------------------------------------- // c1541_professional_dos_v1_device - constructor //------------------------------------------------- c1541_professional_dos_v1_device::c1541_professional_dos_v1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : base_c1541_device(mconfig, C1541_PROFESSIONAL_DOS_V1, "C1541 Professional-DOS v1", tag, owner, clock, TYPE_1541_PROFESSIONAL_DOS_V1, "c1541pd", __FILE__) { } //------------------------------------------------- // c1541_prologic_dos_classic_device - constructor //------------------------------------------------- c1541_prologic_dos_classic_device::c1541_prologic_dos_classic_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : base_c1541_device(mconfig, C1541_PROLOGIC_DOS_CLASSIC, "C1541 ProLogic-DOS Classic", tag, owner, clock, TYPE_1541_PROLOGIC_DOS_CLASSIC, "c1541pdc", __FILE__), m_pia(*this, MC6821_TAG), m_centronics(*this, CENTRONICS_TAG), m_mmu_rom(*this, "mmu") { } //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- void base_c1541_device::device_start() { // install image callbacks m_ga->set_floppy(m_image); // register for state saving save_item(NAME(m_data_out)); save_item(NAME(m_via0_irq)); save_item(NAME(m_via1_irq)); } void fsd2_device::device_start() { base_c1541_device::device_start(); // decrypt ROM UINT8 *rom = memregion(M6502_TAG)->base(); for (offs_t offset = 0; offset < 0x4000; offset++) { UINT8 data = BITSWAP8(rom[offset], 7, 6, 5, 3, 4, 2, 1, 0); rom[offset] = data; } } //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- void base_c1541_device::device_reset() { m_maincpu->reset(); m_via0->reset(); m_via1->reset(); // initialize gate array m_ga->accl_w(0); m_ga->ted_w(1); } //------------------------------------------------- // iec_atn_w - //------------------------------------------------- void base_c1541_device::cbm_iec_atn(int state) { m_via0->write_ca1(!state); m_ga->atni_w(!state); set_iec_data(); } //------------------------------------------------- // iec_reset_w - //------------------------------------------------- void base_c1541_device::cbm_iec_reset(int state) { if (!state) { device_reset(); } } //------------------------------------------------- // parallel_data_w - //------------------------------------------------- void base_c1541_device::parallel_data_w(UINT8 data) { m_parallel_data = data; } //------------------------------------------------- // parallel_strobe_w - //------------------------------------------------- void base_c1541_device::parallel_strobe_w(int state) { m_via0->write_cb1(state); }