New turbo floppy poller, should be a bit faster than before.

This commit is contained in:
OBattler
2017-07-26 00:16:54 +02:00
parent 562a138ec8
commit 02f5d663d0
10 changed files with 382 additions and 8 deletions

View File

@@ -194,11 +194,6 @@ double disc_byteperiod(int drive)
if (drives[drive].byteperiod)
{
if (fdd_get_turbo(drive))
{
return 1.0;
}
return drives[drive].byteperiod(drive);
}
else
@@ -217,7 +212,12 @@ double disc_real_period(int drive)
dusec = (double) TIMER_USEC;
/* This is a giant hack but until the timings become even more correct, this is needed to make floppies work right on that BIOS. */
if ((romset == ROM_MRTHOR) && !fdd_get_turbo(drive))
if (fdd_get_turbo(drive))
{
return (32.0 * dusec);
}
if (romset == ROM_MRTHOR)
{
return (ddbp * dusec) / 4.0;
}

View File

@@ -231,5 +231,10 @@ typedef union
sector_id_fields_t id;
} sector_id_t;
void d86f_set_version(int drive, uint16_t version);
void d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n);
void d86f_zero_bit_field(int drive, int side);
#endif /*EMU_DISC_H*/

View File

@@ -35,8 +35,6 @@
#include "fdd.h"
#include "ibm.h"
#define D86FVER 0x020B
#define CHUNK 16384
uint64_t poly = 0x42F0E1EBA9EA3693ll; /* ECMA normal */
@@ -252,6 +250,8 @@ struct __attribute__((__packed__))
uint8_t *filebuf;
uint8_t *outbuf;
uint32_t dma_over;
int turbo_pos;
uint16_t sector_id_bit_field[2][256][256][256];
} d86f[FDD_NUM];
#ifdef __MSC__
# pragma pack(pop)
@@ -273,6 +273,28 @@ void d86f_log(const char *format, ...)
#endif
}
void d86f_zero_bit_field(int drive, int side)
{
int i = 0;
int j = 0;
int k = 0;
int l = 0;
for (i = 0; i < side; i++)
{
for (j = 0; j < 256; j++)
{
for (k = 0; k < 256; k++)
{
for (l = 0; l < 256; l++)
{
d86f[drive].sector_id_bit_field[i][j][k][l] = 0;
}
}
}
}
}
static void d86f_setupcrc(uint16_t poly)
{
int c = 256, bc;
@@ -490,6 +512,11 @@ uint32_t common_get_raw_size(int drive, int side)
return ((((uint32_t) size) >> 4) << 4) + d86f_handler[drive].extra_bit_cells(drive, side);
}
void d86f_set_version(int drive, uint16_t version)
{
d86f[drive].version = version;
}
void d86f_unregister(int drive)
{
d86f_handler[drive].disk_flags = null_disk_flags;
@@ -1793,6 +1820,20 @@ void d86f_format_finish(int drive, int side, int mfm, uint16_t sc, uint16_t gap_
fdc_sector_finishread();
}
void d86f_format_turbo_finish(int drive, int side, int do_write)
{
d86f[drive].state = STATE_IDLE;
if (do_write)
{
d86f_handler[drive].writeback(drive);
}
d86f[drive].error_condition = 0;
d86f[drive].datac = 0;
fdc_sector_finishread();
}
void d86f_format_track(int drive, int side, int do_write)
{
int data;
@@ -2001,6 +2042,251 @@ void d86f_format_track_nop(int drive, int side)
d86f_format_track(drive, side, 0);
}
void d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n)
{
d86f[drive].last_sector.id.c = c;
d86f[drive].last_sector.id.h = h;
d86f[drive].last_sector.id.r = r;
d86f[drive].last_sector.id.n = n;
}
void d86f_turbo_read(int drive, int side)
{
uint8_t dat = 0;
int recv_data = 0;
int read_status = 0;
dat = d86f_handler[drive].read_data(drive, side, d86f[drive].turbo_pos);
d86f[drive].turbo_pos++;
if (d86f[drive].state == STATE_11_SCAN_DATA)
{
/* Scan/compare command. */
recv_data = d86f_get_data(drive, 0);
d86f_compare_byte(drive, recv_data, dat);
}
else
{
if (d86f[drive].data_find.bytes_obtained < (128 << d86f[drive].last_sector.id.n))
{
if (d86f[drive].state != STATE_16_VERIFY_DATA)
{
read_status = fdc_data(dat);
if (read_status == -1)
{
d86f[drive].dma_over++;
}
}
}
}
if (d86f[drive].dma_over > 1)
{
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
d86f[drive].error_condition = 0;
d86f[drive].state = STATE_IDLE;
fdc_finishread();
fdc_overrun();
return;
}
if (d86f[drive].turbo_pos >= (128 << d86f[drive].last_sector.id.n))
{
/* CRC is valid. */
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
d86f[drive].error_condition = 0;
if (d86f[drive].state == STATE_11_SCAN_DATA)
{
d86f[drive].state = STATE_IDLE;
fdc_sector_finishcompare((d86f[drive].satisfying_bytes == ((128 << ((uint32_t) d86f[drive].last_sector.id.n)) - 1)) ? 1 : 0);
}
else
{
d86f[drive].state = STATE_IDLE;
fdc_sector_finishread();
}
}
}
void d86f_turbo_write(int drive, int side)
{
uint8_t dat = 0;
dat = d86f_get_data(drive, 1);
d86f_handler[drive].write_data(drive, side, d86f[drive].turbo_pos, dat);
d86f[drive].turbo_pos++;
if (d86f[drive].turbo_pos >= (128 << d86f[drive].last_sector.id.n))
{
/* We've written the data. */
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
d86f[drive].error_condition = 0;
d86f[drive].state = STATE_IDLE;
d86f_handler[drive].writeback(drive);
fdc_sector_finishread();
return;
}
}
void d86f_turbo_format(int drive, int side, int nop)
{
int dat;
int i = 0;
uint16_t sc = 0;
uint16_t dtl = 0;
sc = fdc_get_format_sectors();
dtl = 128 << fdc_get_format_n();
if (d86f[drive].datac <= 3)
{
dat = fdc_getdata(0);
if (dat != -1)
{
dat &= 0xff;
}
if ((dat == -1) && (d86f[drive].datac < 3))
{
dat = 0;
}
d86f[drive].format_sector_id.byte_array[d86f[drive].datac] = dat & 0xff;
if (d86f[drive].datac == 3)
{
fdc_stop_id_request();
d86f_handler[drive].set_sector(drive, side, d86f[drive].format_sector_id.id.c, d86f[drive].format_sector_id.id.h, d86f[drive].format_sector_id.id.r, d86f[drive].format_sector_id.id.n);
}
}
else if (d86f[drive].datac == 4)
{
if (!nop)
{
for (i = 0; i < dtl; i++)
{
d86f_handler[drive].write_data(drive, side, i, d86f[drive].fill);
}
}
d86f[drive].sector_count++;
}
d86f[drive].datac++;
if (d86f[drive].datac == 6)
{
d86f[drive].datac = 0;
if (d86f[drive].sector_count < sc)
{
/* Sector within allotted amount. */
fdc_request_next_sector_id();
}
else
{
d86f[drive].state = STATE_IDLE;
d86f_format_turbo_finish(drive, side, nop);
}
}
}
void d86f_turbo_poll(int drive, int side)
{
switch(d86f[drive].state)
{
case STATE_0D_SPIN_TO_INDEX:
case STATE_0D_NOP_SPIN_TO_INDEX:
d86f[drive].sector_count = 0;
d86f[drive].datac = 5;
case STATE_02_SPIN_TO_INDEX:
d86f[drive].state++;
return;
case STATE_02_FIND_ID:
if (!(d86f[drive].sector_id_bit_field[side][fdc_get_read_track_sector().id.c][fdc_get_read_track_sector().id.h][fdc_get_read_track_sector().id.r] & (1 << fdc_get_read_track_sector().id.n)))
{
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0;
fdc_nosector();
d86f[drive].state = STATE_IDLE;
return;
}
d86f[drive].last_sector.id.c = fdc_get_read_track_sector().id.c;
d86f[drive].last_sector.id.h = fdc_get_read_track_sector().id.h;
d86f[drive].last_sector.id.r = fdc_get_read_track_sector().id.r;
d86f[drive].last_sector.id.n = fdc_get_read_track_sector().id.n;
d86f_handler[drive].set_sector(drive, side, d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n);
d86f[drive].turbo_pos = 0;
d86f[drive].state++;
return;
case STATE_05_FIND_ID:
case STATE_09_FIND_ID:
case STATE_06_FIND_ID:
case STATE_0C_FIND_ID:
case STATE_11_FIND_ID:
case STATE_16_FIND_ID:
if (!(d86f[drive].sector_id_bit_field[side][d86f[drive].req_sector.id.c][d86f[drive].req_sector.id.h][d86f[drive].req_sector.id.r] & (1 << d86f[drive].req_sector.id.n)))
{
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0;
fdc_nosector();
d86f[drive].state = STATE_IDLE;
return;
}
d86f[drive].last_sector.id.c = d86f[drive].req_sector.id.c;
d86f[drive].last_sector.id.h = d86f[drive].req_sector.id.h;
d86f[drive].last_sector.id.r = d86f[drive].req_sector.id.r;
d86f[drive].last_sector.id.n = d86f[drive].req_sector.id.n;
d86f_handler[drive].set_sector(drive, side, d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n);
case STATE_0A_FIND_ID:
d86f[drive].turbo_pos = 0;
d86f[drive].state++;
return;
case STATE_0A_READ_ID:
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0;
fdc_sectorid(d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n, 0, 0);
d86f[drive].state = STATE_IDLE;
break;
case STATE_02_READ_ID:
case STATE_05_READ_ID:
case STATE_09_READ_ID:
case STATE_06_READ_ID:
case STATE_0C_READ_ID:
case STATE_11_READ_ID:
case STATE_16_READ_ID:
d86f[drive].state++;
break;
case STATE_02_FIND_DATA:
case STATE_06_FIND_DATA:
case STATE_11_FIND_DATA:
case STATE_16_FIND_DATA:
case STATE_05_FIND_DATA:
case STATE_09_FIND_DATA:
case STATE_0C_FIND_DATA:
d86f[drive].state++;
break;
case STATE_02_READ_DATA:
case STATE_06_READ_DATA:
case STATE_0C_READ_DATA:
case STATE_11_SCAN_DATA:
case STATE_16_VERIFY_DATA:
d86f_turbo_read(drive, side);
break;
case STATE_05_WRITE_DATA:
case STATE_09_WRITE_DATA:
d86f_turbo_write(drive, side);
break;
case STATE_0D_FORMAT_TRACK:
d86f_turbo_format(drive, side, 0);
return;
case STATE_0D_NOP_FORMAT_TRACK:
d86f_turbo_format(drive, side, 1);
return;
case STATE_IDLE:
case STATE_SECTOR_NOT_FOUND:
default:
break;
}
}
void d86f_poll(int drive)
{
int side = 0;
@@ -2035,6 +2321,12 @@ void d86f_poll(int drive)
}
}
if (fdd_get_turbo(drive) && (d86f[drive].version == 0x0063))
{
d86f_turbo_poll(drive, side);
return;
}
if ((d86f[drive].state != STATE_02_SPIN_TO_INDEX) && (d86f[drive].state != STATE_0D_SPIN_TO_INDEX))
{
d86f_get_bit(drive, side ^ 1);
@@ -2337,6 +2629,8 @@ uint16_t d86f_prepare_sector(int drive, int side, int prev_pos, uint8_t *id_buf,
uint16_t dataam_mfm = 0x4555;
uint16_t datadam_mfm = 0x4A55;
d86f[drive].sector_id_bit_field[side][id_buf[0]][id_buf[1]][id_buf[2]] |= (1 << id_buf[3]);
mfm = d86f_is_mfm(drive);
gap_fill = mfm ? 0x4E : 0xFF;

View File

@@ -33,6 +33,7 @@ void d86f_readaddress(int drive, int side, int density);
void d86f_format(int drive, int side, int density, uint8_t fill);
void d86f_prepare_track_layout(int drive, int side);
void d86f_set_version(int drive, uint16_t version);
#define length_gap0 80
#define length_gap1 50
@@ -59,3 +60,8 @@ extern int gap2_size[2];
extern int gap3_size[2];
extern int gap4_size[2];
#endif
#define D86FVER 0x020B
void d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n);
void d86f_zero_bit_field(int drive, int side);

View File

@@ -22,6 +22,7 @@
#include <wchar.h>
#include "ibm.h"
#include "disc.h"
#include "disc_86f.h"
#include "disc_img.h"
#include "disc_fdi.h"
#include "fdc.h"
@@ -254,6 +255,7 @@ void d86f_register_fdi(int drive)
d86f_handler[drive].index_hole_pos = fdi_index_hole_pos;
d86f_handler[drive].get_raw_size = fdi_get_raw_size;
d86f_handler[drive].check_crc = 1;
d86f_set_version(drive, D86FVER);
}
void fdi_load(int drive, wchar_t *fn)

