diff options
Diffstat (limited to 'src/mame/machine/isbc_215g.cpp')
-rw-r--r-- | src/mame/machine/isbc_215g.cpp | 434 |
1 files changed, 0 insertions, 434 deletions
diff --git a/src/mame/machine/isbc_215g.cpp b/src/mame/machine/isbc_215g.cpp deleted file mode 100644 index 4390604a884..00000000000 --- a/src/mame/machine/isbc_215g.cpp +++ /dev/null @@ -1,434 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Carl -// Currently only emulates Shugart SA1000 interface disks (aka ST506) -// despite the controller supporting many different disk types (hard sectored, onboard controllers, ANSI X3T9) -// Xenix supports the Quantum Q540 CHS 512,8,9 with 1024B sectors - -// TODO: multibus - -#include "emu.h" -#include "isbc_215g.h" - -DEFINE_DEVICE_TYPE(ISBC_215G, isbc_215g_device, "isbc_215g", "ISBC 215G Winchester Disk Controller") - -isbc_215g_device::isbc_215g_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - device_t(mconfig, ISBC_215G, tag, owner, clock), - m_maincpu(*this, finder_base::DUMMY_TAG), - m_dmac(*this, "u84"), - m_hdd0(*this, "drive0"), - m_hdd1(*this, "drive1"), - m_sbx1(*this, "sbx1"), - m_sbx2(*this, "sbx2"), - m_out_irq_func(*this) -{ -} - -void isbc_215g_device::find_sector() -{ - //sector id - // 0/6-7: sector type - 0-data, 1-alternate, 2-bad, 3-invalid - // 0/4-5: size - 128<<n - // 0/0-3: cyl high - // 1: cyl low - // 2: head - // 3: sector - uint16_t cyl = ((m_idcompare[0] & 0xf) << 8) | m_idcompare[1]; - uint16_t bps = 128 << ((m_idcompare[0] >> 4) & 3); - - if(!m_geom[m_drive]) - return; - - if(m_cyl[m_drive] != cyl) - return; - - if((m_idcompare[3] != m_head) || (m_head > m_geom[m_drive]->heads)) - return; - - if(m_idcompare[2] > m_geom[m_drive]->sectors) - return; - - if(bps != m_geom[m_drive]->sectorbytes) - return; - - if(m_idcompare[0] >> 6) - return; - - m_idfound = true; - m_lba[m_drive] = (cyl * m_geom[m_drive]->heads + m_head) * m_geom[m_drive]->sectors + m_idcompare[2]; - m_secoffset = 0; - return; -} - -uint16_t isbc_215g_device::read_sector() -{ - uint16_t wps = 64 << ((m_idcompare[0] >> 4) & 3); - harddisk_image_device *drive = (m_drive ? m_hdd1 : m_hdd0); - if(!m_secoffset) - hard_disk_read(drive->get_hard_disk_file(), m_lba[m_drive], m_sector); - if(m_secoffset >= wps) - return 0; - return m_sector[m_secoffset++]; -} - -bool isbc_215g_device::write_sector(uint16_t data) -{ - uint16_t wps = 64 << ((m_idcompare[0] >> 4) & 3); - harddisk_image_device *drive = (m_drive ? m_hdd1 : m_hdd0); - if(m_secoffset >= wps) - return true; - m_sector[m_secoffset++] = data; - if(m_secoffset == wps) - { - hard_disk_write(drive->get_hard_disk_file(), m_lba[m_drive], m_sector); - return true; - } - return false; -} - -READ16_MEMBER(isbc_215g_device::io_r) -{ - uint16_t data = 0; - switch(offset) - { - case 0x00: - //read status - // 0: gnd - // 1: drive ready - // 2: seek done - // 3: sector sync found - // 4: fault - // 5: bus ack - // 6: sector id not found or bad ecc - // 7: timeout - // 8: sbx 1 present - // 9: sbx 1 int 0 - // a: sbx 1 int 1 - // b: sbx 1 opt 0 - // c: sbx 1 opt 1 - // d: illegal req/vendor 2 - // e: drive req - // f: index latch - data |= (!m_idfound) << 6; - data |= (m_sbx1->get_card_device() ? 0 : 1) << 8; - data |= m_isbx_irq[0] << 9; - data |= m_isbx_irq[1] << 10; - data |= ((m_index--) <= 0) ? 0x8000 : 0; // fake an index pulse - break; - case 0x04: - //read status 2 - // 0: sbx 2 present - // 1: sbx 2 int 0 - // 2: sbx 2 int 1 - // 3: sbx 2 opt 0 - // 4: sbx 2 opt 1 - // 5: vendor bit 0 - // 6: track 0/busy - // 7: wp - data |= m_sbx2->get_card_device() ? 0 : 1; - data |= m_isbx_irq[2] << 1; - data |= m_isbx_irq[3] << 2; - data |= (!m_cyl[m_drive]) ? 0 : 0x40; - break; - case 0x08: - //cmd data bus - break; - case 0x0c: - // reset channel 2 - if(machine().side_effects_disabled()) // reading this is bad - break; - m_dmac->sel_w(1); - m_dmac->ca_w(1); - m_dmac->ca_w(0); - m_dmac->sel_w(0); - break; - case 0x10: - //pit ch 0 - break; - case 0x11: - //pit ch 1 - break; - case 0x12: - //pit ch 2 - break; - case 0x14: - //read buffer - if(m_rdgate && !m_amsrch && m_geom[m_drive]) - data = read_sector(); - break; - case 0x18: - //vendor bit 1,3-4 - data |= 3<<4 | 2; - break; - default: - logerror("isbc_215g: invalid port read 0x80%02x\n", offset*2); - break; - } - return data; -} - -WRITE16_MEMBER(isbc_215g_device::io_w) -{ - switch(offset) - { - case 0x00: - //control, 0x8002 doesn't set gates or search - // 0: wr gate - // 1: rd gate - // 2: address mark search - // 3: cmd bus enable - // 4: drive sel/head sel 2 - // 5: safe/head sel 1 - // 6: b ack - // 7: drive reg addr 0/step dir - // 8: drive reg addr 1 - // 9: cmd/rd - // a: para/head sel 0 - m_wrgate = data & 1; - m_rdgate = (data >> 1) & 1; - m_amsrch = (data >> 2) & 1; - if(m_wrgate && (m_rdgate || m_amsrch)) - logerror("isbc_215g: both write gate and read gate and/or address search enabled\n"); - else if(m_rdgate && m_amsrch) - find_sector(); - else if(m_amsrch) - logerror("isbc_215g: address search without read gate\n"); - case 0x01: - m_stepdir = (data & 0x80) ? 1 : 0; - break; - case 0x04: - //clear index and id latch - m_index = 10; - m_idfound = false; - break; - case 0x08: - //cmd data bus/head sel - m_head = data & 7; - m_out_irq_func((data & 0x100) ? 1 : 0); - break; - case 0x0c: - //unit select - // 0: step/wr - // 1: sbx 1 opt 0/1 (sbx2?) - // 2: sbx 2 opt 0/1 - // 3: unit select 0 - // 4: unit select 1 - // 5: extr 2 - // 6: format - // 7: format wr gate - if(!m_step && (data & 1) && m_geom[m_drive]) - { - if(m_cyl[m_drive] && !m_stepdir) - m_cyl[m_drive]--; - else if((m_cyl[m_drive] < m_geom[m_drive]->cylinders) && m_stepdir) - m_cyl[m_drive]++; - } - m_step = data & 1; - m_drive = (data >> 3) & 1; // shugart interface, two drives only - if(((data >> 1) & 1) != m_fdctc) - { - m_fdctc = !m_fdctc; - m_sbx2->opt0_w(m_fdctc); - } - if((data & 0xc0) == 0xc0) // low-level format - { - if(!m_format) - m_format_bytes = 5; // sync + sector id - m_format = true; - } - else - m_format = false; - break; - case 0x10: - //pit ch 0 - break; - case 0x11: - //pit ch 1 - break; - case 0x12: - //pit ch 2 - break; - case 0x13: - //pit control - break; - case 0x14: - //write buffer - if(m_wrgate) - { - if(m_format) - { - m_format_bytes -= 2; - if(m_format_bytes <= 0) - { - m_dmac->ext1_w(1); - m_dmac->ext1_w(0); - m_format_bytes = 5; - } - } - else - { - if(m_geom[m_drive]) - { - if(write_sector(data)) - { - m_dmac->ext1_w(1); - m_dmac->ext1_w(0); - } - } - } - } - break; - case 0x18: - //sector id/format - m_idcompare[1] = data & 0xff; - m_idcompare[0] = data >> 8; - break; - case 0x1c: - //sector id low - m_idcompare[3] = data & 0xff; - m_idcompare[2] = data >> 8; - break; - default: - logerror("isbc_215g: invalid port write 0x80%02x\n", offset*2); - break; - } -} - -READ16_MEMBER(isbc_215g_device::mem_r) -{ - // XXX: hack to permit debugger to disassemble rom - if(machine().side_effects_disabled() && (offset < 0x1fff)) - return m_dmac->space(AS_IO).read_word_unaligned(offset*2); - - switch(offset) - { - case 0x7fffb: - return 1; - case 0x7fffc: - return 0; - case 0x7fffd: - return m_wakeup; - default: - return m_maincpu_mem->read_word_unaligned(offset*2, mem_mask); - } -} - -WRITE16_MEMBER(isbc_215g_device::mem_w) -{ - m_maincpu_mem->write_word_unaligned(offset*2, data, mem_mask); -} - -void isbc_215g_device::isbc_215g_mem(address_map &map) -{ - map(0x00000, 0xfffff).rw(FUNC(isbc_215g_device::mem_r), FUNC(isbc_215g_device::mem_w)); -} - -void isbc_215g_device::isbc_215g_io(address_map &map) -{ - map(0x0000, 0x3fff).rom().region("i8089", 0); - map(0x4000, 0x47ff).mirror(0x3800).ram(); - map(0x8000, 0x8039).mirror(0x3fc0).rw(FUNC(isbc_215g_device::io_r), FUNC(isbc_215g_device::io_w)); - map(0xc070, 0xc08f).rw("sbx1", FUNC(isbx_slot_device::mcs0_r), FUNC(isbx_slot_device::mcs0_w)).umask16(0x00ff); - map(0xc0b0, 0xc0bf).rw("sbx1", FUNC(isbx_slot_device::mcs1_r), FUNC(isbx_slot_device::mcs1_w)).umask16(0x00ff); - map(0xc0d0, 0xc0df).rw("sbx2", FUNC(isbx_slot_device::mcs0_r), FUNC(isbx_slot_device::mcs0_w)).umask16(0x00ff); - map(0xc0e0, 0xc0ef).rw("sbx2", FUNC(isbx_slot_device::mcs1_r), FUNC(isbx_slot_device::mcs1_w)).umask16(0x00ff); -} - -WRITE_LINE_MEMBER(isbc_215g_device::isbx_irq_00_w) -{ - m_isbx_irq[0] = state ? true : false; -} - -WRITE_LINE_MEMBER(isbc_215g_device::isbx_irq_01_w) -{ - m_isbx_irq[1] = state ? true : false; -} - -WRITE_LINE_MEMBER(isbc_215g_device::isbx_irq_10_w) -{ - m_isbx_irq[2] = state ? true : false; -} - -WRITE_LINE_MEMBER(isbc_215g_device::isbx_irq_11_w) -{ - m_isbx_irq[3] = state ? true : false; -} - -void isbc_215g_device::device_add_mconfig(machine_config &config) -{ - I8089(config, m_dmac, XTAL(15'000'000) / 3); - m_dmac->set_addrmap(AS_PROGRAM, &isbc_215g_device::isbc_215g_mem); - m_dmac->set_addrmap(AS_IO, &isbc_215g_device::isbc_215g_io); - m_dmac->set_data_width(16); - - HARDDISK(config, "drive0", 0); - HARDDISK(config, "drive1", 0); - - ISBX_SLOT(config, m_sbx1, 0, isbx_cards, nullptr); - m_sbx1->mintr0().set(FUNC(isbc_215g_device::isbx_irq_00_w)); - m_sbx1->mintr1().set(FUNC(isbc_215g_device::isbx_irq_01_w)); - ISBX_SLOT(config, m_sbx2, 0, isbx_cards, "fdc_218a"); - m_sbx2->mintr0().set(FUNC(isbc_215g_device::isbx_irq_10_w)); - m_sbx2->mintr1().set(FUNC(isbc_215g_device::isbx_irq_11_w)); -} - - -ROM_START( isbc_215g ) - ROM_REGION( 0x4000, "i8089", ROMREGION_ERASEFF ) - ROM_LOAD16_BYTE( "174581.001.bin", 0x0000, 0x2000, CRC(ccdbc7ab) SHA1(5c2ebdde1b0252124177221ba9cacdb6d925a24d)) - ROM_LOAD16_BYTE( "174581.002.bin", 0x0001, 0x2000, CRC(6190fa67) SHA1(295dd4e75f699aaf93227cc4876cee8accae383a)) -ROM_END - -const tiny_rom_entry *isbc_215g_device::device_rom_region() const -{ - return ROM_NAME( isbc_215g ); -} - -void isbc_215g_device::device_reset() -{ - if(m_hdd0->get_hard_disk_file()) - m_geom[0] = hard_disk_get_info(m_hdd0->get_hard_disk_file()); - else - m_geom[0] = nullptr; - if(m_hdd1->get_hard_disk_file()) - m_geom[1] = hard_disk_get_info(m_hdd1->get_hard_disk_file()); - else - m_geom[1] = nullptr; - - m_reset = false; - m_fdctc = false; - m_isbx_irq[0] = m_isbx_irq[1] = m_isbx_irq[2] = m_isbx_irq[3] = false; -} - -void isbc_215g_device::device_start() -{ - m_maincpu_mem = &m_maincpu->space(AS_PROGRAM); - m_cyl[0] = m_cyl[1] = 0; - m_lba[0] = m_lba[1] = 0; - m_idcompare[0] = m_idcompare[1] = m_idcompare[2] = m_idcompare[3] = 0; - m_index = 10; - m_idfound = false; - m_drive = 0; - m_head = 0; - m_stepdir = false; - m_step = false; - m_format = false; - m_wrgate = false; - m_rdgate = false; - m_format_bytes = 0; - m_out_irq_func.resolve_safe(); - -} - -WRITE8_MEMBER(isbc_215g_device::write) -{ - if(!offset) - { - data &= 3; - if(!data && (m_reset == 2)) - m_dmac->reset(); - m_out_irq_func(0); - m_dmac->ca_w(data == 1); - m_dmac->ca_w(0); - m_reset = data; - } -} |