Compare commits

...

2 commits

Author SHA1 Message Date
Keir Fraser
33ce100bca tweaks 2023-09-17 13:35:14 +01:00
Eric Anderson
7fed26da99 img: Stream writes to flash
This starts writes for larger sector sizes earlier, allowing large
sectors to be supported independent of the write_bc size.
It also allows some write latencies to be hidden by the time it takes to
receive the data.

This also makes better use of write_bc for buffering. Waiting for a full
sector means that space in write_bc is _not_ used for buffering
processing delays of the sector. Draining the sector data earlier frees
space earlier from the buffer.
2023-09-17 13:16:13 +01:00

View file

@ -1876,15 +1876,17 @@ static void raw_setup_track(
im->cur_ticks = im->cur_bc * im->ticks_per_cell;
im->ticks_since_flux = 0;
decode_off = calc_start_pos(im);
rd->prod = rd->cons = 0;
bc->prod = bc->cons = 0;
if (start_pos) {
decode_off = calc_start_pos(im);
image_read_track(im);
bc->cons = decode_off * 16;
*start_pos = start_ticks;
} else {
im->img.decode_pos = 0;
}
}
@ -1963,8 +1965,8 @@ static bool_t raw_write_track(struct image *im)
struct raw_sec *sec;
unsigned int i, off;
time_t t;
uint16_t crc;
uint8_t idam_r, x;
uint16_t crc = im->img.crc;
uint8_t idam_r;
/* If we are processing final data then use the end index, rounded up. */
barrier();
@ -1974,7 +1976,9 @@ static bool_t raw_write_track(struct image *im)
while ((int16_t)(p - c) > 128) {
uint32_t sc = c;
if (im->img.decode_pos == 0) {
uint8_t x;
if (im->sync == SYNC_fm) {
@ -2030,13 +2034,25 @@ static bool_t raw_write_track(struct image *im)
}
break;
case 0xfb: /* DAM */ {
unsigned int nr, todo, sec_sz;
case 0xfb: /* DAM */
im->img.decode_pos = 1;
im->img.decode_data_pos = 0;
break;
}
} else {
/* Data record, shy address mark */
unsigned int sec_sz;
int sec_nr = im->img.write_sector;
ASSERT(im->img.decode_pos == 1);
if (sec_nr < 0) {
if (sec_nr == -1)
if (sec_nr == -1) {
sec_nr = raw_find_first_write_sector(im, write, trk);
im->img.write_sector = sec_nr;
}
if (sec_nr < 0) {
log("DAM Unknown\n");
goto dam_out;
@ -2044,40 +2060,54 @@ static bool_t raw_write_track(struct image *im)
}
sec_sz = sec_sz(im->img.sec_info[sec_nr].n);
if ((int16_t)(p - c) < (sec_sz + 2)) {
c = sc;
goto out;
}
crc = (im->sync == SYNC_fm) ? FM_DAM_CRC : MFM_DAM_CRC;
sec = &im->img.sec_info[sec_nr];
log("Write %u[%02x]/%u... ", sec_nr, sec->r, trk->nr_sectors);
t = time_now();
if (im->img.file_sec_offsets) {
off = im->img.file_sec_offsets[sec_nr];
} else if (trk->img_bps != 0) {
off = sec_nr * trk->img_bps;
} else {
off = 0;
sec = im->img.sec_info;
for (i = 0; i < sec_nr; i++)
for (i = off = 0; i < sec_nr; i++)
off += sec_sz(sec++->n);
}
F_lseek(&im->fp, im->img.trk_off + off);
off += im->img.trk_off;
off += im->img.decode_data_pos;
for (todo = sec_sz; todo != 0; todo -= nr) {
nr = min_t(unsigned int, todo, CHUNK_SIZE);
if (im->img.decode_data_pos < sec_sz) {
unsigned int nr;
nr = sec_sz - im->img.decode_data_pos;
nr = min_t(unsigned int, nr, CHUNK_SIZE - (off & 511)); /* XXX */
if (p - c < nr)
break;
if (!im->img.decode_data_pos) {
crc = (im->sync == SYNC_fm) ? FM_DAM_CRC : MFM_DAM_CRC;
log("Write %u[%02x]/%u...",
sec_nr, sec->r, trk->nr_sectors);
F_lseek(&im->fp, off);
}
t = time_now();
mfm_ring_to_bin(buf, bufmask, c, wrbuf, nr);
c += nr;
crc = crc16_ccitt(wrbuf, nr, crc);
process_data(im, wrbuf, nr);
F_write(&im->fp, wrbuf, nr, NULL);
printk(" %u us", time_diff(t, time_now()) / TIME_MHZ);
im->img.decode_data_pos += nr;
if (im->img.decode_data_pos < sec_sz)
printk("...");
else
printk("\n");
}
printk("%u us\n", time_diff(t, time_now()) / TIME_MHZ);
if (im->img.decode_data_pos < sec_sz)
continue;
if (p - c < 2)
break;
mfm_ring_to_bin(buf, bufmask, c, wrbuf, 2);
c += 2;
crc = crc16_ccitt(wrbuf, 2, crc);
@ -2087,13 +2117,12 @@ static bool_t raw_write_track(struct image *im)
dam_out:
im->img.write_sector = -2;
break;
}
im->img.decode_pos = 0;
}
}
out:
im->img.crc = crc;
wr->cons = c * 16;
return flush;
}