Rewrote the 86F handler's turbo mode sector present checking, reduces the emulator's RAM usage by about 330 MB.

This commit is contained in:
OBattler
2018-03-15 00:02:19 +01:00
parent b35e6a535d
commit a9c5ba1345
8 changed files with 97 additions and 37 deletions

View File

@@ -8,7 +8,7 @@
*
* Implementation of the floppy drive emulation.
*
* Version: @(#)fdd.c 1.0.8 2018/03/06
* Version: @(#)fdd.c 1.0.9 2018/03/14
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -447,6 +447,7 @@ void fdd_load(int drive, wchar_t *fn)
{
driveloaders[drive] = c;
memcpy(floppyfns[drive], fn, (wcslen(fn) << 1) + 2);
d86f_initialize_linked_lists(drive);
loaders[c].load(drive, floppyfns[drive]);
drive_empty[drive] = 0;
fdd_forced_seek(drive, 0);
@@ -468,6 +469,8 @@ void fdd_close(int drive)
drive_empty[drive] = 1;
fdd_set_head(drive, 0);
floppyfns[drive][0] = 0;
d86f_destroy_linked_lists(drive, 0);
d86f_destroy_linked_lists(drive, 1);
drives[drive].hole = NULL;
drives[drive].poll = NULL;
drives[drive].seek = NULL;

View File

@@ -263,7 +263,7 @@ typedef union
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);
void d86f_destroy_linked_lists(int drive, int side);
void d86f_set_fdc(void *fdc);
void fdi_set_fdc(void *fdc);

View File

@@ -10,7 +10,7 @@
* data in the form of FM/MFM-encoded transitions) which also
* forms the core of the emulator's floppy disk emulation.
*
* Version: @(#)fdd_86f.c 1.0.15 2018/03/05
* Version: @(#)fdd_86f.c 1.0.16 2018/03/14
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Copyright 2016-2018 Miran Grca.
@@ -195,6 +195,14 @@ typedef union {
static fdc_t *d86f_fdc;
#pragma pack(push,1)
typedef struct
{
uint8_t c, h, r, n;
void *prev;
} sector_t;
#pragma pack(pop)
#pragma pack(push,1)
struct
{
@@ -239,7 +247,7 @@ struct
uint8_t *outbuf;
uint32_t dma_over;
int turbo_pos;
uint16_t sector_id_bit_field[2][256][256][256];
sector_t *last_side_sector[2];
} d86f[FDD_NUM + 1];
#pragma pack(pop)
@@ -265,25 +273,29 @@ d86f_log(const char *format, ...)
}
void d86f_zero_bit_field(int drive, int side)
void d86f_initialize_linked_lists(int drive)
{
int i = 0;
int j = 0;
int k = 0;
int l = 0;
d86f[drive].last_side_sector[0] = NULL;
d86f[drive].last_side_sector[1] = NULL;
}
for (i = 0; i < side; i++)
void d86f_destroy_linked_lists(int drive, int side)
{
sector_t *s;
sector_t *t;
if (d86f[drive].last_side_sector[side])
{
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;
}
}
s = d86f[drive].last_side_sector[side];
while (s) {
t = s->prev;
free(s);
s = NULL;
if (!t)
break;
s = t;
}
d86f[drive].last_side_sector[side] = NULL;
}
}
@@ -2190,6 +2202,24 @@ void d86f_turbo_format(int drive, int side, int nop)
}
}
int d86f_sector_is_present(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n)
{
sector_t *s, *t;
if (d86f[drive].last_side_sector[side]) {
s = d86f[drive].last_side_sector[side];
while (s) {
if ((s->c == c) && (s->h == h) && (s->r == r) && (s->n == n))
return 1;
if (!s->prev)
break;
t = s->prev;
s = t;
}
}
return 0;
}
void d86f_turbo_poll(int drive, int side)
{
if ((d86f[drive].state != STATE_IDLE) && (d86f[drive].state != STATE_SECTOR_NOT_FOUND) && ((d86f[drive].state & 0xF8) != 0xE8))
@@ -2213,7 +2243,11 @@ void d86f_turbo_poll(int drive, int side)
d86f[drive].state++;
return;
case STATE_02_FIND_ID:
if (!(d86f[drive].sector_id_bit_field[side][fdc_get_read_track_sector(d86f_fdc).id.c][fdc_get_read_track_sector(d86f_fdc).id.h][fdc_get_read_track_sector(d86f_fdc).id.r] & (1 << fdc_get_read_track_sector(d86f_fdc).id.n)))
if (!d86f_sector_is_present(drive, side,
fdc_get_read_track_sector(d86f_fdc).id.c,
fdc_get_read_track_sector(d86f_fdc).id.h,
fdc_get_read_track_sector(d86f_fdc).id.r,
fdc_get_read_track_sector(d86f_fdc).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_fdc);
@@ -2234,7 +2268,11 @@ void d86f_turbo_poll(int drive, int side)
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)))
if (!d86f_sector_is_present(drive, side,
d86f[drive].req_sector.id.c,
d86f[drive].req_sector.id.h,
d86f[drive].req_sector.id.r,
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_fdc);
@@ -2577,6 +2615,8 @@ uint16_t d86f_prepare_pretrack(int drive, int side, int iso)
d86f[drive].index_hole_pos[side] = 0;
d86f_destroy_linked_lists(drive, side);
for (i = 0; i < raw_size; i++)
{
d86f_write_direct_common(drive, side, gap_fill, 0, i);
@@ -2621,6 +2661,7 @@ uint16_t d86f_prepare_sector(int drive, int side, int prev_pos, uint8_t *id_buf,
uint16_t pos;
int i;
sector_t *s;
int real_gap2_len = gap2;
int real_gap3_len = gap3;
@@ -2635,7 +2676,15 @@ 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]);
s = (sector_t *) malloc(sizeof(sector_t));
memset(s, 0, sizeof(sector_t));
s->c = id_buf[0];
s->h = id_buf[1];
s->r = id_buf[2];
s->n = id_buf[3];
if (d86f[drive].last_side_sector[side])
s->prev = d86f[drive].last_side_sector[side];
d86f[drive].last_side_sector[side] = s;
mfm = d86f_is_mfm(drive);
@@ -3748,10 +3797,16 @@ void d86f_load(int drive, wchar_t *fn)
void d86f_init()
{
int i;
memset(d86f, 0, sizeof(d86f));
d86f_setupcrc(0x1021);
d86f[0].state = d86f[1].state = STATE_IDLE;
for (i = 0; i < (FDD_NUM + 1); i++)
{
d86f[i].state = STATE_IDLE;
d86f_initialize_linked_lists(i);
}
}
void d86f_set_fdc(void *fdc)

View File

@@ -10,7 +10,7 @@
* data in the form of FM/MFM-encoded transitions) which also
* forms the core of the emulator's floppy disk emulation.
*
* Version: @(#)floppy_86f.h 1.0.4 2018/01/18
* Version: @(#)floppy_86f.h 1.0.5 2018/03/14
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Copyright 2016-2018 Miran Grca.
@@ -69,7 +69,9 @@ extern int gap4_size[2];
#define D86FVER 0x020B
extern void d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n);
extern void d86f_zero_bit_field(int drive, int side);
extern void d86f_initialize_linked_lists(int drive);
extern void d86f_destroy_linked_lists(int drive, int side);
#endif /*EMU_FLOPPY_86F_H*/

View File

@@ -8,7 +8,7 @@
*
* Implementation of the IMD floppy image format.
*
* Version: @(#)fdd_imd.c 1.0.7 2018/03/06
* Version: @(#)fdd_imd.c 1.0.8 2018/03/14
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Copyright 2016-2018 Miran Grca.
@@ -542,8 +542,8 @@ 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);
d86f_destroy_linked_lists(drive, 0);
d86f_destroy_linked_lists(drive, 1);
if (track > imd[drive].track_count)
{

View File

@@ -9,7 +9,7 @@
* Implementation of the raw sector-based floppy image format,
* as well as the Japanese FDI, CopyQM, and FDF formats.
*
* Version: @(#)fdd_img.c 1.0.8 2018/01/16
* Version: @(#)fdd_img.c 1.0.9 2018/03/14
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -960,8 +960,8 @@ 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);
d86f_destroy_linked_lists(drive, 0);
d86f_destroy_linked_lists(drive, 1);
if (track > img[drive].tracks)
{

View File

@@ -8,7 +8,7 @@
*
* Implementation of the PCjs JSON floppy image format.
*
* Version: @(#)fdd_json.c 1.0.10 2018/01/16
* Version: @(#)fdd_json.c 1.0.11 2018/03/14
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*
@@ -357,8 +357,8 @@ json_seek(int drive, int track)
/* Reset the 86F state machine. */
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);
d86f_destroy_linked_lists(drive, 0);
d86f_destroy_linked_lists(drive, 1);
interleave_type = 0;

View File

@@ -8,7 +8,7 @@
*
* Implementation of the Teledisk floppy image format.
*
* Version: @(#)fdd_td0.c 1.0.7 2018/01/16
* Version: @(#)fdd_td0.c 1.0.8 2018/03/14
*
* Authors: Milodrag Milanovic,
* Haruhiko OKUMURA,
@@ -1111,8 +1111,8 @@ 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);
d86f_destroy_linked_lists(drive, 0);
d86f_destroy_linked_lists(drive, 1);
if (track > td0[drive].tracks)
{