diff options
Diffstat (limited to 'src/devices/bus/vtech/memexp/floppy.cpp')
-rw-r--r-- | src/devices/bus/vtech/memexp/floppy.cpp | 141 |
1 files changed, 85 insertions, 56 deletions
diff --git a/src/devices/bus/vtech/memexp/floppy.cpp b/src/devices/bus/vtech/memexp/floppy.cpp index 5807588ec27..7fdfd30a65a 100644 --- a/src/devices/bus/vtech/memexp/floppy.cpp +++ b/src/devices/bus/vtech/memexp/floppy.cpp @@ -12,6 +12,11 @@ #include "emu.h" #include "floppy.h" +#include "formats/fs_vtech.h" +#include "formats/vt_dsk.h" + +#include <algorithm> + //************************************************************************** // DEVICE DEFINITIONS @@ -19,12 +24,27 @@ DEFINE_DEVICE_TYPE(VTECH_FLOPPY_CONTROLLER, vtech_floppy_controller_device, "vtech_fdc", "Laser/VZ Floppy Disk Controller") -void vtech_floppy_controller_device::map(address_map &map) +//------------------------------------------------- +// mem_map - memory space address map +//------------------------------------------------- + +void vtech_floppy_controller_device::mem_map(address_map &map) { - map(0, 0).w(FUNC(vtech_floppy_controller_device::latch_w)); - map(1, 1).r(FUNC(vtech_floppy_controller_device::shifter_r)); - map(2, 2).r(FUNC(vtech_floppy_controller_device::rd_r)); - map(3, 3).r(FUNC(vtech_floppy_controller_device::wpt_r)); + map.unmap_value_high(); + map(0x4000, 0x5fff).rom().region("software", 0); +} + +//------------------------------------------------- +// io_map - io space address map +//------------------------------------------------- + +void vtech_floppy_controller_device::io_map(address_map &map) +{ + map.unmap_value_high(); + map(0x10, 0x10).w(FUNC(vtech_floppy_controller_device::latch_w)); + map(0x11, 0x11).r(FUNC(vtech_floppy_controller_device::shifter_r)); + map(0x12, 0x12).r(FUNC(vtech_floppy_controller_device::rd_r)); + map(0x13, 0x13).r(FUNC(vtech_floppy_controller_device::wpt_r)); } //------------------------------------------------- @@ -32,7 +52,7 @@ void vtech_floppy_controller_device::map(address_map &map) //------------------------------------------------- ROM_START( floppy ) - ROM_REGION(0x3000, "software", 0) + ROM_REGION(0x2000, "software", 0) ROM_LOAD("vzdos.rom", 0x0000, 0x2000, CRC(b6ed6084) SHA1(59d1cbcfa6c5e1906a32704fbf0d9670f0d1fd8b)) ROM_END @@ -47,14 +67,26 @@ const tiny_rom_entry *vtech_floppy_controller_device::device_rom_region() const static void laser_floppies(device_slot_interface &device) { - device.option_add("525", FLOPPY_525_SSSD); + device.option_add("525", FLOPPY_525_VTECH); +} + +void vtech_floppy_controller_device::floppy_formats(format_registration &fr) +{ + fr.add(FLOPPY_VTECH_BIN_FORMAT); + fr.add(FLOPPY_VTECH_DSK_FORMAT); + fr.add(fs::VTECH); } void vtech_floppy_controller_device::device_add_mconfig(machine_config &config) { + vtech_memexp_device::device_add_mconfig(config); + VTECH_MEMEXP_SLOT(config, m_memexp); - FLOPPY_CONNECTOR(config, m_floppy0, laser_floppies, "525", floppy_image_device::default_floppy_formats); - FLOPPY_CONNECTOR(config, m_floppy1, laser_floppies, "525", floppy_image_device::default_floppy_formats); + m_memexp->set_memspace(m_mem, AS_PROGRAM); + m_memexp->set_iospace(m_io, AS_PROGRAM); + + for (auto &floppy : m_floppy) + FLOPPY_CONNECTOR(config, floppy, laser_floppies, "525", floppy_formats); } @@ -67,12 +99,10 @@ void vtech_floppy_controller_device::device_add_mconfig(machine_config &config) //------------------------------------------------- vtech_floppy_controller_device::vtech_floppy_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - device_t(mconfig, VTECH_FLOPPY_CONTROLLER, tag, owner, clock), - device_vtech_memexp_interface(mconfig, *this), + vtech_memexp_device(mconfig, VTECH_FLOPPY_CONTROLLER, tag, owner, clock), m_memexp(*this, "mem"), - m_floppy0(*this, "0"), - m_floppy1(*this, "1"), - m_floppy(nullptr), m_latch(0), m_shifter(0), m_latching_inverter(false), m_current_cyl(0), m_write_position(0) + m_floppy(*this, "%u", 0U), + m_selected_floppy(nullptr), m_latch(0), m_shifter(0), m_latching_inverter(false), m_current_cyl(0), m_write_position(0) { } @@ -82,6 +112,9 @@ vtech_floppy_controller_device::vtech_floppy_controller_device(const machine_con void vtech_floppy_controller_device::device_start() { + vtech_memexp_device::device_start(); + + // register for save states save_item(NAME(m_latch)); save_item(NAME(m_shifter)); save_item(NAME(m_latching_inverter)); @@ -90,15 +123,13 @@ void vtech_floppy_controller_device::device_start() save_item(NAME(m_write_start_time)); save_item(NAME(m_write_position)); - // TODO: save m_write_buffer and rebuild m_floppy after load - - uint8_t *bios = memregion("software")->base(); + // TODO: save m_write_buffer and rebuild m_selected_floppy after load // Obvious bugs... must have worked by sheer luck and very subtle // timings. Our current z80 is not subtle enough. - - bios[0x1678] = 0x75; - bios[0x1688] = 0x85; + uint8_t *rom = memregion("software")->base(); + rom[0x1678] = 0x75; + rom[0x1688] = 0x85; } //------------------------------------------------- @@ -107,19 +138,15 @@ void vtech_floppy_controller_device::device_start() void vtech_floppy_controller_device::device_reset() { - program_space().install_rom(0x4000, 0x5fff, memregion("software")->base()); - - io_space().install_device(0x10, 0x1f, *this, &vtech_floppy_controller_device::map); - m_latch = 0x00; - m_floppy = nullptr; + m_selected_floppy = nullptr; m_current_cyl = 0; m_shifter = 0x00; m_latching_inverter = false; m_last_latching_inverter_update_time = machine().time(); m_write_start_time = attotime::never; m_write_position = 0; - memset(m_write_buffer, 0, sizeof(m_write_buffer)); + std::fill(std::begin(m_write_buffer), std::end(m_write_buffer), attotime::zero); } @@ -133,34 +160,33 @@ void vtech_floppy_controller_device::device_reset() // bit 6: !write request // bits 4,7: floppy select -WRITE8_MEMBER(vtech_floppy_controller_device::latch_w) +void vtech_floppy_controller_device::latch_w(uint8_t data) { uint8_t diff = m_latch ^ data; m_latch = data; floppy_image_device *newflop = nullptr; if(m_latch & 0x10) - newflop = m_floppy0->get_device(); + newflop = m_floppy[0]->get_device(); else if(m_latch & 0x80) - newflop = m_floppy1->get_device(); + newflop = m_floppy[1]->get_device(); - if(newflop != m_floppy) { + if(newflop != m_selected_floppy) { update_latching_inverter(); flush_writes(); - if(m_floppy) { - m_floppy->mon_w(1); - m_floppy->setup_index_pulse_cb(floppy_image_device::index_pulse_cb()); + if(m_selected_floppy) { + m_selected_floppy->mon_w(1); + m_selected_floppy->setup_index_pulse_cb(floppy_image_device::index_pulse_cb()); } if(newflop) { - newflop->set_rpm(85); newflop->mon_w(0); newflop->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(&vtech_floppy_controller_device::index_callback, this)); m_current_cyl = newflop->get_cyl() << 1; } - m_floppy = newflop; + m_selected_floppy = newflop; } - if(m_floppy) { + if(m_selected_floppy) { int cph = m_current_cyl & 3; int pcyl = m_current_cyl; if(!(m_latch & (1 << cph))) { @@ -169,10 +195,10 @@ WRITE8_MEMBER(vtech_floppy_controller_device::latch_w) if(m_current_cyl && (m_latch & (1 << ((cph+3) & 3)))) m_current_cyl--; if(m_current_cyl != pcyl && !(m_current_cyl & 1)) { - m_floppy->dir_w(m_current_cyl < pcyl); - m_floppy->stp_w(true); - m_floppy->stp_w(false); - m_floppy->stp_w(true); + m_selected_floppy->dir_w(m_current_cyl < pcyl); + m_selected_floppy->stp_w(true); + m_selected_floppy->stp_w(false); + m_selected_floppy->stp_w(true); } } } @@ -181,8 +207,8 @@ WRITE8_MEMBER(vtech_floppy_controller_device::latch_w) if(!(m_latch & 0x40)) { m_write_start_time = machine().time(); m_write_position = 0; - if(m_floppy) - m_floppy->set_write_splice(m_write_start_time); + if(m_selected_floppy) + m_selected_floppy->set_write_splice(m_write_start_time); } else { update_latching_inverter(); @@ -191,7 +217,7 @@ WRITE8_MEMBER(vtech_floppy_controller_device::latch_w) } } if(!(m_latch & 0x40) && (diff & 0x20)) { - if(m_write_position == ARRAY_LENGTH(m_write_buffer)) { + if(m_write_position == std::size(m_write_buffer)) { update_latching_inverter(); flush_writes(true); } @@ -209,17 +235,20 @@ WRITE8_MEMBER(vtech_floppy_controller_device::latch_w) // - the inverted inverter output is shifted through the lsb of the shift register // - the inverter is cleared -READ8_MEMBER(vtech_floppy_controller_device::shifter_r) +uint8_t vtech_floppy_controller_device::shifter_r() { - update_latching_inverter(); - m_shifter = (m_shifter << 1) | !m_latching_inverter; - m_latching_inverter = false; + if (!machine().side_effects_disabled()) + { + update_latching_inverter(); + m_shifter = (m_shifter << 1) | !m_latching_inverter; + m_latching_inverter = false; + } return m_shifter; } // Linked to the latching inverter on bit 7, rest is floating -READ8_MEMBER(vtech_floppy_controller_device::rd_r) +uint8_t vtech_floppy_controller_device::rd_r() { update_latching_inverter(); return m_latching_inverter ? 0x80 : 0x00; @@ -227,22 +256,22 @@ READ8_MEMBER(vtech_floppy_controller_device::rd_r) // Linked to wp signal on bit 7, rest is floating -READ8_MEMBER(vtech_floppy_controller_device::wpt_r) +uint8_t vtech_floppy_controller_device::wpt_r() { - return m_floppy && m_floppy->wpt_r() ? 0x80 : 0x00; + return m_selected_floppy && m_selected_floppy->wpt_r() ? 0x80 : 0x00; } void vtech_floppy_controller_device::update_latching_inverter() { attotime now = machine().time(); - if(!m_floppy) { + if(!m_selected_floppy) { m_last_latching_inverter_update_time = now; return; } attotime when = m_last_latching_inverter_update_time; for(;;) { - when = m_floppy->get_next_transition(when); + when = m_selected_floppy->get_next_transition(when); if(when == attotime::never || when > now) break; m_latching_inverter = !m_latching_inverter; @@ -258,7 +287,7 @@ void vtech_floppy_controller_device::index_callback(floppy_image_device *floppy, void vtech_floppy_controller_device::flush_writes(bool keep_margin) { - if(!m_floppy || m_write_start_time == attotime::never) + if(!m_selected_floppy || m_write_start_time == attotime::never) return; // Beware of time travel. Index pulse callback (which flushes) @@ -283,13 +312,13 @@ void vtech_floppy_controller_device::flush_writes(bool keep_margin) m_write_position -= kept_count; if(m_write_position && m_write_buffer[0] == m_write_start_time) { if(m_write_position) - memmove(m_write_buffer, m_write_buffer+1, sizeof(m_write_buffer[0])*(m_write_position-1)); + std::copy_n(m_write_buffer + 1, m_write_position - 1, m_write_buffer); m_write_position--; } - m_floppy->write_flux(m_write_start_time, limit, m_write_position, m_write_buffer); + m_selected_floppy->write_flux(m_write_start_time, limit, m_write_position, m_write_buffer); m_write_start_time = limit; if(kept_count != 0) - memmove(m_write_buffer, m_write_buffer+kept_pos, kept_count*sizeof(m_write_buffer[0])); + std::copy_n(m_write_buffer + kept_pos, kept_count, m_write_buffer); m_write_position = kept_count; } |