View File

@@ -531,6 +531,9 @@ void imd_seek(int drive, int track)
d86f_reset_index_hole_pos(drive, 0);
d86f_reset_index_hole_pos(drive, 1);
d86f_zero_bit_field(drive, 0);
d86f_zero_bit_field(drive, 1);
for (side = 0; side < imd[drive].sides; side++)
{
track_rate = imd[drive].current_side_flags[side] & 7;
@@ -601,6 +604,11 @@ void imd_seek(int drive, int track)
imd_sector_to_buffer(drive, track, side, data, actual_sector, ssize);
current_pos = d86f_prepare_sector(drive, side, current_pos, id, data, ssize, 22, track_gap3, deleted, bad_crc);
track_buf_pos[side] += ssize;
if (sector == 0)
{
d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]);
}
}
}
else
@@ -635,6 +643,11 @@ void imd_seek(int drive, int track)
}
track_buf_pos[side] += ssize;
if (sector == 0)
{
d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]);
}
}
}
}
@@ -746,6 +759,16 @@ void imd_writeback(int drive)
}
}
uint8_t imd_poll_read_data(int drive, int side, uint16_t pos)
{
int type = imd[drive].current_data[side][0];
if (!(type & 1))
{
return 0xf6; /* Should never happen. */
}
return imd[drive].current_data[side][pos + 1];
}
void imd_poll_write_data(int drive, int side, uint16_t pos, uint8_t data)
{
int type = imd[drive].current_data[side][0];
@@ -777,6 +800,7 @@ void d86f_register_imd(int drive)
d86f_handler[drive].side_flags = imd_side_flags;
d86f_handler[drive].writeback = imd_writeback;
d86f_handler[drive].set_sector = imd_set_sector;
d86f_handler[drive].read_data = imd_poll_read_data;
d86f_handler[drive].write_data = imd_poll_write_data;
d86f_handler[drive].format_conditions = imd_format_conditions;
d86f_handler[drive].extra_bit_cells = null_extra_bit_cells;
@@ -785,4 +809,5 @@ void d86f_register_imd(int drive)
d86f_handler[drive].index_hole_pos = null_index_hole_pos;
d86f_handler[drive].get_raw_size = common_get_raw_size;
d86f_handler[drive].check_crc = 1;
d86f_set_version(drive, 0x0063);
}

