diff options
Diffstat (limited to 'src/devices/bus/s100/vectordualmode.cpp')
-rw-r--r-- | src/devices/bus/s100/vectordualmode.cpp | 81 |
1 files changed, 56 insertions, 25 deletions
diff --git a/src/devices/bus/s100/vectordualmode.cpp b/src/devices/bus/s100/vectordualmode.cpp index c1aec1d746a..fbf66d0d06e 100644 --- a/src/devices/bus/s100/vectordualmode.cpp +++ b/src/devices/bus/s100/vectordualmode.cpp @@ -65,10 +65,12 @@ s100_vector_dualmode_device::s100_vector_dualmode_device(const machine_config &m , m_cmar(0) , m_drive(0) , m_sector(0) + , m_fdd_sector_counter(0xf) , m_read(false) + , m_busy(false) + , m_last_sector_pulse(attotime::zero) , m_pll() , m_byte_timer(nullptr) - , m_sector_timer(nullptr) , m_pending_byte(0) , m_pending_size(0) { @@ -81,6 +83,8 @@ TIMER_CALLBACK_MEMBER(s100_vector_dualmode_device::motor_off) if (flop) flop->mon_w(1); } + m_byte_timer->enable(false); + m_busy = false; } bool s100_vector_dualmode_device::hdd_selected() @@ -91,6 +95,8 @@ bool s100_vector_dualmode_device::hdd_selected() uint8_t s100_vector_dualmode_device::s100_sinp_r(offs_t offset) { + if (m_busy) + return 0xff; // 7200-1200-02-1 page 16 (1-10) uint8_t data; if (offset == 0xc0) { // status (0) port @@ -124,7 +130,7 @@ uint8_t s100_vector_dualmode_device::s100_sinp_r(offs_t offset) | 0xc0; } else if (offset == 0xc1) { // status (1) port bool floppy_disk_selected; - bool controller_busy = m_sector_timer->enabled(); + bool controller_busy = m_busy; // returned early if true bool motor_on; // FDD bool type_of_hard_disk = true; if (hdd_selected()) { @@ -157,10 +163,8 @@ uint8_t s100_vector_dualmode_device::s100_sinp_r(offs_t offset) void s100_vector_dualmode_device::s100_sout_w(offs_t offset, uint8_t data) { - // TODO: check actual behavior when controller is busy - if (m_sector_timer->enabled()) { + if (m_busy) return; - } // 7200-1200-02-1 page 14 (1-8) if (offset == 0xc0) { // control (0) port m_drive = BIT(data, 0, 2); @@ -183,6 +187,7 @@ void s100_vector_dualmode_device::s100_sout_w(offs_t offset, uint8_t data) // Software should not change other bits when pulsing step flop->stp_w(!step); flop->dir_w(!step_in); + flop->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(&s100_vector_dualmode_device::floppy_index_cb, this)); } } else if (offset == 0xc1) { // control (1) port m_sector = BIT(data, 0, 5); @@ -191,14 +196,7 @@ void s100_vector_dualmode_device::s100_sout_w(offs_t offset, uint8_t data) m_ram[m_cmar++] = data; m_cmar &= 0x1ff; } else if (offset == 0xc3) { // start port - floppy_image_device* flop = m_floppy[m_drive]->get_device(); - if (!flop || flop->time_next_index().is_never()) - return; - const attotime rot_time = attotime::from_msec(200); - attotime sector_time = flop->time_next_index() - machine().time() + (rot_time / 16) * m_sector; - if (sector_time > rot_time) - sector_time -= rot_time; - m_sector_timer->adjust(sector_time, SECTOR_START); + m_busy = m_motor_on_timer->enabled(); } } @@ -213,10 +211,40 @@ bool s100_vector_dualmode_device::get_next_bit(attotime &tm, const attotime &lim return true; } -TIMER_CALLBACK_MEMBER(s100_vector_dualmode_device::sector_cb) +void s100_vector_dualmode_device::floppy_index_cb(floppy_image_device *floppy, int state) +{ + if (hdd_selected() || m_floppy[m_drive]->get_device() != floppy) + return; + if (!state) + return; + attotime now = machine().time(); + // U25 74LS221: 61.9 KOhm * .22 uF * .75 + if (now - m_last_sector_pulse < attotime::from_nsec(10213500)) { + m_fdd_sector_counter = 0xf; + } else { + m_last_sector_pulse = now; + m_fdd_sector_counter++; + m_fdd_sector_counter &= 0xf; + start_of_sector(); + } +} + +void s100_vector_dualmode_device::start_of_sector() { - switch (param) { - case SECTOR_START: + if (!m_busy) + return; + + if (m_byte_timer->enabled()) { + // op completed + m_byte_timer->enable(false); + m_busy = false; + if (m_read) + m_ram[274] = 0; // Ignore ECC + return; + } + + uint8_t cur_sector = m_fdd_sector_counter; + if (cur_sector == m_sector) { if (m_read) { m_pll.set_clock(half_bitcell_size); m_pll.read_reset(machine().time()); @@ -233,14 +261,6 @@ TIMER_CALLBACK_MEMBER(s100_vector_dualmode_device::sector_cb) m_pending_size = 0; m_byte_timer->adjust(attotime::zero); } - m_sector_timer->adjust(attotime::from_msec(200)/16, SECTOR_END); - break; - - case SECTOR_END: - m_byte_timer->enable(false); - if (m_read) - m_ram[274] = 0; // Ignore ECC - break; } } @@ -282,13 +302,20 @@ void s100_vector_dualmode_device::device_start() { m_motor_on_timer = timer_alloc(FUNC(s100_vector_dualmode_device::motor_off), this); m_byte_timer = timer_alloc(FUNC(s100_vector_dualmode_device::byte_cb), this); - m_sector_timer = timer_alloc(FUNC(s100_vector_dualmode_device::sector_cb), this); + + for (auto& f : m_floppy) { + if (f->get_device()) + f->get_device()->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(&s100_vector_dualmode_device::floppy_index_cb, this)); + } save_item(NAME(m_ram)); save_item(NAME(m_cmar)); save_item(NAME(m_drive)); save_item(NAME(m_sector)); + save_item(NAME(m_fdd_sector_counter)); save_item(NAME(m_read)); + save_item(NAME(m_busy)); + save_item(NAME(m_last_sector_pulse)); save_item(NAME(m_pending_byte)); save_item(NAME(m_pending_size)); } @@ -319,9 +346,13 @@ static void vector4_formats(format_registration &fr) void s100_vector_dualmode_device::device_add_mconfig(machine_config &config) { FLOPPY_CONNECTOR(config, m_floppy[0], vector4_floppies, "525", vector4_formats).enable_sound(true); + m_floppy[0]->set_sectoring_type(floppy_image::H16); FLOPPY_CONNECTOR(config, m_floppy[1], vector4_floppies, "525", vector4_formats).enable_sound(true); + m_floppy[1]->set_sectoring_type(floppy_image::H16); FLOPPY_CONNECTOR(config, m_floppy[2], vector4_floppies, "525", vector4_formats).enable_sound(true); + m_floppy[2]->set_sectoring_type(floppy_image::H16); FLOPPY_CONNECTOR(config, m_floppy[3], vector4_floppies, "525", vector4_formats).enable_sound(true); + m_floppy[3]->set_sectoring_type(floppy_image::H16); } DEFINE_DEVICE_TYPE(S100_VECTOR_DUALMODE, s100_vector_dualmode_device, "vectordualmode", "Vector Dual-Mode Disk Controller") |