summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/isbc_215g.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/machine/isbc_215g.cpp')
-rw-r--r--src/mame/machine/isbc_215g.cpp434
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 6b00e9eabfc..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;
-}
-
-uint16_t isbc_215g_device::io_r(offs_t offset)
-{
- 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;
-}
-
-void isbc_215g_device::io_w(offs_t offset, uint16_t data)
-{
- 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;
- }
-}
-
-uint16_t isbc_215g_device::mem_r(offs_t offset, uint16_t mem_mask)
-{
- // 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);
- }
-}
-
-void isbc_215g_device::mem_w(offs_t offset, uint16_t data, uint16_t mem_mask)
-{
- 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_REGION16_LE( 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();
-
-}
-
-void isbc_215g_device::write(offs_t offset, uint8_t data)
-{
- 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;
- }
-}