View File

@@ -938,6 +938,9 @@ void img_seek(int drive, int track)
d86f_reset_index_hole_pos(drive, 0);
d86f_reset_index_hole_pos(drive, 1);
d86f_zero_bit_field(drive, 0);
d86f_zero_bit_field(drive, 1);
if (!img[drive].xdf_type || img[drive].is_cqm)
{
for (side = 0; side < img[drive].sides; side++)
@@ -980,6 +983,11 @@ void img_seek(int drive, int track)
img[drive].sector_pos_side[side][sr] = side;
img[drive].sector_pos[side][sr] = (sr - 1) * ssize;
current_pos = d86f_prepare_sector(drive, side, current_pos, id, &img[drive].track_data[side][(sr - 1) * ssize], ssize, img[drive].gap2_size, img[drive].gap3_size, 0, 0);
if (sector == 0)
{
d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]);
}
}
}
}
@@ -1039,6 +1047,11 @@ void img_seek(int drive, int track)
ssize = (128 << id[3]);
current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[current_xdft][array_sector], id, &img[drive].track_data[buf_side][buf_pos], ssize, img[drive].gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0, 0);
}
if (sector == 0)
{
d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]);
}
}
}
}
@@ -1108,6 +1121,7 @@ void d86f_register_img(int drive)
d86f_handler[drive].side_flags = img_side_flags;
d86f_handler[drive].writeback = img_writeback;
d86f_handler[drive].set_sector = img_set_sector;
d86f_handler[drive].read_data = img_poll_read_data;
d86f_handler[drive].write_data = img_poll_write_data;
d86f_handler[drive].format_conditions = img_format_conditions;
d86f_handler[drive].extra_bit_cells = null_extra_bit_cells;
@@ -1116,4 +1130,5 @@ void d86f_register_img(int drive)
d86f_handler[drive].index_hole_pos = null_index_hole_pos;
d86f_handler[drive].get_raw_size = common_get_raw_size;
d86f_handler[drive].check_crc = 1;
d86f_set_version(drive, 0x0063);
}

