summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/s100/vectordualmode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/s100/vectordualmode.cpp')
-rw-r--r--src/devices/bus/s100/vectordualmode.cpp81
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")