From a9c5ba13453f35cf68550eea69cc968a809f3f5c Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 15 Mar 2018 00:02:19 +0100 Subject: [PATCH] Rewrote the 86F handler's turbo mode sector present checking, reduces the emulator's RAM usage by about 330 MB. --- src/floppy/fdd.c | 5 ++- src/floppy/fdd.h | 2 +- src/floppy/fdd_86f.c | 97 +++++++++++++++++++++++++++++++++---------- src/floppy/fdd_86f.h | 6 ++- src/floppy/fdd_imd.c | 6 +-- src/floppy/fdd_img.c | 6 +-- src/floppy/fdd_json.c | 6 +-- src/floppy/fdd_td0.c | 6 +-- 8 files changed, 97 insertions(+), 37 deletions(-) diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 4c048e93a..a309e7e3a 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -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, * Miran Grca, @@ -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; diff --git a/src/floppy/fdd.h b/src/floppy/fdd.h index 8b05881ef..f4a26e988 100644 --- a/src/floppy/fdd.h +++ b/src/floppy/fdd.h @@ -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); diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index a36b79e29..3d5064a80 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -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, * 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) diff --git a/src/floppy/fdd_86f.h b/src/floppy/fdd_86f.h index 983915fcb..f272ff59b 100644 --- a/src/floppy/fdd_86f.h +++ b/src/floppy/fdd_86f.h @@ -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, * 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*/ diff --git a/src/floppy/fdd_imd.c b/src/floppy/fdd_imd.c index ca56f5fe7..503521e1d 100644 --- a/src/floppy/fdd_imd.c +++ b/src/floppy/fdd_imd.c @@ -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, * 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) { diff --git a/src/floppy/fdd_img.c b/src/floppy/fdd_img.c index 23ac2d919..daab0ad39 100644 --- a/src/floppy/fdd_img.c +++ b/src/floppy/fdd_img.c @@ -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, * Miran Grca, @@ -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) { diff --git a/src/floppy/fdd_json.c b/src/floppy/fdd_json.c index 8bf8cc6c4..1daad4ee8 100644 --- a/src/floppy/fdd_json.c +++ b/src/floppy/fdd_json.c @@ -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, * @@ -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; diff --git a/src/floppy/fdd_td0.c b/src/floppy/fdd_td0.c index 20e1a019c..c3056f705 100644 --- a/src/floppy/fdd_td0.c +++ b/src/floppy/fdd_td0.c @@ -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) {