View File

@@ -1103,6 +1103,9 @@ void td0_seek(int drive, int track)
d86f_reset_index_hole_pos(drive, 0);
d86f_reset_index_hole_pos(drive, 1);
d86f_zero_bit_field(drive, 0);
d86f_zero_bit_field(drive, 1);
for (side = 0; side < td0[drive].sides; side++)
{
track_rate = td0[drive].current_side_flags[side] & 7;
@@ -1141,6 +1144,11 @@ void td0_seek(int drive, int track)
id[3] = td0[drive].sects[track][side][actual_sector].size;
ssize = 128 << ((uint32_t) td0[drive].sects[track][side][actual_sector].size);
current_pos = d86f_prepare_sector(drive, side, current_pos, id, td0[drive].sects[track][side][actual_sector].data, ssize, track_gap2, track_gap3, td0[drive].sects[track][side][actual_sector].deleted, td0[drive].sects[track][side][actual_sector].bad_crc);
if (sector == 0)
{
d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]);
}
}
}
else
@@ -1164,6 +1172,11 @@ void td0_seek(int drive, int track)
{
current_pos = d86f_prepare_sector(drive, side, current_pos, id, td0[drive].sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], td0[drive].sects[track][side][ordered_pos].deleted, td0[drive].sects[track][side][ordered_pos].bad_crc);
}
if (sector == 0)
{
d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]);
}
}
}
}
@@ -1201,12 +1214,18 @@ void td0_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_
return;
}
uint8_t td0_poll_read_data(int drive, int side, uint16_t pos)
{
return td0[drive].sects[td0[drive].track][side][td0[drive].current_sector_index[side]].data[pos];
}
void d86f_register_td0(int drive)
{
d86f_handler[drive].disk_flags = td0_disk_flags;
d86f_handler[drive].side_flags = td0_side_flags;
d86f_handler[drive].writeback = null_writeback;
d86f_handler[drive].set_sector = td0_set_sector;
d86f_handler[drive].read_data = td0_poll_read_data;
d86f_handler[drive].write_data = null_write_data;
d86f_handler[drive].format_conditions = null_format_conditions;
d86f_handler[drive].extra_bit_cells = null_extra_bit_cells;
@@ -1215,4 +1234,5 @@ void d86f_register_td0(int drive)
d86f_handler[drive].index_hole_pos = null_index_hole_pos;
d86f_handler[drive].get_raw_size = common_get_raw_size;
d86f_handler[drive].check_crc = 1;
d86f_set_version(drive, 0x0063);
}

View File

@@ -189,6 +189,11 @@ int fdd_track0(int drive)
return !fdd[drive].track;
}
int fdd_track(int drive)
{
return fdd[drive].track;
}
void fdd_set_densel(int densel)
{
int i = 0;

View File

@@ -49,3 +49,5 @@ char *fdd_getname(int type);
char *fdd_get_internal_name(int type);
int fdd_get_from_internal_name(char *s);
int fdd_track(int drive);