summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/vtech/memexp/floppy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/vtech/memexp/floppy.cpp')
-rw-r--r--src/devices/bus/vtech/memexp/floppy.cpp141
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;
}