Skip to content

Commit 248fffb

Browse files
committed
imagedev/floppy: batch sequential flux writes
Some floppy controllers commit generated write flux in very small spans. This is especially visible while formatting, where a controller can emit a full track byte-by-byte and each byte-level commit previously edited the persistent track vector immediately. That turns one logical sequential track write into thousands of repeated track scans and insertions, making format operations orders of magnitude slower than the emulated disk timing. Keep the existing write path semantics by delaying only contiguous writes to the same cylinder, side and subcylinder. The accumulated span is flushed before any operation that can observe or depend on committed media state, including cache fills, write-splice updates and image commit. Non-contiguous writes or writes to another track also flush first, so existing callers that issue isolated writes continue to take the same path with no behavioral change beyond avoiding redundant intermediate vector edits. The pending span stores the original start/end positions and concatenated flux-change positions, then reuses the existing wspan_remove_damaged and wspan_write helpers when flushed. This preserves the existing damaged-region handling and track modification logic while making sequential write streams behave like the single larger write they represent.
1 parent 4810ca9 commit 248fffb

2 files changed

Lines changed: 48 additions & 1 deletion

File tree

src/devices/imagedev/floppy.cpp

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,12 @@ floppy_image_device::floppy_image_device(const machine_config &mconfig, device_t
293293
m_amplifier_freakout_time(attotime::from_usec(16)),
294294
m_image_dirty(false),
295295
m_track_dirty(false),
296+
m_pending_write(false),
297+
m_pending_write_cyl(0),
298+
m_pending_write_ss(0),
299+
m_pending_write_subcyl(0),
300+
m_pending_write_start(0),
301+
m_pending_write_end(0),
296302
m_ready_counter(0),
297303
m_make_sound(false),
298304
m_sound_out(*this, FLOPSND_TAG)
@@ -498,6 +504,7 @@ void floppy_image_device::setup_write(const floppy_image_format_t *_output_forma
498504

499505
void floppy_image_device::commit_image()
500506
{
507+
flush_pending_write();
501508
m_image_dirty = false;
502509
if(!m_output_format || !m_output_format->supports_save())
503510
return;
@@ -649,6 +656,8 @@ std::pair<std::error_condition, const floppy_image_format_t *> floppy_image_devi
649656
void floppy_image_device::init_floppy_load(bool write_supported)
650657
{
651658
cache_clear();
659+
m_pending_write = false;
660+
m_pending_write_flux_change_positions.clear();
652661
m_revolution_start_time = m_mon ? attotime::never : machine().time();
653662
m_revolution_count = 0;
654663

@@ -1125,6 +1134,7 @@ void floppy_image_device::cache_clear()
11251134

11261135
void floppy_image_device::cache_fill(const attotime &when)
11271136
{
1137+
flush_pending_write();
11281138
std::vector<uint32_t> &buf = m_image->get_buffer(m_cyl, m_ss, m_subcyl);
11291139
uint32_t const cells = buf.size();
11301140
if(cells <= 1) {
@@ -1234,8 +1244,38 @@ void floppy_image_device::write_flux(const attotime &start, const attotime &end,
12341244

12351245
wspan_split_on_wrap(wspans);
12361246

1237-
std::vector<uint32_t> &buf = m_image->get_buffer(m_cyl, m_ss, m_subcyl);
1247+
for(const auto &ws : wspans) {
1248+
if(!m_pending_write || m_pending_write_cyl != m_cyl || m_pending_write_ss != m_ss || m_pending_write_subcyl != m_subcyl || m_pending_write_end != ws.start) {
1249+
flush_pending_write();
1250+
m_pending_write = true;
1251+
m_pending_write_cyl = m_cyl;
1252+
m_pending_write_ss = m_ss;
1253+
m_pending_write_subcyl = m_subcyl;
1254+
m_pending_write_start = ws.start;
1255+
m_pending_write_end = ws.start;
1256+
m_pending_write_flux_change_positions.clear();
1257+
}
1258+
1259+
m_pending_write_end = ws.end;
1260+
m_pending_write_flux_change_positions.insert(
1261+
m_pending_write_flux_change_positions.end(),
1262+
ws.flux_change_positions.begin(),
1263+
ws.flux_change_positions.end());
1264+
}
1265+
}
1266+
1267+
1268+
void floppy_image_device::flush_pending_write()
1269+
{
1270+
if(!m_pending_write)
1271+
return;
1272+
1273+
std::vector<wspan> wspans(1);
1274+
wspans[0].start = m_pending_write_start;
1275+
wspans[0].end = m_pending_write_end;
1276+
wspans[0].flux_change_positions.swap(m_pending_write_flux_change_positions);
12381277

1278+
std::vector<uint32_t> &buf = m_image->get_buffer(m_pending_write_cyl, m_pending_write_ss, m_pending_write_subcyl);
12391279
if(buf.empty()) {
12401280
buf.push_back(floppy_image::MG_N);
12411281
buf.push_back(floppy_image::MG_E | 199999999);
@@ -1244,6 +1284,7 @@ void floppy_image_device::write_flux(const attotime &start, const attotime &end,
12441284
wspan_remove_damaged(wspans, buf);
12451285
wspan_write(wspans, buf);
12461286

1287+
m_pending_write = false;
12471288
cache_clear();
12481289
}
12491290

@@ -1370,6 +1411,7 @@ void floppy_image_device::wspan_write(const std::vector<wspan> &wspans, std::vec
13701411
void floppy_image_device::set_write_splice(const attotime &when)
13711412
{
13721413
if(m_image && !m_mon) {
1414+
flush_pending_write();
13731415
m_image_dirty = true;
13741416
attotime base;
13751417
int splice_pos = find_position(base, when);

src/devices/imagedev/floppy.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ class floppy_image_device : public device_t,
231231
bool m_cache_weak;
232232

233233
bool m_image_dirty, m_track_dirty;
234+
bool m_pending_write;
235+
int m_pending_write_cyl, m_pending_write_ss, m_pending_write_subcyl;
236+
int m_pending_write_start, m_pending_write_end;
237+
std::vector<int> m_pending_write_flux_change_positions;
234238
int m_ready_counter;
235239

236240
load_cb m_cur_load_cb;
@@ -260,6 +264,7 @@ class floppy_image_device : public device_t,
260264
attotime position_to_time(const attotime &base, int position) const;
261265

262266
void commit_image();
267+
void flush_pending_write();
263268

264269
u32 hash32(u32 val) const;
265270

0 commit comments

Comments
 (0)