diff --git a/src/bugger.c b/src/bugger.c index 2b7a6ff..cf66def 100644 --- a/src/bugger.c +++ b/src/bugger.c @@ -44,7 +44,7 @@ * configuration register (CTRL_SPCFG bit set) but have to * remember that stuff first... * - * Version: @(#)bugger.c 1.0.1 2018/02/14 + * Version: @(#)bugger.c 1.0.2 2018/03/15 * * Author: Fred N. van Kempen, * @@ -340,7 +340,7 @@ bug_read(uint16_t port, void *priv) /* Initialize the ISA BusBugger emulator. */ static void * -bug_init(device_t *info) +bug_init(const device_t *info) { pclog("%s, I/O=%04x\n", info->name, BUGGER_ADDR); @@ -351,7 +351,7 @@ bug_init(device_t *info) bug_read, NULL, NULL, bug_write, NULL, NULL, NULL); /* Just so its not NULL. */ - return(info); + return((void *)info); } @@ -364,7 +364,7 @@ bug_close(UNUSED(void *priv)) } -device_t bugger_device = { +const device_t bugger_device = { "ISA/PCI Bus Bugger", DEVICE_ISA | DEVICE_AT, 0, diff --git a/src/bugger.h b/src/bugger.h index 7e1ebb3..228583a 100644 --- a/src/bugger.h +++ b/src/bugger.h @@ -8,7 +8,7 @@ * * Definitions for the BUGGER card. * - * Version: @(#)bugger.h 1.0.1 2018/02/14 + * Version: @(#)bugger.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * @@ -58,7 +58,7 @@ extern "C" { #endif /* Global variables. */ -extern device_t bugger_device; +extern const device_t bugger_device; /* Functions. */ diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 0ac9ac8..d3e8103 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -9,7 +9,7 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)cdrom.c 1.0.4 2018/03/08 + * Version: @(#)cdrom.c 1.0.5 2018/03/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -120,7 +120,7 @@ static struct /* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ -uint8_t cdrom_command_flags[0x100] = +const uint8_t cdrom_command_flags[0x100] = { IMPLEMENTED | CHECK_READY | NONDATA, IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, diff --git a/src/config.c b/src/config.c index 5eaeded..c940496 100644 --- a/src/config.c +++ b/src/config.c @@ -12,7 +12,7 @@ * it on Windows XP, and possibly also Vista. Use the * -DANSI_CFG for use on these systems. * - * Version: @(#)config.c 1.0.4 2018/03/11 + * Version: @(#)config.c 1.0.5 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -536,12 +536,17 @@ load_video(void) char *cat = "Video"; char *p; - if (machines[machine].fixed_gfxcard) { - config_delete_var(cat, "gfxcard"); + if (machines[machine].fixed_vidcard) { + config_delete_var(cat, "video_card"); config_delete_var(cat, "voodoo"); - gfxcard = GFX_INTERNAL; + vid_card = VID_INTERNAL; } else { - p = config_get_string(cat, "gfxcard", NULL); + p = config_get_string(cat, "video_card", NULL); + if (p == NULL) { + p = config_get_string(cat, "gfxcard", NULL); + if (p != NULL) + config_delete_var(cat, "gfxcard"); + } if (p == NULL) { if (machines[machine].flags & MACHINE_VIDEO) { p = (char *)malloc((strlen("internal")+1)*sizeof(char)); @@ -551,7 +556,7 @@ load_video(void) strcpy(p, "none"); } } - gfxcard = video_get_video_from_internal_name(p); + vid_card = video_get_video_from_internal_name(p); video_speed = config_get_int(cat, "video_speed", -1); @@ -664,22 +669,27 @@ load_network(void) } else network_type = NET_TYPE_NONE; - memset(network_pcap, '\0', sizeof(network_pcap)); - p = config_get_string(cat, "net_pcap_device", NULL); + memset(network_host, '\0', sizeof(network_host)); + p = config_get_string(cat, "net_host_device", NULL); + if (p == NULL) { + p = config_get_string(cat, "net_pcap_device", NULL); + if (p != NULL) + config_delete_var(cat, "net_pcap_device"); + } if (p != NULL) { if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) { - if ((network_ndev == 1) && strcmp(network_pcap, "none")) { + if ((network_ndev == 1) && strcmp(network_host, "none")) { ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2140); } else if (network_dev_to_id(p) == -1) { ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2141); } - strcpy(network_pcap, "none"); + strcpy(network_host, "none"); } else { - strcpy(network_pcap, p); + strcpy(network_host, p); } } else - strcpy(network_pcap, "none"); + strcpy(network_host, "none"); p = config_get_string(cat, "net_card", NULL); if (p != NULL) @@ -1445,7 +1455,7 @@ config_load(void) plat_langid = 0x0409; #endif scale = 1; - gfxcard = GFX_CGA; + vid_card = VID_CGA; vid_api = plat_vidapi("default");; enable_sync = 1; joystick_type = 7; @@ -1632,8 +1642,8 @@ save_video(void) { char *cat = "Video"; - config_set_string(cat, "gfxcard", - video_get_internal_name(video_old_to_new(gfxcard))); + config_set_string(cat, "video_card", + video_get_internal_name(video_old_to_new(vid_card))); if (video_speed == 3) config_delete_var(cat, "video_speed"); @@ -1773,14 +1783,13 @@ save_network(void) config_set_string(cat, "net_type", (network_type == NET_TYPE_SLIRP) ? "slirp" : "pcap"); - if (network_pcap[0] != '\0') { - if (! strcmp(network_pcap, "none")) - config_delete_var(cat, "net_pcap_device"); + if (network_host[0] != '\0') { + if (! strcmp(network_host, "none")) + config_delete_var(cat, "net_host_device"); else - config_set_string(cat, "net_pcap_device", network_pcap); + config_set_string(cat, "net_host_device", network_host); } else { - /* config_set_string(cat, "net_pcap_device", "none"); */ - config_delete_var(cat, "net_pcap_device"); + config_delete_var(cat, "net_host_device"); } if (network_card == 0) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 70183e4..12fa249 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -8,7 +8,7 @@ * * CPU type handler. * - * Version: @(#)cpu.c 1.0.3 2018/03/12 + * Version: @(#)cpu.c 1.0.4 2018/03/15 * * Authors: Sarah Walker, * leilei, @@ -127,6 +127,7 @@ int cpu_hasVME; int cpu_cyrix_alignment; int hasfpu; int cpuspeed; +int CPUID; uint64_t cpu_CR4_mask; diff --git a/src/device.c b/src/device.c index 1adcd64..ca82e11 100644 --- a/src/device.c +++ b/src/device.c @@ -9,7 +9,7 @@ * Implementation of the generic device interface to handle * all devices attached to the emulator. * - * Version: @(#)device.c 1.0.3 2018/03/13 + * Version: @(#)device.c 1.0.4 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -52,8 +52,8 @@ #define DEVICE_MAX 256 /* max # of devices */ -static device_t *devices[DEVICE_MAX]; static void *device_priv[DEVICE_MAX]; +static device_t *devices[DEVICE_MAX]; static device_t *device_current; @@ -65,13 +65,13 @@ device_init(void) void * -device_add(device_t *d) +device_add(const device_t *d) { void *priv = NULL; int c; for (c=0; c<256; c++) { - if (devices[c] == d) { + if (devices[c] == (device_t *)d) { pclog("DEVICE: device already exists!\n"); return(NULL); } @@ -80,7 +80,7 @@ device_add(device_t *d) if (c >= DEVICE_MAX) fatal("DEVICE: too many devices\n"); - device_current = d; + device_current = (device_t *)d; if (d->init != NULL) { priv = d->init(d); @@ -93,7 +93,7 @@ device_add(device_t *d) } } - devices[c] = d; + devices[c] = (device_t *)d; device_priv[c] = priv; return(priv); @@ -102,12 +102,12 @@ device_add(device_t *d) /* For devices that do not have an init function (internal video etc.) */ void -device_add_ex(device_t *d, void *priv) +device_add_ex(const device_t *d, void *priv) { int c; for (c=0; c<256; c++) { - if (devices[c] == d) { + if (devices[c] == (device_t *)d) { fatal("device_add: device already exists!\n"); break; } @@ -116,9 +116,9 @@ device_add_ex(device_t *d, void *priv) if (c >= DEVICE_MAX) fatal("device_add: too many devices\n"); - device_current = d; + device_current = (device_t *)d; - devices[c] = d; + devices[c] = (device_t *)d; device_priv[c] = priv; } @@ -153,7 +153,7 @@ device_reset_all(void) void * -device_get_priv(device_t *d) +device_get_priv(const device_t *d) { int c; @@ -169,7 +169,7 @@ device_get_priv(device_t *d) int -device_available(device_t *d) +device_available(const device_t *d) { #ifdef RELEASE_BUILD if (d->flags & DEVICE_NOT_WORKING) return(0); @@ -228,7 +228,7 @@ device_add_status_info(char *s, int max_len) char * device_get_config_string(char *s) { - device_config_t *c = device_current->config; + const device_config_t *c = device_current->config; while (c && c->type != -1) { if (! strcmp(s, c->name)) @@ -244,7 +244,7 @@ device_get_config_string(char *s) int device_get_config_int(char *s) { - device_config_t *c = device_current->config; + const device_config_t *c = device_current->config; while (c && c->type != -1) { if (! strcmp(s, c->name)) @@ -260,7 +260,7 @@ device_get_config_int(char *s) int device_get_config_int_ex(char *s, int default_int) { - device_config_t *c = device_current->config; + const device_config_t *c = device_current->config; while (c && c->type != -1) { if (! strcmp(s, c->name)) @@ -276,7 +276,7 @@ device_get_config_int_ex(char *s, int default_int) int device_get_config_hex16(char *s) { - device_config_t *c = device_current->config; + const device_config_t *c = device_current->config; while (c && c->type != -1) { if (! strcmp(s, c->name)) @@ -292,7 +292,7 @@ device_get_config_hex16(char *s) int device_get_config_hex20(char *s) { - device_config_t *c = device_current->config; + const device_config_t *c = device_current->config; while (c && c->type != -1) { if (! strcmp(s, c->name)) @@ -308,7 +308,7 @@ device_get_config_hex20(char *s) int device_get_config_mac(char *s, int default_int) { - device_config_t *c = device_current->config; + const device_config_t *c = device_current->config; while (c && c->type != -1) { if (! strcmp(s, c->name)) @@ -324,7 +324,7 @@ device_get_config_mac(char *s, int default_int) void device_set_config_int(char *s, int val) { - device_config_t *c = device_current->config; + const device_config_t *c = device_current->config; while (c && c->type != -1) { if (! strcmp(s, c->name)) { @@ -340,7 +340,7 @@ device_set_config_int(char *s, int val) void device_set_config_hex16(char *s, int val) { - device_config_t *c = device_current->config; + const device_config_t *c = device_current->config; while (c && c->type != -1) { if (! strcmp(s, c->name)) { @@ -356,7 +356,7 @@ device_set_config_hex16(char *s, int val) void device_set_config_hex20(char *s, int val) { - device_config_t *c = device_current->config; + const device_config_t *c = device_current->config; while (c && c->type != -1) { if (! strcmp(s, c->name)) { @@ -372,7 +372,7 @@ device_set_config_hex20(char *s, int val) void device_set_config_mac(char *s, int val) { - device_config_t *c = device_current->config; + const device_config_t *c = device_current->config; while (c && c->type != -1) { if (! strcmp(s, c->name)) { @@ -386,7 +386,7 @@ device_set_config_mac(char *s, int val) int -device_is_valid(device_t *device, int mflags) +device_is_valid(const device_t *device, int mflags) { if (device == NULL) return(1); @@ -414,8 +414,8 @@ device_is_valid(device_t *device, int mflags) int machine_get_config_int(char *s) { - device_t *d = machine_getdevice(machine); - device_config_t *c; + const device_t *d = machine_getdevice(machine); + const device_config_t *c; if (d == NULL) return(0); @@ -434,8 +434,8 @@ machine_get_config_int(char *s) char * machine_get_config_string(char *s) { - device_t *d = machine_getdevice(machine); - device_config_t *c; + const device_t *d = machine_getdevice(machine); + const device_config_t *c; if (d == NULL) return(0); diff --git a/src/device.h b/src/device.h index 66a02cc..32f803a 100644 --- a/src/device.h +++ b/src/device.h @@ -8,7 +8,7 @@ * * Definitions for the device handler. * - * Version: @(#)device.h 1.0.1 2018/02/14 + * Version: @(#)device.h 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -98,7 +98,7 @@ typedef struct _device_ { uint32_t flags; /* system flags */ uint32_t local; /* flags local to device */ - void *(*init)(struct _device_ *); + void *(*init)(const struct _device_ *); void (*close)(void *p); void (*reset)(void *p); int (*available)(/*void*/); @@ -106,7 +106,7 @@ typedef struct _device_ { void (*force_redraw)(void *p); void (*add_status_info)(char *s, int max_len, void *p); - device_config_t *config; + const device_config_t *config; } device_t; @@ -115,12 +115,12 @@ extern "C" { #endif extern void device_init(void); -extern void *device_add(device_t *d); -extern void device_add_ex(device_t *d, void *priv); +extern void *device_add(const device_t *d); +extern void device_add_ex(const device_t *d, void *priv); extern void device_close_all(void); extern void device_reset_all(void); -extern void *device_get_priv(device_t *d); -extern int device_available(device_t *d); +extern void *device_get_priv(const device_t *d); +extern int device_available(const device_t *d); extern void device_speed_changed(void); extern void device_force_redraw(void); extern void device_add_status_info(char *s, int max_len); @@ -135,7 +135,7 @@ extern void device_set_config_hex16(char *s, int val); extern void device_set_config_hex20(char *s, int val); extern void device_set_config_mac(char *s, int val); extern char *device_get_config_string(char *name); -extern int device_is_valid(device_t *device, int machine_flags); +extern int device_is_valid(const device_t *device, int machine_flags); extern int machine_get_config_int(char *s); extern char *machine_get_config_string(char *s); diff --git a/src/disk/hdc.c b/src/disk/hdc.c index 7cfa7dc..946df71 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -8,7 +8,7 @@ * * Common code to handle all sorts of disk controllers. * - * Version: @(#)hdc.c 1.0.1 2018/02/14 + * Version: @(#)hdc.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -49,7 +49,7 @@ int hdc_current; static void * -null_init(device_t *info) +null_init(const device_t *info) { return(NULL); } @@ -61,7 +61,7 @@ null_close(void *priv) } -static device_t null_device = { +static const device_t null_device = { "Null HDC", 0, 0, null_init, null_close, NULL, NULL, NULL, NULL, NULL, NULL @@ -69,7 +69,7 @@ static device_t null_device = { static void * -inthdc_init(device_t *info) +inthdc_init(const device_t *info) { return(NULL); } @@ -81,18 +81,18 @@ inthdc_close(void *priv) } -static device_t inthdc_device = { +static const device_t inthdc_device = { "Internal Controller", 0, 0, inthdc_init, inthdc_close, NULL, NULL, NULL, NULL, NULL, NULL }; -static struct { - char *name; - char *internal_name; - device_t *device; - int is_mfm; +static const struct { + const char *name; + const char *internal_name; + const device_t *device; + int is_mfm; } controllers[] = { { "None", "none", &null_device, 0 }, @@ -158,7 +158,7 @@ hdc_init(char *name) pclog("HDC: initializing..\n"); for (c=0; controllers[c].device; c++) { - if (! strcmp(name, controllers[c].internal_name)) { + if (! strcmp(name, (char *)controllers[c].internal_name)) { hdc_current = c; break; } @@ -182,18 +182,18 @@ hdc_reset(void) char * hdc_get_name(int hdc) { - return(controllers[hdc].name); + return((char *)controllers[hdc].name); } char * hdc_get_internal_name(int hdc) { - return(controllers[hdc].internal_name); + return((char *)controllers[hdc].internal_name); } -device_t * +const device_t * hdc_get_device(int hdc) { return(controllers[hdc].device); diff --git a/src/disk/hdc.h b/src/disk/hdc.h index c2c960c..b888fd0 100644 --- a/src/disk/hdc.h +++ b/src/disk/hdc.h @@ -8,7 +8,7 @@ * * Definitions for the common disk controller handler. * - * Version: @(#)hdc.h 1.0.1 2018/02/14 + * Version: @(#)hdc.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -46,29 +46,29 @@ * least 7 devices, with each device being * able to support 8 units, but hey... */ -extern char *hdc_name; -extern int hdc_current; +extern char *hdc_name; +extern int hdc_current; -extern device_t mfm_xt_xebec_device; /* mfm_xt_xebec */ -extern device_t mfm_xt_dtc5150x_device; /* mfm_xt_dtc */ -extern device_t mfm_at_wd1003_device; /* mfm_at_wd1003 */ +extern const device_t mfm_xt_xebec_device; /* mfm_xt_xebec */ +extern const device_t mfm_xt_dtc5150x_device; /* mfm_xt_dtc */ +extern const device_t mfm_at_wd1003_device; /* mfm_at_wd1003 */ -extern device_t esdi_at_wd1007vse1_device; /* esdi_at */ -extern device_t esdi_ps2_device; /* esdi_mca */ +extern const device_t esdi_at_wd1007vse1_device; /* esdi_at */ +extern const device_t esdi_ps2_device; /* esdi_mca */ -extern device_t ide_isa_device; /* isa_ide */ -extern device_t ide_isa_2ch_device; /* isa_ide_2ch */ -extern device_t ide_isa_2ch_opt_device; /* isa_ide_2ch_opt */ -extern device_t ide_vlb_device; /* vlb_ide */ -extern device_t ide_vlb_2ch_device; /* vlb_ide_2ch */ -extern device_t ide_pci_device; /* pci_ide */ -extern device_t ide_pci_2ch_device; /* pci_ide_2ch */ +extern const device_t ide_isa_device; /* isa_ide */ +extern const device_t ide_isa_2ch_device; /* isa_ide_2ch */ +extern const device_t ide_isa_2ch_opt_device; /* isa_ide_2ch_opt */ +extern const device_t ide_vlb_device; /* vlb_ide */ +extern const device_t ide_vlb_2ch_device; /* vlb_ide_2ch */ +extern const device_t ide_pci_device; /* pci_ide */ +extern const device_t ide_pci_2ch_device; /* pci_ide_2ch */ -extern device_t xtide_device; /* xtide_xt */ -extern device_t xtide_at_device; /* xtide_at */ -extern device_t xtide_acculogic_device; /* xtide_ps2 */ -extern device_t xtide_at_ps2_device; /* xtide_at_ps2 */ +extern const device_t xtide_device; /* xtide_xt */ +extern const device_t xtide_at_device; /* xtide_at */ +extern const device_t xtide_acculogic_device; /* xtide_ps2 */ +extern const device_t xtide_at_ps2_device; /* xtide_at_ps2 */ extern void hdc_init(char *name); @@ -76,7 +76,7 @@ extern void hdc_reset(void); extern char *hdc_get_name(int hdc); extern char *hdc_get_internal_name(int hdc); -extern device_t *hdc_get_device(int hdc); +extern const device_t *hdc_get_device(int hdc); extern int hdc_get_flags(int hdc); extern int hdc_available(int hdc); extern int hdc_current_is_mfm(void); diff --git a/src/disk/hdc_esdi_at.c b/src/disk/hdc_esdi_at.c index 0188a4b..2b3f19b 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -8,7 +8,7 @@ * * Driver for the ESDI controller (WD1007-vse1) for PC/AT. * - * Version: @(#)hdc_esdi_at.c 1.0.2 2018/02/26 + * Version: @(#)hdc_esdi_at.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -788,7 +788,7 @@ loadhd(esdi_t *esdi, int hdd_num, int d, const wchar_t *fn) static void * -wd1007vse1_init(device_t *info) +wd1007vse1_init(const device_t *info) { int c, d; @@ -853,7 +853,7 @@ wd1007vse1_available(void) } -device_t esdi_at_wd1007vse1_device = { +const device_t esdi_at_wd1007vse1_device = { "Western Digital WD1007V-SE1 (ESDI)", DEVICE_ISA | DEVICE_AT, 0, diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index f0a9938..408f325 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -52,7 +52,7 @@ * however, are auto-configured by the system software as * shown above. * - * Version: @(#)hdc_esdi_mca.c 1.0.1 2018/02/14 + * Version: @(#)hdc_esdi_mca.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Sarah Walker, @@ -1059,7 +1059,7 @@ esdi_mca_write(int port, uint8_t val, void *priv) static void * -esdi_init(device_t *info) +esdi_init(const device_t *info) { drive_t *drive; esdi_t *dev; @@ -1153,7 +1153,7 @@ esdi_available(void) } -device_t esdi_ps2_device = { +const device_t esdi_ps2_device = { "IBM ESDI Fixed Disk Adapter (MCA)", DEVICE_MCA, 0, esdi_init, esdi_close, NULL, diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 533fd2d..0e1f2c2 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -9,7 +9,7 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)hdc_ide.c 1.0.7 2018/03/12 + * Version: @(#)hdc_ide.c 1.0.9 2018/03/16 * * Authors: Miran Grca, * Sarah Walker, @@ -38,11 +38,12 @@ #define __USE_LARGEFILE64 #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE +#include #include #include #include +#include #include -#include #include #define HAVE_STDARG_H #include "../emu.h" @@ -757,6 +758,25 @@ void ide_ter_disable_cond(); void ide_qua_disable_cond(); +void ide_destroy_buffers(void) +{ + int d; + + for (d = 0; d < (IDE_NUM+XTIDE_NUM); d++) + { + if (ide_drives[d].buffer) { + free(ide_drives[d].buffer); + ide_drives[d].buffer = NULL; + } + + if (ide_drives[d].sector_buffer) { + free(ide_drives[d].sector_buffer); + ide_drives[d].sector_buffer = NULL; + } + } +} + + void ide_reset(void) { int c, d; @@ -782,8 +802,18 @@ void ide_reset(void) ide_drives[d].atastat = READY_STAT | DSC_STAT; ide_drives[d].service = 0; ide_drives[d].board = d >> 1; + + if (ide_drives[d].buffer) { + free(ide_drives[d].buffer); + ide_drives[d].buffer = NULL; + } + + if (ide_drives[d].sector_buffer) { + free(ide_drives[d].sector_buffer); + ide_drives[d].sector_buffer = NULL; + } } - + idecallback[0]=idecallback[1]=0LL; idecallback[2]=idecallback[3]=0LL; idecallback[4]=0LL; @@ -796,12 +826,14 @@ void ide_reset(void) { ide_log("Found IDE hard disk on channel %i\n", hdd[d].ide_channel); loadhd(&ide_drives[hdd[d].ide_channel], d, hdd[d].fn); + ide_drives[hdd[d].ide_channel].sector_buffer = (uint8_t *) malloc(256*512); if (++c >= (IDE_NUM+XTIDE_NUM)) break; } if ((hdd[d].bus==HDD_BUS_XTIDE) && (hdd[d].xtide_channel < XTIDE_NUM)) { ide_log("Found XT IDE hard disk on channel %i\n", hdd[d].xtide_channel); loadhd(&ide_drives[hdd[d].xtide_channel | 8], d, hdd[d].fn); + ide_drives[hdd[d].xtide_channel | 8].sector_buffer = (uint8_t *) malloc(256*512); if (++c >= (IDE_NUM+XTIDE_NUM)) break; } } @@ -809,14 +841,13 @@ void ide_reset(void) for (d = 0; d < IDE_NUM; d++) { - if (ide_drive_is_zip(&ide_drives[d]) && (ide_drives[d].type != IDE_HDD)) - { + if (ide_drive_is_zip(&ide_drives[d]) && (ide_drives[d].type == IDE_NONE)) ide_drives[d].type = IDE_ZIP; - } - else if (ide_drive_is_cdrom(&ide_drives[d]) && (ide_drives[d].type != IDE_HDD)) - { + else if (ide_drive_is_cdrom(&ide_drives[d]) && (ide_drives[d].type == IDE_NONE)) ide_drives[d].type = IDE_CDROM; - } + + if (ide_drives[d].type != IDE_NONE) + ide_drives[d].buffer = (uint16_t *) malloc(65536 * sizeof(uint16_t)); ide_set_signature(&ide_drives[d]); @@ -2758,7 +2789,7 @@ void secondary_ide_check(void) * keeping a zillion of duplicate functions around. */ static void * -ide_sainit(device_t *info) +ide_sainit(const device_t *info) { switch(info->local) { case 0: /* ISA, single-channel */ @@ -2788,7 +2819,7 @@ ide_sainit(device_t *info) break; } - return(info); + return((void *)info); } @@ -2800,7 +2831,7 @@ ide_saclose(void *priv) } -device_t ide_isa_device = { +const device_t ide_isa_device = { "ISA PC/AT IDE Controller", DEVICE_ISA | DEVICE_AT, 0, @@ -2809,7 +2840,7 @@ device_t ide_isa_device = { NULL }; -device_t ide_isa_2ch_device = { +const device_t ide_isa_2ch_device = { "ISA PC/AT IDE Controller (Dual-Channel)", DEVICE_ISA | DEVICE_AT, 2, @@ -2818,7 +2849,7 @@ device_t ide_isa_2ch_device = { NULL }; -device_t ide_isa_2ch_opt_device = { +const device_t ide_isa_2ch_opt_device = { "ISA PC/AT IDE Controller (Single/Dual)", DEVICE_ISA | DEVICE_AT, 3, @@ -2827,7 +2858,7 @@ device_t ide_isa_2ch_opt_device = { NULL }; -device_t ide_vlb_device = { +const device_t ide_vlb_device = { "VLB IDE Controller", DEVICE_VLB | DEVICE_AT, 4, @@ -2836,7 +2867,7 @@ device_t ide_vlb_device = { NULL }; -device_t ide_vlb_2ch_device = { +const device_t ide_vlb_2ch_device = { "VLB IDE Controller (Dual-Channel)", DEVICE_VLB | DEVICE_AT, 6, @@ -2845,7 +2876,7 @@ device_t ide_vlb_2ch_device = { NULL }; -device_t ide_pci_device = { +const device_t ide_pci_device = { "PCI IDE Controller", DEVICE_PCI | DEVICE_AT, 8, @@ -2854,7 +2885,7 @@ device_t ide_pci_device = { NULL }; -device_t ide_pci_2ch_device = { +const device_t ide_pci_2ch_device = { "PCI IDE Controller (Dual-Channel)", DEVICE_PCI | DEVICE_AT, 10, diff --git a/src/disk/hdc_ide.h b/src/disk/hdc_ide.h index 10de1d2..2141f4f 100644 --- a/src/disk/hdc_ide.h +++ b/src/disk/hdc_ide.h @@ -8,7 +8,7 @@ * * Definitions for the IDE module. * - * Version: @(#)hdd_ide.h 1.0.1 2018/02/14 + * Version: @(#)hdc_ide.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -56,7 +56,7 @@ typedef struct { int packetstatus; uint8_t asc; int reset; - uint16_t buffer[65536]; + uint16_t *buffer; int irqstat; int service; int lba; @@ -69,7 +69,7 @@ typedef struct { int hdd_num; uint8_t specify_success; int mdma_mode; - uint8_t sector_buffer[256*512]; + uint8_t *sector_buffer; int do_initial_read; int sector_pos; } IDE; @@ -124,6 +124,7 @@ extern void ide_set_callback(uint8_t channel, int64_t callback); extern void secondary_ide_check(void); extern void ide_padstr8(uint8_t *buf, int buf_size, const char *src); +extern void ide_destroy_buffers(void); extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length); extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length); diff --git a/src/disk/hdc_mfm_at.c b/src/disk/hdc_mfm_at.c index 2f51353..de0c24e 100644 --- a/src/disk/hdc_mfm_at.c +++ b/src/disk/hdc_mfm_at.c @@ -12,7 +12,7 @@ * based design. Most cards were WD1003-WA2 or -WAH, where the * -WA2 cards had a floppy controller as well (to save space.) * - * Version: @(#)hdc_mfm_at.c 1.0.1 2018/02/14 + * Version: @(#)hdc_mfm_at.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Sarah Walker, @@ -725,7 +725,7 @@ loadhd(mfm_t *mfm, int c, int d, const wchar_t *fn) static void * -mfm_init(device_t *info) +mfm_init(const device_t *info) { mfm_t *mfm; int c, d; @@ -782,7 +782,7 @@ mfm_close(void *priv) } -device_t mfm_at_wd1003_device = { +const device_t mfm_at_wd1003_device = { "WD1003 AT MFM/RLL Controller", DEVICE_ISA | DEVICE_AT, 0, diff --git a/src/disk/hdc_mfm_xt.c b/src/disk/hdc_mfm_xt.c index 74f6d3f..0ddac3c 100644 --- a/src/disk/hdc_mfm_xt.c +++ b/src/disk/hdc_mfm_xt.c @@ -41,7 +41,7 @@ * Since all controllers (including the ones made by DTC) use * (mostly) the same API, we keep them all in this module. * - * Version: @(#)hdc_mfm_xt.c 1.0.1 2018/02/14 + * Version: @(#)hdc_mfm_xt.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Sarah Walker, @@ -826,7 +826,7 @@ mfm_set_switches(mfm_t *mfm) static void * -xebec_init(device_t *info) +xebec_init(const device_t *info) { int i, c = 0; @@ -881,7 +881,7 @@ xebec_available(void) } -device_t mfm_xt_xebec_device = { +const device_t mfm_xt_xebec_device = { "IBM PC Fixed Disk Adapter", DEVICE_ISA, 0, @@ -892,7 +892,7 @@ device_t mfm_xt_xebec_device = { static void * -dtc5150x_init(device_t *info) +dtc5150x_init(const device_t *info) { int i, c = 0; @@ -936,7 +936,7 @@ dtc5150x_available(void) } -device_t mfm_xt_dtc5150x_device = { +const device_t mfm_xt_dtc5150x_device = { "DTC 5150X", DEVICE_ISA, 0, diff --git a/src/disk/hdc_xtide.c b/src/disk/hdc_xtide.c index fe7b41e..52b5cd6 100644 --- a/src/disk/hdc_xtide.c +++ b/src/disk/hdc_xtide.c @@ -21,7 +21,7 @@ * already on their way out, the newer IDE standard based on the * PC/AT controller and 16b design became the IDE we now know. * - * Version: @(#)hdc_xtide.c 1.0.2 2018/02/22 + * Version: @(#)hdc_xtide.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -143,7 +143,7 @@ xtide_read(uint16_t port, void *priv) static void * -xtide_init(device_t *info) +xtide_init(const device_t *info) { xtide_t *xtide = malloc(sizeof(xtide_t)); @@ -170,7 +170,7 @@ xtide_available(void) static void * -xtide_at_init(device_t *info) +xtide_at_init(const device_t *info) { xtide_t *xtide = malloc(sizeof(xtide_t)); @@ -193,7 +193,7 @@ xtide_at_available(void) static void * -xtide_acculogic_init(device_t *info) +xtide_acculogic_init(const device_t *info) { xtide_t *xtide = malloc(sizeof(xtide_t)); @@ -220,7 +220,7 @@ xtide_acculogic_available(void) static void * -xtide_at_ps2_init(device_t *info) +xtide_at_ps2_init(const device_t *info) { xtide_t *xtide = malloc(sizeof(xtide_t)); @@ -251,7 +251,7 @@ xtide_close(void *priv) } -device_t xtide_device = { +const device_t xtide_device = { "XTIDE", DEVICE_ISA, 0, @@ -260,7 +260,7 @@ device_t xtide_device = { NULL }; -device_t xtide_at_device = { +const device_t xtide_at_device = { "XTIDE (AT)", DEVICE_ISA | DEVICE_AT, 0, @@ -269,7 +269,7 @@ device_t xtide_at_device = { NULL }; -device_t xtide_acculogic_device = { +const device_t xtide_acculogic_device = { "XTIDE (Acculogic)", DEVICE_ISA, 0, @@ -278,7 +278,7 @@ device_t xtide_acculogic_device = { NULL }; -device_t xtide_at_ps2_device = { +const device_t xtide_at_ps2_device = { "XTIDE (AT) (1.1.5)", DEVICE_ISA | DEVICE_PS2, 0, diff --git a/src/emu.h b/src/emu.h index 7a91782..6dabe77 100644 --- a/src/emu.h +++ b/src/emu.h @@ -8,7 +8,7 @@ * * Main include file for the application. * - * Version: @(#)emu.h 1.0.6 2018/03/11 + * Version: @(#)emu.h 1.0.7 2018/03/15 * * Author: Fred N. van Kempen, * @@ -117,6 +117,7 @@ extern int vid_cga_contrast, /* (C) video */ video_fullscreen_scale, /* (C) video */ enable_overscan, /* (C) video */ force_43, /* (C) video */ + vid_card, /* (C) graphics/video card */ video_speed; /* (C) video */ extern int serial_enabled[], /* (C) enable serial ports */ lpt_enabled, /* (C) enable LPT ports */ @@ -126,7 +127,6 @@ extern int update_icons; /* (C) enable icons updates */ #ifdef WALTJE extern int romdos_enabled; /* (C) enable ROM DOS */ #endif -extern int gfxcard; /* (C) graphics/video card */ extern int sound_is_float, /* (C) sound uses FP values */ GAMEBLASTER, /* (C) sound option */ GUS, /* (C) sound option */ @@ -138,6 +138,9 @@ extern int cpu_manufacturer, /* (C) cpu manufacturer */ cpu_use_dynarec, /* (C) cpu uses/needs Dyna */ enable_external_fpu; /* (C) enable external FPU */ extern int enable_sync; /* (C) enable time sync */ +extern int network_type; /* (C) net provider type */ +extern int network_card; /* (C) net interface num */ +extern char network_host[512]; /* (C) host network intf */ #ifdef ENABLE_LOG_TOGGLES diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index d52ceb3..eb12382 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -9,7 +9,7 @@ * Implementation of the NEC uPD-765 and compatible floppy disk * controller. * - * Version: @(#)fdc.c 1.0.3 2018/03/12 + * Version: @(#)fdc.c 1.0.5 2018/03/16 * * Authors: Miran Grca, * Sarah Walker, @@ -60,7 +60,7 @@ extern int64_t motoron[FDD_NUM]; -int command_has_drivesel[256] = { +const int command_has_drivesel[256] = { 0, 0, 1, /* READ TRACK */ 0, @@ -2037,7 +2037,7 @@ fdc_close(void *priv) static void * -fdc_init(device_t *info) +fdc_init(const device_t *info) { fdc_t *fdc = (fdc_t *) malloc(sizeof(fdc_t)); memset(fdc, 0, sizeof(fdc_t)); @@ -2075,7 +2075,7 @@ fdc_3f1_enable(fdc_t *fdc, int enable) } -device_t fdc_xt_device = { +const device_t fdc_xt_device = { "PC/XT Floppy Drive Controller", 0, 0, @@ -2085,7 +2085,7 @@ device_t fdc_xt_device = { NULL, NULL, NULL, NULL }; -device_t fdc_pcjr_device = { +const device_t fdc_pcjr_device = { "PCjr Floppy Drive Controller", 0, FDC_FLAG_PCJR, @@ -2095,7 +2095,7 @@ device_t fdc_pcjr_device = { NULL, NULL, NULL, NULL }; -device_t fdc_at_device = { +const device_t fdc_at_device = { "PC/AT Floppy Drive Controller", 0, FDC_FLAG_AT, @@ -2105,7 +2105,7 @@ device_t fdc_at_device = { NULL, NULL, NULL, NULL }; -device_t fdc_at_actlow_device = { +const device_t fdc_at_actlow_device = { "PC/AT Floppy Drive Controller (Active low)", 0, FDC_FLAG_DISKCHG_ACTLOW | FDC_FLAG_AT, @@ -2115,7 +2115,7 @@ device_t fdc_at_actlow_device = { NULL, NULL, NULL, NULL }; -device_t fdc_at_ps1_device = { +const device_t fdc_at_ps1_device = { "PC/AT Floppy Drive Controller (PS/1, PS/2 ISA)", 0, FDC_FLAG_DISKCHG_ACTLOW | FDC_FLAG_AT | FDC_FLAG_PS1, @@ -2125,7 +2125,7 @@ device_t fdc_at_ps1_device = { NULL, NULL, NULL, NULL }; -device_t fdc_at_smc_device = { +const device_t fdc_at_smc_device = { "PC/AT Floppy Drive Controller (SM(s)C FDC37Cxxx)", 0, FDC_FLAG_AT | FDC_FLAG_SUPERIO, @@ -2135,7 +2135,7 @@ device_t fdc_at_smc_device = { NULL, NULL, NULL, NULL }; -device_t fdc_at_winbond_device = { +const device_t fdc_at_winbond_device = { "PC/AT Floppy Drive Controller (Winbond W83x77F)", 0, FDC_FLAG_AT | FDC_FLAG_SUPERIO | FDC_FLAG_START_RWC_1 | FDC_FLAG_MORE_TRACKS, @@ -2145,7 +2145,7 @@ device_t fdc_at_winbond_device = { NULL, NULL, NULL, NULL }; -device_t fdc_at_nsc_device = { +const device_t fdc_at_nsc_device = { "PC/AT Floppy Drive Controller (NSC PC8730x)", 0, FDC_FLAG_AT | FDC_FLAG_MORE_TRACKS | FDC_FLAG_NSC, diff --git a/src/floppy/fdc.h b/src/floppy/fdc.h index 5ca1603..0d540e9 100644 --- a/src/floppy/fdc.h +++ b/src/floppy/fdc.h @@ -9,11 +9,13 @@ * Implementation of the NEC uPD-765 and compatible floppy disk * controller. * - * Version: @(#)fdc.h 1.0.2 2018/03/04 + * Version: @(#)fdc.h 1.0.3 2018/03/17 * - * Authors: Miran Grca, + * Authors: Fred N. van Kempen, + * Miran Grca, * Sarah Walker, * + * Copyright 2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. * Copyright 2008-2018 Sarah Walker. * @@ -48,8 +50,8 @@ #define FDC_FLAG_MORE_TRACKS 0x40 /* W83877F, W83977F, PC87306, PC87309 */ #define FDC_FLAG_NSC 0x80 /* PC87306, PC87309 */ -typedef struct -{ + +typedef struct { uint8_t dor, stat, command, dat, st0, swap; uint8_t swwp, disable_write; uint8_t params[256], res[256]; @@ -98,6 +100,7 @@ typedef struct int64_t watchdog_timer, watchdog_count; } fdc_t; + extern void fdc_remove(fdc_t *fdc); extern void fdc_poll(fdc_t *fdc); extern void fdc_abort(fdc_t *fdc); @@ -167,7 +170,9 @@ extern void fdc_set_base(fdc_t *fdc, int base); extern int fdc_getdata(fdc_t *fdc, int last); extern int fdc_data(fdc_t *fdc, uint8_t data); -extern void fdc_sectorid(fdc_t *fdc, uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1, uint8_t crc2); +extern void fdc_sectorid(fdc_t *fdc, uint8_t track, uint8_t side, + uint8_t sector, uint8_t size, uint8_t crc1, + uint8_t crc2); extern uint8_t fdc_read(uint16_t addr, void *priv); extern void fdc_reset(void *priv); @@ -175,14 +180,14 @@ extern void fdc_reset(void *priv); extern uint8_t fdc_ps1_525(void); #ifdef EMU_DEVICE_H -extern device_t fdc_xt_device; -extern device_t fdc_pcjr_device; -extern device_t fdc_at_device; -extern device_t fdc_at_actlow_device; -extern device_t fdc_at_ps1_device; -extern device_t fdc_at_smc_device; -extern device_t fdc_at_winbond_device; -extern device_t fdc_at_nsc_device; +extern const device_t fdc_xt_device; +extern const device_t fdc_pcjr_device; +extern const device_t fdc_at_device; +extern const device_t fdc_at_actlow_device; +extern const device_t fdc_at_ps1_device; +extern const device_t fdc_at_smc_device; +extern const device_t fdc_at_winbond_device; +extern const device_t fdc_at_nsc_device; #endif diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 541233d..1e1ba16 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -8,11 +8,13 @@ * * Implementation of the floppy drive emulation. * - * Version: @(#)fdd.c 1.0.4 2018/03/14 + * Version: @(#)fdd.c 1.0.5 2018/03/16 * - * Authors: Miran Grca, + * Authors: Fred N. van Kempen, + * Miran Grca, * Sarah Walker, * + * Copyright 2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. * Copyright 2008-2018 Sarah Walker. * @@ -84,8 +86,9 @@ int fdc_indexcount = 52; fdc_t *fdd_fdc; +d86f_handler_t d86f_handler[FDD_NUM]; -static struct +static const struct { wchar_t *ext; void (*load)(int drive, wchar_t *fn); @@ -168,7 +171,7 @@ int ui_writeprot[FDD_NUM] = {0, 0, 0, 0}; #define FLAG_IGNORE_DENSEL 512 #define FLAG_PS2 1024 -static struct +static const struct { int max_track; int flags; @@ -225,12 +228,12 @@ static struct char *fdd_getname(int type) { - return drive_types[type].name; + return (char *)drive_types[type].name; } char *fdd_get_internal_name(int type) { - return drive_types[type].internal_name; + return (char *)drive_types[type].internal_name; } int fdd_get_from_internal_name(char *s) @@ -239,7 +242,7 @@ int fdd_get_from_internal_name(char *s) while (strlen(drive_types[c].internal_name)) { - if (!strcmp(drive_types[c].internal_name, s)) + if (!strcmp((char *)drive_types[c].internal_name, s)) return c; c++; } @@ -451,6 +454,9 @@ void fdd_load(int drive, wchar_t *fn) int c = 0, size; wchar_t *p; FILE *f; + + pclog("FDD: loading drive %d with '%ls'\n", drive, fn); + if (!fn) return; p = plat_get_extension(fn); if (!p) return; @@ -465,7 +471,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); + d86f_setup(drive); loaders[c].load(drive, floppyfns[drive]); drive_empty[drive] = 0; fdd_forced_seek(drive, 0); @@ -474,7 +480,7 @@ void fdd_load(int drive, wchar_t *fn) } c++; } - pclog("Couldn't load %ls %s\n",fn,p); + pclog("FDD: could not load '%ls' %s\n",fn,p); drive_empty[drive] = 1; fdd_set_head(drive, 0); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); @@ -483,12 +489,13 @@ void fdd_load(int drive, wchar_t *fn) void fdd_close(int drive) { + pclog("FDD: closing drive %d\n", drive); + if (loaders[driveloaders[drive]].close) loaders[driveloaders[drive]].close(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); + d86f_destroy(drive); drives[drive].hole = NULL; drives[drive].poll = NULL; drives[drive].seek = NULL; @@ -712,6 +719,7 @@ void fdd_init(void) d86f_init(); td0_init(); imd_init(); + json_init(); fdd_load(0, floppyfns[0]); fdd_load(1, floppyfns[1]); diff --git a/src/floppy/fdd.h b/src/floppy/fdd.h index 6179ff1..7610cee 100644 --- a/src/floppy/fdd.h +++ b/src/floppy/fdd.h @@ -8,11 +8,13 @@ * * Definitions for the floppy drive emulation. * - * Version: @(#)fdd.h 1.0.2 2018/03/14 + * Version: @(#)fdd.h 1.0.3 2018/03/17 * - * Authors: Miran Grca, + * Authors: Fred N. van Kempen, + * Miran Grca, * Sarah Walker, * + * Copyright 2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. * Copyright 2008-2018 Sarah Walker. * @@ -38,15 +40,15 @@ # define EMU_FDD_H -#define FDD_NUM 4 -#define SEEK_RECALIBRATE -999 +#define FDD_NUM 4 +#define SEEK_RECALIBRATE -999 #ifdef __cplusplus extern "C" { #endif -extern int fdd_swap; +extern int fdd_swap; extern void fdd_do_seek(int drive, int track); @@ -83,16 +85,19 @@ extern int fdd_current_track(int drive); typedef struct { - void (*seek)(int drive, int track); - void (*readsector)(int drive, int sector, int track, int side, int density, int sector_size); - void (*writesector)(int drive, int sector, int track, int side, int density, int sector_size); - void (*comparesector)(int drive, int sector, int track, int side, int density, int sector_size); - void (*readaddress)(int drive, int side, int density); - void (*format)(int drive, int side, int density, uint8_t fill); - int (*hole)(int drive); - double (*byteperiod)(int drive); - void (*stop)(int drive); - void (*poll)(int drive); + void (*seek)(int drive, int track); + void (*readsector)(int drive, int sector, int track, int side, + int density, int sector_size); + void (*writesector)(int drive, int sector, int track, int side, + int density, int sector_size); + void (*comparesector)(int drive, int sector, int track, int side, + int density, int sector_size); + void (*readaddress)(int drive, int side, int density); + void (*format)(int drive, int side, int density, uint8_t fill); + int (*hole)(int drive); + double (*byteperiod)(int drive); + void (*stop)(int drive); + void (*poll)(int drive); } DRIVE; @@ -133,60 +138,24 @@ extern void fdd_stop(int drive); extern int fdd_empty(int drive); extern void fdd_set_rate(int drive, int drvden, int rate); -extern int motorspin; -extern int64_t motoron[FDD_NUM]; +extern int motorspin; +extern int64_t motoron[FDD_NUM]; -extern int swwp; -extern int disable_write; +extern int swwp; +extern int disable_write; -extern int defaultwriteprot; +extern int defaultwriteprot; -extern int writeprot[FDD_NUM], fwriteprot[FDD_NUM]; -extern int fdd_cur_track[FDD_NUM]; -extern int fdd_changed[FDD_NUM]; -extern int drive_empty[FDD_NUM]; -extern int drive_type[FDD_NUM]; +extern int writeprot[FDD_NUM], fwriteprot[FDD_NUM]; +extern int fdd_cur_track[FDD_NUM]; +extern int fdd_changed[FDD_NUM]; +extern int drive_empty[FDD_NUM]; +extern int drive_type[FDD_NUM]; /*Used in the Read A Track command. Only valid for fdd_readsector(). */ #define SECTOR_FIRST -2 #define SECTOR_NEXT -1 -#if 0 -/* Bits 0-3 define byte type, bit 5 defines whether it is a per-track (0) or per-sector (1) byte, if bit 7 is set, the byte is the index hole. */ -#define BYTE_GAP0 0x00 -#define BYTE_GAP1 0x10 -#define BYTE_GAP4 0x20 -#define BYTE_GAP2 0x40 -#define BYTE_GAP3 0x50 -#define BYTE_I_SYNC 0x01 -#define BYTE_ID_SYNC 0x41 -#define BYTE_DATA_SYNC 0x51 -#define BYTE_IAM_SYNC 0x02 -#define BYTE_IDAM_SYNC 0x42 -#define BYTE_DATAAM_SYNC 0x52 -#define BYTE_IAM 0x03 -#define BYTE_IDAM 0x43 -#define BYTE_DATAAM 0x53 -#define BYTE_ID 0x44 -#define BYTE_DATA 0x54 -#define BYTE_ID_CRC 0x45 -#define BYTE_DATA_CRC 0x55 - -#define BYTE_IS_FUZZY 0x80 -#define BYTE_INDEX_HOLE 0x80 /* 1 = index hole, 0 = regular byte */ -#define BYTE_IS_SECTOR 0x40 /* 1 = per-sector, 0 = per-track */ -#define BYTE_IS_POST_TRACK 0x20 /* 1 = after all sectors, 0 = before or during all sectors */ -#define BYTE_IS_DATA 0x10 /* 1 = data, 0 = id */ -#define BYTE_TYPE 0x0F /* 5 = crc, 4 = data, 3 = address mark, 2 = address mark sync, 1 = sync, 0 = gap */ - -#define BYTE_TYPE_GAP 0x00 -#define BYTE_TYPE_SYNC 0x01 -#define BYTE_TYPE_AM_SYNC 0x02 -#define BYTE_TYPE_AM 0x03 -#define BYTE_TYPE_DATA 0x04 -#define BYTE_TYPE_CRC 0x05 -#endif - typedef union { uint16_t word; uint8_t bytes[2]; @@ -194,94 +163,92 @@ typedef union { void fdd_calccrc(uint8_t byte, crc_t *crc_var); -typedef struct -{ - uint16_t (*disk_flags)(int drive); - uint16_t (*side_flags)(int drive); - void (*writeback)(int drive); - void (*set_sector)(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n); - uint8_t (*read_data)(int drive, int side, uint16_t pos); - void (*write_data)(int drive, int side, uint16_t pos, uint8_t data); - int (*format_conditions)(int drive); - int32_t (*extra_bit_cells)(int drive, int side); - uint16_t* (*encoded_data)(int drive, int side); - void (*read_revolution)(int drive); - uint32_t (*index_hole_pos)(int drive, int side); - uint32_t (*get_raw_size)(int drive, int side); - uint8_t check_crc; +typedef struct { + uint16_t (*disk_flags)(int drive); + uint16_t (*side_flags)(int drive); + void (*writeback)(int drive); + void (*set_sector)(int drive, int side, uint8_t c, uint8_t h, + uint8_t r, uint8_t n); + uint8_t (*read_data)(int drive, int side, uint16_t pos); + void (*write_data)(int drive, int side, uint16_t pos, + uint8_t data); + int (*format_conditions)(int drive); + int32_t (*extra_bit_cells)(int drive, int side); + uint16_t* (*encoded_data)(int drive, int side); + void (*read_revolution)(int drive); + uint32_t (*index_hole_pos)(int drive, int side); + uint32_t (*get_raw_size)(int drive, int side); + + uint8_t check_crc; } d86f_handler_t; -d86f_handler_t d86f_handler[FDD_NUM]; +extern const int gap3_sizes[5][8][48]; +extern d86f_handler_t d86f_handler[FDD_NUM]; -void d86f_common_handlers(int drive); +extern void d86f_setup(int drive); +extern void d86f_destroy(int drive); +extern int d86f_export(int drive, wchar_t *fn); +extern void d86f_unregister(int drive); +extern void d86f_common_handlers(int drive); +extern void d86f_set_version(int drive, uint16_t version); +extern int d86f_is_40_track(int drive); +extern void d86f_reset_index_hole_pos(int drive, int side); +extern uint16_t d86f_prepare_pretrack(int drive, int side, int iso); +extern uint16_t d86f_prepare_sector(int drive, int side, int prev_pos, + uint8_t *id_buf, uint8_t *data_buf, + int data_len, int gap2, int gap3, + int deleted, int bad_crc); +extern void d86f_set_track_pos(int drive, uint32_t track_pos); +extern void d86f_set_cur_track(int drive, int track); +extern void d86f_zero_track(int drive); +extern void d86f_initialize_last_sector_id(int drive, int c, int h, + int r, int n); +extern void d86f_initialize_linked_lists(int drive); +extern void d86f_destroy_linked_lists(int drive, int side); +extern uint16_t *common_encoded_data(int drive, int side); +extern void common_read_revolution(int drive); +extern uint32_t common_get_raw_size(int drive, int side); +extern void null_writeback(int drive); +extern void null_write_data(int drive, int side, uint16_t pos, + uint8_t data); +extern int null_format_conditions(int drive); +extern int32_t null_extra_bit_cells(int drive, int side); +extern void null_set_sector(int drive, int side, uint8_t c, uint8_t h, + uint8_t r, uint8_t n); +extern uint32_t null_index_hole_pos(int drive, int side); -int d86f_is_40_track(int drive); +extern const uint8_t dmf_r[21]; +extern const uint8_t xdf_physical_sectors[2][2]; +extern const uint8_t xdf_gap3_sizes[2][2]; +extern const uint16_t xdf_trackx_spos[2][8]; -void d86f_reset_index_hole_pos(int drive, int side); - -uint16_t d86f_prepare_pretrack(int drive, int side, int iso); -uint16_t d86f_prepare_sector(int drive, int side, int prev_pos, uint8_t *id_buf, uint8_t *data_buf, int data_len, int gap2, int gap3, int deleted, int bad_crc); - -extern int gap3_sizes[5][8][48]; - -void null_writeback(int drive); -void null_write_data(int drive, int side, uint16_t pos, uint8_t data); -int null_format_conditions(int drive); -void d86f_unregister(int drive); - -extern uint8_t dmf_r[21]; -extern uint8_t xdf_physical_sectors[2][2]; -extern uint8_t xdf_gap3_sizes[2][2]; -extern uint16_t xdf_trackx_spos[2][8]; - -typedef struct -{ - uint8_t h; - uint8_t r; +typedef struct { + uint8_t h; + uint8_t r; } xdf_id_t; -typedef union -{ - uint16_t word; - xdf_id_t id; +typedef union { + uint16_t word; + xdf_id_t id; } xdf_sector_t; -extern xdf_sector_t xdf_img_layout[2][2][46]; -extern xdf_sector_t xdf_disk_layout[2][2][38]; +extern const xdf_sector_t xdf_img_layout[2][2][46]; +extern const xdf_sector_t xdf_disk_layout[2][2][38]; -uint32_t td0_get_raw_tsize(int side_flags, int slower_rpm); -void d86f_set_track_pos(int drive, uint32_t track_pos); - -int32_t null_extra_bit_cells(int drive, int side); -uint16_t* common_encoded_data(int drive, int side); - -void common_read_revolution(int drive); -void null_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n); - -uint32_t null_index_hole_pos(int drive, int side); - -uint32_t common_get_raw_size(int drive, int side); - -typedef struct -{ - uint8_t c; - uint8_t h; - uint8_t r; - uint8_t n; +typedef struct { + uint8_t c; + uint8_t h; + uint8_t r; + uint8_t n; } sector_id_fields_t; -typedef union -{ - uint32_t dword; - uint8_t byte_array[4]; - sector_id_fields_t id; +typedef union { + uint32_t dword; + uint8_t byte_array[4]; + 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_destroy_linked_lists(int drive, int side); void d86f_set_fdc(void *fdc); void fdi_set_fdc(void *fdc); @@ -289,10 +256,6 @@ void fdd_set_fdc(void *fdc); void imd_set_fdc(void *fdc); void img_set_fdc(void *fdc); -extern void d86f_set_cur_track(int drive, int track); -extern void d86f_zero_track(int drive); - -extern int d86f_export(int drive, wchar_t *fn); #ifdef __cplusplus } diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 8105049..c09003a 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -10,10 +10,12 @@ * 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.5 2018/03/14 + * Version: @(#)fdd_86f.c 1.0.6 2018/03/16 * - * Author: Miran Grca, + * Authors: Fred N. van Kempen, + * Miran Grca, * + * Copyright 2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. * * This program is free software; you can redistribute it and/or modify @@ -55,227 +57,226 @@ #include "lzf/lzf.h" -#define CHUNK 16384 +/* + * Let's give this some more logic: + * + * Bits 4,3 = Read/write (0 = read, 1 = write, 2 = scan, 3 = verify) + * Bits 6,5 = Sector/track (0 = ID, 1 = sector, 2 = deleted sector, 3 = track) + * Bit 7 = State type (0 = idle states, 1 = active states) + */ +enum { + /* 0 ?? ?? ??? */ + STATE_IDLE = 0x00, + STATE_SECTOR_NOT_FOUND, + /* 1 00 00 ??? */ + STATE_0A_FIND_ID = 0x80, /* READ SECTOR ID */ + STATE_0A_READ_ID, -uint64_t poly = 0x42F0E1EBA9EA3693ll; /* ECMA normal */ + /* 1 01 00 ??? */ + STATE_06_FIND_ID = 0xA0, /* READ DATA */ + STATE_06_READ_ID, + STATE_06_FIND_DATA, + STATE_06_READ_DATA, -uint64_t table[256]; + /* 1 01 01 ??? */ + STATE_05_FIND_ID = 0xA8, /* WRITE DATA */ + STATE_05_READ_ID, + STATE_05_FIND_DATA, + STATE_05_WRITE_DATA, -/* Let's give this some more logic: - Bits 4,3 = Read/write (0 = read, 1 = write, 2 = scan, 3 = verify) - Bits 6,5 = Sector/track (0 = ID, 1 = sector, 2 = deleted sector, 3 = track) - Bit 7 = State type (0 = idle states, 1 = active states) -*/ -enum -{ - /* 0 ?? ?? ??? */ - STATE_IDLE = 0x00, - STATE_SECTOR_NOT_FOUND, + /* 1 01 10 ??? */ + STATE_11_FIND_ID = 0xB0, /* SCAN EQUAL,SCAN LOW/EQUAL,SCAN HIGH/EQUAL */ + STATE_11_READ_ID, + STATE_11_FIND_DATA, + STATE_11_SCAN_DATA, - /* 1 00 00 ??? */ - STATE_0A_FIND_ID = 0x80, /* READ SECTOR ID */ - STATE_0A_READ_ID, + /* 1 01 11 ??? */ + STATE_16_FIND_ID = 0xB8, /* VERIFY */ + STATE_16_READ_ID, + STATE_16_FIND_DATA, + STATE_16_VERIFY_DATA, - /* 1 01 00 ??? */ - STATE_06_FIND_ID = 0xA0, /* READ DATA */ - STATE_06_READ_ID, - STATE_06_FIND_DATA, - STATE_06_READ_DATA, + /* 1 10 00 ??? */ + STATE_0C_FIND_ID = 0xC0, /* READ DELETED DATA */ + STATE_0C_READ_ID, + STATE_0C_FIND_DATA, + STATE_0C_READ_DATA, - /* 1 01 01 ??? */ - STATE_05_FIND_ID = 0xA8, /* WRITE DATA */ - STATE_05_READ_ID, - STATE_05_FIND_DATA, - STATE_05_WRITE_DATA, + /* 1 10 01 ??? */ + STATE_09_FIND_ID = 0xC8, /* WRITE DELETED DATA */ + STATE_09_READ_ID, + STATE_09_FIND_DATA, + STATE_09_WRITE_DATA, - /* 1 01 10 ??? */ - STATE_11_FIND_ID = 0xB0, /* SCAN EQUAL, SCAN LOW OR EQUAL, SCAN HIGH OR EQUAL */ - STATE_11_READ_ID, - STATE_11_FIND_DATA, - STATE_11_SCAN_DATA, + /* 1 11 00 ??? */ + STATE_02_SPIN_TO_INDEX = 0xE0, /* READ TRACK */ + STATE_02_FIND_ID, + STATE_02_READ_ID, + STATE_02_FIND_DATA, + STATE_02_READ_DATA, - /* 1 01 11 ??? */ - STATE_16_FIND_ID = 0xB8, /* VERIFY */ - STATE_16_READ_ID, - STATE_16_FIND_DATA, - STATE_16_VERIFY_DATA, + /* 1 11 01 ??? */ + STATE_0D_SPIN_TO_INDEX = 0xE8, /* FORMAT TRACK */ + STATE_0D_FORMAT_TRACK, - /* 1 10 00 ??? */ - STATE_0C_FIND_ID = 0xC0, /* READ DELETED DATA */ - STATE_0C_READ_ID, - STATE_0C_FIND_DATA, - STATE_0C_READ_DATA, - - /* 1 10 01 ??? */ - STATE_09_FIND_ID = 0xC8, /* WRITE DELETED DATA */ - STATE_09_READ_ID, - STATE_09_FIND_DATA, - STATE_09_WRITE_DATA, - - /* 1 11 00 ??? */ - STATE_02_SPIN_TO_INDEX = 0xE0, /* READ TRACK */ - STATE_02_FIND_ID, - STATE_02_READ_ID, - STATE_02_FIND_DATA, - STATE_02_READ_DATA, - - /* 1 11 01 ??? */ - STATE_0D_SPIN_TO_INDEX = 0xE8, /* FORMAT TRACK */ - STATE_0D_FORMAT_TRACK, - - /* 1 11 11 ??? */ - STATE_0D_NOP_SPIN_TO_INDEX = 0xF8, /* FORMAT TRACK */ - STATE_0D_NOP_FORMAT_TRACK + /* 1 11 11 ??? */ + STATE_0D_NOP_SPIN_TO_INDEX = 0xF8, /* FORMAT TRACK */ + STATE_0D_NOP_FORMAT_TRACK }; -static uint16_t CRCTable[256]; +enum { + FMT_PRETRK_GAP0, + FMT_PRETRK_SYNC, + FMT_PRETRK_IAM, + FMT_PRETRK_GAP1, -#pragma pack(push,1) -typedef struct -{ - uint8_t buffer[10]; - uint32_t pos; - uint32_t len; + FMT_SECTOR_ID_SYNC, + FMT_SECTOR_IDAM, + FMT_SECTOR_ID, + FMT_SECTOR_ID_CRC, + FMT_SECTOR_GAP2, + FMT_SECTOR_DATA_SYNC, + FMT_SECTOR_DATAAM, + FMT_SECTOR_DATA, + FMT_SECTOR_DATA_CRC, + FMT_SECTOR_GAP3, + + FMT_POSTTRK_CHECK, + FMT_POSTTRK_GAP4 +}; + + +typedef struct { + uint8_t buffer[10]; + uint32_t pos; + uint32_t len; } sliding_buffer_t; -#pragma pack(pop) -#pragma pack(push,1) -typedef struct -{ - uint32_t sync_marks; - uint32_t bits_obtained; - uint32_t bytes_obtained; - uint32_t sync_pos; +typedef struct { + uint32_t sync_marks; + uint32_t bits_obtained; + uint32_t bytes_obtained; + uint32_t sync_pos; } find_t; -#pragma pack(pop) - -uint8_t encoded_fm[64] = { 0xAA, 0xAB, 0xAE, 0xAF, 0xBA, 0xBB, 0xBE, 0xBF, 0xEA, 0xEB, 0xEE, 0xEF, 0xFA, 0xFB, 0xFE, 0xFF, - 0xAA, 0xAB, 0xAE, 0xAF, 0xBA, 0xBB, 0xBE, 0xBF, 0xEA, 0xEB, 0xEE, 0xEF, 0xFA, 0xFB, 0xFE, 0xFF, - 0xAA, 0xAB, 0xAE, 0xAF, 0xBA, 0xBB, 0xBE, 0xBF, 0xEA, 0xEB, 0xEE, 0xEF, 0xFA, 0xFB, 0xFE, 0xFF, - 0xAA, 0xAB, 0xAE, 0xAF, 0xBA, 0xBB, 0xBE, 0xBF, 0xEA, 0xEB, 0xEE, 0xEF, 0xFA, 0xFB, 0xFE, 0xFF }; - -uint8_t encoded_mfm[64] = { 0xAA, 0xA9, 0xA4, 0xA5, 0x92, 0x91, 0x94, 0x95, 0x4A, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55, - 0x2A, 0x29, 0x24, 0x25, 0x12, 0x11, 0x14, 0x15, 0x4A, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55, - 0xAA, 0xA9, 0xA4, 0xA5, 0x92, 0x91, 0x94, 0x95, 0x4A, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55, - 0x2A, 0x29, 0x24, 0x25, 0x12, 0x11, 0x14, 0x15, 0x4A, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55 }; - - -enum -{ - FMT_PRETRK_GAP0, - FMT_PRETRK_SYNC, - FMT_PRETRK_IAM, - FMT_PRETRK_GAP1, - - FMT_SECTOR_ID_SYNC, - FMT_SECTOR_IDAM, - FMT_SECTOR_ID, - FMT_SECTOR_ID_CRC, - FMT_SECTOR_GAP2, - FMT_SECTOR_DATA_SYNC, - FMT_SECTOR_DATAAM, - FMT_SECTOR_DATA, - FMT_SECTOR_DATA_CRC, - FMT_SECTOR_GAP3, - - FMT_POSTTRK_CHECK, - FMT_POSTTRK_GAP4 -}; - - -#pragma pack(push,1) -typedef struct -{ - unsigned nibble0 :4; - unsigned nibble1 :4; +typedef struct { + unsigned nibble0 :4; + unsigned nibble1 :4; } split_byte_t; -#pragma pack(pop) typedef union { - uint8_t byte; - split_byte_t nibbles; + uint8_t byte; + split_byte_t nibbles; } decoded_t; - -/* Disk flags: Bit 0 Has surface data (1 = yes, 0 = no) - Bits 2, 1 Hole (3 = ED + 2000 kbps, 2 = ED, 1 = HD, 0 = DD) - Bit 3 Sides (1 = 2 sides, 0 = 1 side) - Bit 4 Write protect (1 = yes, 0 = no) - Bits 6, 5 RPM slowdown (3 = 2%, 2 = 1.5%, 1 = 1%, 0 = 0%) - Bit 7 Bitcell mode (1 = Extra bitcells count specified after disk flags, 0 = No extra bitcells) - The maximum number of extra bitcells is 1024 (which after decoding translates to 64 bytes) - Bit 8 Disk type (1 = Zoned, 0 = Fixed RPM) - Bits 10, 9 Zone type (3 = Commodore 64 zoned, 2 = Apple zoned, 1 = Pre-Apple zoned #2, 0 = Pre-Apple zoned #1) - Bit 11 Data and surface bits are stored in reverse byte endianness */ - - -static fdc_t *d86f_fdc; - - -#pragma pack(push,1) -typedef struct -{ - uint8_t c, h, r, n; - void *prev; +typedef struct { + uint8_t c, h, r, n; + void *prev; } sector_t; -#pragma pack(pop) -#pragma pack(push,1) -struct -{ - FILE *f; - uint16_t version; - uint16_t disk_flags; - int32_t extra_bit_cells[2]; - uint16_t track_encoded_data[2][53048]; - uint16_t track_surface_data[2][53048]; - uint16_t thin_track_encoded_data[2][2][53048]; - uint16_t thin_track_surface_data[2][2][53048]; - uint16_t side_flags[2]; - uint32_t index_hole_pos[2]; - uint32_t track_offset[512]; - uint32_t file_size; - sector_id_t format_sector_id; - sector_id_t last_sector; - sector_id_t req_sector; - uint32_t index_count; - uint8_t state; - uint8_t fill; - uint32_t track_pos; - uint32_t datac; - uint32_t id_pos; - uint16_t last_word[2]; - find_t id_find; - find_t data_find; - crc_t calc_crc; - crc_t track_crc; - uint8_t sector_count; - uint8_t format_state; - uint16_t satisfying_bytes; - uint16_t preceding_bit[2]; - uint16_t current_byte[2]; - uint16_t current_bit[2]; - int cur_track; - uint32_t error_condition; - int is_compressed; - int id_found; - wchar_t original_file_name[2048]; - uint8_t *filebuf; - uint8_t *outbuf; - uint32_t dma_over; - int turbo_pos; - sector_t *last_side_sector[2]; -} d86f[FDD_NUM + 1]; -#pragma pack(pop) +/* Disk flags: + * Bit 0 Has surface data (1 = yes, 0 = no) + * Bits 2, 1 Hole (3 = ED + 2000 kbps, 2 = ED, 1 = HD, 0 = DD) + * Bit 3 Sides (1 = 2 sides, 0 = 1 side) + * Bit 4 Write protect (1 = yes, 0 = no) + * Bits 6, 5 RPM slowdown (3 = 2%, 2 = 1.5%, 1 = 1%, 0 = 0%) + * Bit 7 Bitcell mode (1 = Extra bitcells count specified after + * disk flags, 0 = No extra bitcells) + * The maximum number of extra bitcells is 1024 (which + * after decoding translates to 64 bytes) + * Bit 8 Disk type (1 = Zoned, 0 = Fixed RPM) + * Bits 10, 9 Zone type (3 = Commodore 64 zoned, 2 = Apple zoned, + * 1 = Pre-Apple zoned #2, 0 = Pre-Apple zoned #1) + * Bit 11 Data and surface bits are stored in reverse byte endianness + */ +typedef struct { + FILE *f; + uint16_t version; + uint16_t disk_flags; + int32_t extra_bit_cells[2]; + uint16_t track_encoded_data[2][53048]; + uint16_t track_surface_data[2][53048]; + uint16_t thin_track_encoded_data[2][2][53048]; + uint16_t thin_track_surface_data[2][2][53048]; + uint16_t side_flags[2]; + uint32_t index_hole_pos[2]; + uint32_t track_offset[512]; + uint32_t file_size; + sector_id_t format_sector_id; + sector_id_t last_sector; + sector_id_t req_sector; + uint32_t index_count; + uint8_t state; + uint8_t fill; + uint32_t track_pos; + uint32_t datac; + uint32_t id_pos; + uint16_t last_word[2]; + find_t id_find; + find_t data_find; + crc_t calc_crc; + crc_t track_crc; + uint8_t sector_count; + uint8_t format_state; + uint16_t satisfying_bytes; + uint16_t preceding_bit[2]; + uint16_t current_byte[2]; + uint16_t current_bit[2]; + int cur_track; + uint32_t error_condition; + int is_compressed; + int id_found; + wchar_t original_file_name[2048]; + uint8_t *filebuf; + uint8_t *outbuf; + uint32_t dma_over; + int turbo_pos; + sector_t *last_side_sector[2]; +} d86f_t; #ifdef ENABLE_D86F_LOG -int d86f_do_log = ENABLE_D86F_LOG; +int d86f_do_log = ENABLE_D86F_LOG; #endif +static const uint8_t encoded_fm[64] = { + 0xaa, 0xab, 0xae, 0xaf, 0xba, 0xbb, 0xbe, 0xbf, + 0xea, 0xeb, 0xee, 0xef, 0xfa, 0xfb, 0xfe, 0xff, + 0xaa, 0xab, 0xae, 0xaf, 0xba, 0xbb, 0xbe, 0xbf, + 0xea, 0xeb, 0xee, 0xef, 0xfa, 0xfb, 0xfe, 0xff, + 0xaa, 0xab, 0xae, 0xaf, 0xba, 0xbb, 0xbe, 0xbf, + 0xea, 0xeb, 0xee, 0xef, 0xfa, 0xfb, 0xfe, 0xff, + 0xaa, 0xab, 0xae, 0xaf, 0xba, 0xbb, 0xbe, 0xbf, + 0xea, 0xeb, 0xee, 0xef, 0xfa, 0xfb, 0xfe, 0xff +}; +static const uint8_t encoded_mfm[64] = { + 0xaa, 0xa9, 0xa4, 0xa5, 0x92, 0x91, 0x94, 0x95, + 0x4a, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55, + 0x2a, 0x29, 0x24, 0x25, 0x12, 0x11, 0x14, 0x15, + 0x4a, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55, + 0xaa, 0xa9, 0xa4, 0xa5, 0x92, 0x91, 0x94, 0x95, + 0x4a, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55, + 0x2a, 0x29, 0x24, 0x25, 0x12, 0x11, 0x14, 0x15, + 0x4a, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55 +}; + +static d86f_t *d86f[FDD_NUM]; +static uint16_t CRCTable[256]; +static fdc_t *d86f_fdc; +uint64_t poly = 0x42F0E1EBA9EA3693ll; /* ECMA normal */ +uint64_t table[256]; + + +uint16_t d86f_side_flags(int drive); +int d86f_is_mfm(int drive); +void d86f_writeback(int drive); +uint8_t d86f_poll_read_data(int drive, int side, uint16_t pos); +void d86f_poll_write_data(int drive, int side, uint16_t pos, uint8_t data); +int d86f_format_conditions(int drive); + + static void d86f_log(const char *format, ...) { @@ -291,3558 +292,3513 @@ d86f_log(const char *format, ...) } -void d86f_initialize_linked_lists(int drive) +static void +setup_crc(uint16_t poly) { - d86f[drive].last_side_sector[0] = NULL; - d86f[drive].last_side_sector[1] = NULL; + int c = 256, bc; + uint16_t temp; + + while(c--) { + temp = c << 8; + bc = 8; + + while (bc--) { + if (temp & 0x8000) + temp = (temp << 1) ^ poly; + else + temp <<= 1; + + CRCTable[c] = temp; + } + } } -void d86f_destroy_linked_lists(int drive, int side) -{ - sector_t *s; - sector_t *t; - if (d86f[drive].last_side_sector[side]) { - 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; +void +d86f_destroy_linked_lists(int drive, int side) +{ + d86f_t *dev = d86f[drive]; + sector_t *s, *t; + + if (dev == NULL) return; + + if (dev->last_side_sector[side]) { + s = dev->last_side_sector[side]; + while (s) { + t = s->prev; + free(s); + s = NULL; + if (! t) + break; + s = t; } + dev->last_side_sector[side] = NULL; + } } -static void d86f_setupcrc(uint16_t poly) + +static int +d86f_has_surface_desc(int drive) { - int c = 256, bc; - uint16_t crctemp; + return (d86f_handler[drive].disk_flags(drive) & 1); +} - while(c--) - { - crctemp = c << 8; - bc = 8; - while(bc--) - { - if(crctemp & 0x8000) - { - crctemp = (crctemp << 1) ^ poly; - } - else - { - crctemp <<= 1; - } +int +d86f_get_sides(int drive) +{ + return ((d86f_handler[drive].disk_flags(drive) >> 3) & 1) + 1; +} + + +int +d86f_get_rpm_mode(int drive) +{ + return (d86f_handler[drive].disk_flags(drive) & 0x60) >> 5; +} + +int +d86f_reverse_bytes(int drive) +{ + return (d86f_handler[drive].disk_flags(drive) & 0x800) >> 11; +} + + +uint16_t +d86f_disk_flags(int drive) +{ + d86f_t *dev = d86f[drive]; + + return dev->disk_flags; +} + + +uint32_t +d86f_index_hole_pos(int drive, int side) +{ + d86f_t *dev = d86f[drive]; + + return dev->index_hole_pos[side]; +} + + +uint32_t +null_index_hole_pos(int drive, int side) +{ + return 0; +} + + +uint16_t +null_disk_flags(int drive) +{ + return 0x09; +} + + +uint16_t +null_side_flags(int drive) +{ + return 0x0A; +} + + +void +null_writeback(int drive) +{ + return; +} + + +void +null_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) +{ + return; +} + + +void +null_write_data(int drive, int side, uint16_t pos, uint8_t data) +{ + return; +} + + +int +null_format_conditions(int drive) +{ + return 0; +} + + +int32_t +d86f_extra_bit_cells(int drive, int side) +{ + d86f_t *dev = d86f[drive]; + + return dev->extra_bit_cells[side]; +} + + +int32_t +null_extra_bit_cells(int drive, int side) +{ + return 0; +} + + +uint16_t* +common_encoded_data(int drive, int side) +{ + d86f_t *dev = d86f[drive]; + + return dev->track_encoded_data[side]; +} + + +void +common_read_revolution(int drive) +{ + return; +} + + +uint16_t +d86f_side_flags(int drive) +{ + d86f_t *dev = d86f[drive]; + int side; + + side = fdd_get_head(drive); + + return dev->side_flags[side]; +} + + +uint16_t +d86f_track_flags(int drive) +{ + uint16_t dr, rr, tf; + + tf = d86f_handler[drive].side_flags(drive); + rr = tf & 0x67; + dr = fdd_get_flags(drive) & 7; + tf &= ~0x67; + + switch (rr) { + case 0x02: + case 0x21: + /* 1 MB unformatted medium, treat these two as equivalent. */ + switch (dr) { + case 0x06: + /* 5.25" Single-RPM HD drive, treat as 300 kbps, 360 rpm. */ + tf |= 0x21; + break; + + default: + /* Any other drive, treat as 250 kbps, 300 rpm. */ + tf |= 0x02; + break; } + break; - CRCTable[c] = crctemp; - } -} + default: + tf |= rr; + break; + } -static int d86f_has_surface_desc(int drive) -{ - return (d86f_handler[drive].disk_flags(drive) & 1); -} - -int d86f_get_sides(int drive) -{ - return ((d86f_handler[drive].disk_flags(drive) >> 3) & 1) + 1; -} - -int d86f_get_rpm_mode(int drive) -{ - return (d86f_handler[drive].disk_flags(drive) & 0x60) >> 5; -} - -int d86f_reverse_bytes(int drive) -{ - return (d86f_handler[drive].disk_flags(drive) & 0x800) >> 11; -} - -uint16_t d86f_side_flags(int drive); -int d86f_is_mfm(int drive); -void d86f_writeback(int drive); -uint8_t d86f_poll_read_data(int drive, int side, uint16_t pos); -void d86f_poll_write_data(int drive, int side, uint16_t pos, uint8_t data); -int d86f_format_conditions(int drive); - -uint16_t d86f_disk_flags(int drive) -{ - return d86f[drive].disk_flags; + return tf; } -uint32_t d86f_index_hole_pos(int drive, int side) +uint32_t +common_get_raw_size(int drive, int side) { - return d86f[drive].index_hole_pos[side]; + double rate = 0.0; + double rpm, rpm_diff; + double size = 100000.0; + int mfm; + + mfm = d86f_is_mfm(drive); + rpm = ((d86f_track_flags(drive) & 0xE0) == 0x20) ? 360.0 : 300.0; + rpm_diff = 1.0; + + switch (d86f_get_rpm_mode(drive)) { + case 1: + rpm_diff = 1.01; + break; + + case 2: + rpm_diff = 1.015; + break; + + case 3: + rpm_diff = 1.02; + break; + + default: + rpm_diff = 1.0; + break; + } + + switch (d86f_track_flags(drive) & 7) { + case 0: + rate = 500.0; + break; + + case 1: + rate = 300.0; + break; + + case 2: + rate = 250.0; + break; + + case 3: + rate = 1000.0; + break; + + case 5: + rate = 2000.0; + break; + + default: + rate = 250.0; + break; + } + + if (! mfm) rate /= 2.0; + + size = (size / 250.0) * rate; + size = (size * 300.0) / rpm; + size *= rpm_diff; + + /* + * Round down to a multiple of 16 and add the extra bit cells, + * then return. + */ + return ((((uint32_t) size) >> 4) << 4) + d86f_handler[drive].extra_bit_cells(drive, side); } -uint32_t null_index_hole_pos(int drive, int side) + +void +d86f_set_version(int drive, uint16_t version) { - return 0; + d86f_t *dev = d86f[drive]; + + dev->version = version; } -uint16_t null_disk_flags(int drive) + +void +d86f_unregister(int drive) { - return 0x09; + d86f_t *dev = d86f[drive]; + + if (dev == NULL) return; + + d86f_handler[drive].disk_flags = null_disk_flags; + d86f_handler[drive].side_flags = null_side_flags; + d86f_handler[drive].writeback = null_writeback; + d86f_handler[drive].set_sector = null_set_sector; + 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; + d86f_handler[drive].encoded_data = common_encoded_data; + d86f_handler[drive].read_revolution = common_read_revolution; + 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 = 0; + + dev->version = 0x0063; /* Proxied formats report as version 0.99. */ } -uint16_t null_side_flags(int drive) + +void +d86f_register_86f(int drive) { - return 0x0A; + d86f_handler[drive].disk_flags = d86f_disk_flags; + d86f_handler[drive].side_flags = d86f_side_flags; + d86f_handler[drive].writeback = d86f_writeback; + d86f_handler[drive].set_sector = null_set_sector; + d86f_handler[drive].write_data = null_write_data; + d86f_handler[drive].format_conditions = d86f_format_conditions; + d86f_handler[drive].extra_bit_cells = d86f_extra_bit_cells; + d86f_handler[drive].encoded_data = common_encoded_data; + d86f_handler[drive].read_revolution = common_read_revolution; + d86f_handler[drive].index_hole_pos = d86f_index_hole_pos; + d86f_handler[drive].get_raw_size = common_get_raw_size; + d86f_handler[drive].check_crc = 1; } -void null_writeback(int drive) + +int +d86f_get_array_size(int drive, int side) { - return; -} + int array_size; + int hole, rm; -void null_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) -{ - return; -} + rm = d86f_get_rpm_mode(drive); + hole = (d86f_handler[drive].disk_flags(drive) & 6) >> 1; + switch (hole) { + case 0: + case 1: + default: + array_size = 12500; + switch (rm) { + case 1: + array_size = 12625; + break; -void null_write_data(int drive, int side, uint16_t pos, uint8_t data) -{ - return; -} + case 2: + array_size = 12687; + break; -int null_format_conditions(int drive) -{ - return 0; -} + case 3: + array_size = 12750; + break; -int32_t d86f_extra_bit_cells(int drive, int side) -{ - return d86f[drive].extra_bit_cells[side]; -} - -int32_t null_extra_bit_cells(int drive, int side) -{ - return 0; -} - -uint16_t* common_encoded_data(int drive, int side) -{ - return d86f[drive].track_encoded_data[side]; -} - -void common_read_revolution(int drive) -{ - return; -} - -uint16_t d86f_side_flags(int drive) -{ - int side = 0; - side = fdd_get_head(drive); - return d86f[drive].side_flags[side]; -} - -uint16_t d86f_track_flags(int drive) -{ - uint16_t tf = 0; - uint16_t rr = 0; - uint16_t dr = 0; - - tf = d86f_handler[drive].side_flags(drive); - rr = tf & 0x67; - dr = fdd_get_flags(drive) & 7; - tf &= ~0x67; - - switch (rr) - { - case 0x02: - case 0x21: - /* 1 MB unformatted medium, treat these two as equivalent. */ - switch (dr) - { - case 0x06: - /* 5.25" Single-RPM HD drive, treat as 300 kbps, 360 rpm. */ - tf |= 0x21; - break; - default: - /* Any other drive, treat as 250 kbps, 300 rpm. */ - tf |= 0x02; - break; - } - break; - default: - tf |= rr; - break; - } - return tf; -} - -uint32_t common_get_raw_size(int drive, int side) -{ - double rate = 0.0; - int mfm = 0; - double rpm; - double rpm_diff = 0.0; - double size = 100000.0; - - mfm = d86f_is_mfm(drive); - rpm = ((d86f_track_flags(drive) & 0xE0) == 0x20) ? 360.0 : 300.0; - rpm_diff = 1.0; - - switch (d86f_get_rpm_mode(drive)) - { - case 1: - rpm_diff = 1.01; - break; - case 2: - rpm_diff = 1.015; - break; - case 3: - rpm_diff = 1.02; - break; - default: - rpm_diff = 1.0; - break; - } - switch (d86f_track_flags(drive) & 7) - { - case 0: - rate = 500.0; - break; - case 1: - rate = 300.0; - break; - case 2: - rate = 250.0; - break; - case 3: - rate = 1000.0; - break; - case 5: - rate = 2000.0; - break; - default: - rate = 250.0; - break; - } - if (!mfm) rate /= 2.0; - size = (size / 250.0) * rate; - size = (size * 300.0) / rpm; - size *= rpm_diff; - /* Round down to a multiple of 16 and add the extra bit cells, then return. */ - 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; - d86f_handler[drive].side_flags = null_side_flags; - d86f_handler[drive].writeback = null_writeback; - d86f_handler[drive].set_sector = null_set_sector; - 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; - d86f_handler[drive].encoded_data = common_encoded_data; - d86f_handler[drive].read_revolution = common_read_revolution; - 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 = 0; - d86f[drive].version = 0x0063; /* Proxied formats report as version 0.99. */ -} - -void d86f_register_86f(int drive) -{ - d86f_handler[drive].disk_flags = d86f_disk_flags; - d86f_handler[drive].side_flags = d86f_side_flags; - d86f_handler[drive].writeback = d86f_writeback; - d86f_handler[drive].set_sector = null_set_sector; - d86f_handler[drive].write_data = null_write_data; - d86f_handler[drive].format_conditions = d86f_format_conditions; - d86f_handler[drive].extra_bit_cells = d86f_extra_bit_cells; - d86f_handler[drive].encoded_data = common_encoded_data; - d86f_handler[drive].read_revolution = common_read_revolution; - d86f_handler[drive].index_hole_pos = d86f_index_hole_pos; - d86f_handler[drive].get_raw_size = common_get_raw_size; - d86f_handler[drive].check_crc = 1; -} - -int d86f_get_array_size(int drive, int side) -{ - int array_size = 0; - int rm = 0; - int hole = 0; - rm = d86f_get_rpm_mode(drive); - hole = (d86f_handler[drive].disk_flags(drive) & 6) >> 1; - switch (hole) - { - case 0: - case 1: - default: - array_size = 12500; - switch (rm) - { - case 1: - array_size = 12625; - break; - case 2: - array_size = 12687; - break; - case 3: - array_size = 12750; - break; - default: - array_size = 12500; - break; - } - break; - case 2: - array_size = 25000; - switch (rm) - { - case 1: - array_size = 25250; - break; - case 2: - array_size = 25375; - break; - case 3: - array_size = 25500; - break; - default: - array_size = 25000; - break; - } - break; - case 3: - array_size = 50000; - switch (rm) - { - case 1: - array_size = 50500; - break; - case 2: - array_size = 50750; - break; - case 3: - array_size = 51000; - break; - default: - array_size = 50000; - break; - } - break; - } - array_size <<= 4; - array_size += d86f_handler[drive].extra_bit_cells(drive, side); - array_size >>= 4; - if (d86f_handler[drive].extra_bit_cells(drive, side) & 15) - { - array_size++; - } - return array_size; -} - -int d86f_valid_bit_rate(int drive) -{ - int rate = 0; - int hole = 0; - rate = fdc_get_bit_rate(d86f_fdc); - hole = (d86f_handler[drive].disk_flags(drive) & 6) >> 1; - switch (hole) - { - case 0: /* DD */ - if (!rate && (fdd_get_flags(drive) & 0x10)) return 1; - if ((rate < 1) || (rate > 2)) return 0; - return 1; - case 1: /* HD */ - if (rate != 0) return 0; - return 1; - case 2: /* ED */ - if (rate != 3) return 0; - return 1; - case 3: /* ED with 2000 kbps support */ - if (rate < 3) return 0; - return 1; - } - return 1; -} - -int d86f_hole(int drive) -{ - if (((d86f_handler[drive].disk_flags(drive) >> 1) & 3) == 3) return 2; - return (d86f_handler[drive].disk_flags(drive) >> 1) & 3; -} - -uint8_t d86f_get_encoding(int drive) -{ - return (d86f_track_flags(drive) & 0x18) >> 3; -} - -double d86f_byteperiod(int drive) -{ - switch (d86f_track_flags(drive) & 0x0f) - { - case 0x02: /* 125 kbps, FM */ - return 4.0; - case 0x01: /* 150 kbps, FM */ - return 20.0 / 6.0; - case 0x0A: /* 250 kbps, MFM */ - case 0x00: /* 250 kbps, FM */ - return 2.0; - case 0x09: /* 300 kbps, MFM */ - return 10.0 / 6.0; - case 0x08: /* 500 kbps, MFM */ - return 1.0; - case 0x0B: /* 1000 kbps, MFM */ - return 0.5; - case 0x0D: /* 2000 kbps, MFM */ - return 0.25; - default: - return 2.0; - } - return 2.0; -} - -int d86f_is_mfm(int drive) -{ - return (d86f_track_flags(drive) & 8) ? 1 : 0; -} - -uint32_t d86f_get_data_len(int drive) -{ - if (d86f[drive].req_sector.id.n) - { - if (d86f[drive].req_sector.id.n == 8) return 32768; - return (128 << ((uint32_t) d86f[drive].req_sector.id.n)); - } - else - { - if (fdc_get_dtl(d86f_fdc) < 128) - { - return fdc_get_dtl(d86f_fdc); + default: + break; } - else - { - return (128 << ((uint32_t) d86f[drive].req_sector.id.n)); + break; + + case 2: + array_size = 25000; + switch (rm) { + case 1: + array_size = 25250; + break; + + case 2: + array_size = 25375; + break; + + case 3: + array_size = 25500; + break; + + default: + break; } - } -} + break; -uint32_t d86f_has_extra_bit_cells(int drive) -{ - return (d86f_handler[drive].disk_flags(drive) >> 7) & 1; -} + case 3: + array_size = 50000; + switch (rm) { + case 1: + array_size = 50500; + break; -uint32_t d86f_header_size(int drive) -{ - return 8; -} + case 2: + array_size = 50750; + break; -static uint16_t d86f_encode_get_data(uint8_t dat) -{ - uint16_t temp; - temp = 0; - if (dat & 0x01) temp |= 1; - if (dat & 0x02) temp |= 4; - if (dat & 0x04) temp |= 16; - if (dat & 0x08) temp |= 64; - if (dat & 0x10) temp |= 256; - if (dat & 0x20) temp |= 1024; - if (dat & 0x40) temp |= 4096; - if (dat & 0x80) temp |= 16384; - return temp; -} + case 3: + array_size = 51000; + break; -static uint16_t d86f_encode_get_clock(uint8_t dat) -{ - uint16_t temp; - temp = 0; - if (dat & 0x01) temp |= 2; - if (dat & 0x02) temp |= 8; - if (dat & 0x40) temp |= 32; - if (dat & 0x08) temp |= 128; - if (dat & 0x10) temp |= 512; - if (dat & 0x20) temp |= 2048; - if (dat & 0x40) temp |= 8192; - if (dat & 0x80) temp |= 32768; - return temp; -} - -int d86f_format_conditions(int drive) -{ - return d86f_valid_bit_rate(drive); -} - -int d86f_wrong_densel(int drive) -{ - int is_3mode = 0; - - if ((fdd_get_flags(drive) & 7) == 3) - { - is_3mode = 1; - } - - switch (d86f_hole(drive)) - { - case 0: - default: - if (fdd_is_dd(drive)) - { - return 0; - } - if (fdd_get_densel(drive)) - { - return 1; - } - else - { - return 0; - } - break; - case 1: - if (fdd_is_dd(drive)) - { - return 1; - } - if (fdd_get_densel(drive)) - { - return 0; - } - else - { - if (is_3mode) - { - return 0; - } - else - { - return 1; - } - } - break; - case 2: - if (fdd_is_dd(drive) || !fdd_is_ed(drive)) - { - return 1; - } - if (fdd_get_densel(drive)) - { - return 0; - } - else - { - return 1; - } - break; - } -} - -int d86f_can_format(int drive) -{ - int temp; - temp = !writeprot[drive]; - temp = temp && !fdc_get_swwp(d86f_fdc); - temp = temp && fdd_can_read_medium(real_drive(d86f_fdc, drive)); - temp = temp && d86f_handler[drive].format_conditions(drive); /* Allows proxied formats to add their own extra conditions to formatting. */ - temp = temp && !d86f_wrong_densel(drive); - return temp; -} - -uint16_t d86f_encode_byte(int drive, int sync, decoded_t b, decoded_t prev_b) -{ - uint8_t encoding = d86f_get_encoding(drive); - uint8_t bits89AB = prev_b.nibbles.nibble0; - uint8_t bits7654 = b.nibbles.nibble1; - uint8_t bits3210 = b.nibbles.nibble0; - uint16_t encoded_7654, encoded_3210, result; - if (encoding > 1) return 0xFF; - if (sync) - { - result = d86f_encode_get_data(b.byte); - if (encoding) - { - switch(b.byte) - { - case 0xA1: return result | d86f_encode_get_clock(0x0A); - case 0xC2: return result | d86f_encode_get_clock(0x14); - case 0xF8: return result | d86f_encode_get_clock(0x03); - case 0xFB: case 0xFE: return result | d86f_encode_get_clock(0x00); - case 0xFC: return result | d86f_encode_get_clock(0x01); - } + default: + break; } - else - { - switch(b.byte) - { - case 0xF8: case 0xFB: case 0xFE: return result | d86f_encode_get_clock(0xC7); - case 0xFC: return result | d86f_encode_get_clock(0xD7); - } - } - } - bits3210 += ((bits7654 & 3) << 4); - bits7654 += ((bits89AB & 3) << 4); - encoded_3210 = (encoding == 1) ? encoded_mfm[bits3210] : encoded_fm[bits3210]; - encoded_7654 = (encoding == 1) ? encoded_mfm[bits7654] : encoded_fm[bits7654]; - result = (encoded_7654 << 8) | encoded_3210; - return result; + break; + } + + array_size <<= 4; + array_size += d86f_handler[drive].extra_bit_cells(drive, side); + array_size >>= 4; + + if (d86f_handler[drive].extra_bit_cells(drive, side) & 15) + array_size++; + + return array_size; } -static int d86f_get_bitcell_period(int drive) + +int +d86f_valid_bit_rate(int drive) { - double rate = 0.0; - int mfm = 0; - int tflags = 0; - double rpm = 0; - double size = 8000.0; + int hole, rate; - tflags = d86f_track_flags(drive); - - mfm = (tflags & 8) ? 1 : 0; - rpm = ((tflags & 0xE0) == 0x20) ? 360.0 : 300.0; - - switch (tflags & 7) - { - case 0: - rate = 500.0; - break; - case 1: - rate = 300.0; - break; - case 2: - rate = 250.0; - break; - case 3: - rate = 1000.0; - break; - case 5: - rate = 2000.0; - break; - } - if (!mfm) rate /= 2.0; - size = (size * 250.0) / rate; - size = (size * 300.0) / rpm; - size = (size * fdd_getrpm(real_drive(d86f_fdc, drive))) / 300.0; - return (int) size; -} - -int d86f_can_read_address(int drive) -{ - int temp = 0; - temp = (fdc_get_bitcell_period(d86f_fdc) == d86f_get_bitcell_period(drive)); - temp = temp && fdd_can_read_medium(real_drive(d86f_fdc, drive)); - temp = temp && (fdc_is_mfm(d86f_fdc) == d86f_is_mfm(drive)); - temp = temp && (d86f_get_encoding(drive) <= 1); - return temp; -} - -void d86f_get_bit(int drive, int side) -{ - uint32_t track_word; - uint32_t track_bit; - uint16_t encoded_data; - uint16_t surface_data = 0; - uint16_t current_bit; - uint16_t surface_bit; - - track_word = d86f[drive].track_pos >> 4; - /* We need to make sure we read the bits from MSB to LSB. */ - track_bit = 15 - (d86f[drive].track_pos & 15); - - if (d86f_reverse_bytes(drive)) - { - /* Image is in reverse endianness, read the data as is. */ - encoded_data = d86f_handler[drive].encoded_data(drive, side)[track_word]; - } - else - { - /* We store the words as big endian, so we need to convert them to little endian when reading. */ - encoded_data = (d86f_handler[drive].encoded_data(drive, side)[track_word] & 0xFF) << 8; - encoded_data |= (d86f_handler[drive].encoded_data(drive, side)[track_word] >> 8); - } - - if (d86f_has_surface_desc(drive)) - { - if (d86f_reverse_bytes(drive)) - { - surface_data = d86f[drive].track_surface_data[side][track_word] & 0xFF; - } - else - { - surface_data = (d86f[drive].track_surface_data[side][track_word] & 0xFF) << 8; - surface_data |= (d86f[drive].track_surface_data[side][track_word] >> 8); - } - } - - current_bit = (encoded_data >> track_bit) & 1; - d86f[drive].last_word[side] <<= 1; - - if (d86f_has_surface_desc(drive)) - { - surface_bit = (surface_data >> track_bit) & 1; - if (!surface_bit) - { - if (!current_bit) - { - /* Bit is 0 and is not set to fuzzy, we add it as read. */ - d86f[drive].last_word[side] |= 1; - } - else - { - /* Bit is 1 and is not set to fuzzy, we add it as read. */ - d86f[drive].last_word[side] |= 1; - } - } - else - { - if (current_bit) - { - /* Bit is 1 and is set to fuzzy, we randomly generate it. */ - d86f[drive].last_word[side] |= (random_generate() & 1); - } - } - } - else - { - d86f[drive].last_word[side] |= current_bit; - } -} - -void d86f_put_bit(int drive, int side, int bit) -{ - uint32_t track_word; - uint32_t track_bit; - uint16_t encoded_data; - uint16_t surface_data = 0; - uint16_t current_bit; - uint16_t surface_bit; - - if (fdc_get_diswr(d86f_fdc)) - return; - - track_word = d86f[drive].track_pos >> 4; - /* We need to make sure we read the bits from MSB to LSB. */ - track_bit = 15 - (d86f[drive].track_pos & 15); - - if (d86f_reverse_bytes(drive)) - { - /* Image is in reverse endianness, read the data as is. */ - encoded_data = d86f_handler[drive].encoded_data(drive, side)[track_word]; - } - else - { - /* We store the words as big endian, so we need to convert them to little endian when reading. */ - encoded_data = (d86f_handler[drive].encoded_data(drive, side)[track_word] & 0xFF) << 8; - encoded_data |= (d86f_handler[drive].encoded_data(drive, side)[track_word] >> 8); - } - - if (d86f_has_surface_desc(drive)) - { - if (d86f_reverse_bytes(drive)) - { - surface_data = d86f[drive].track_surface_data[side][track_word] & 0xFF; - } - else - { - surface_data = (d86f[drive].track_surface_data[side][track_word] & 0xFF) << 8; - surface_data |= (d86f[drive].track_surface_data[side][track_word] >> 8); - } - } - - current_bit = (encoded_data >> track_bit) & 1; - d86f[drive].last_word[side] <<= 1; - - if (d86f_has_surface_desc(drive)) - { - surface_bit = (surface_data >> track_bit) & 1; - if (!surface_bit) - { - if (!current_bit) - { - /* Bit is 0 and is not set to fuzzy, we overwrite it as is. */ - d86f[drive].last_word[side] |= bit; - current_bit = bit; - } - else - { - /* Bit is 1 and is not set to fuzzy, we overwrite it as is. */ - d86f[drive].last_word[side] |= bit; - current_bit = bit; - } - } - else - { - if (current_bit) - { - /* Bit is 1 and is set to fuzzy, we overwrite it with a non-fuzzy bit. */ - d86f[drive].last_word[side] |= bit; - current_bit = bit; - surface_bit = 0; - } - } - - surface_data &= ~(1 << track_bit); - surface_data |= (surface_bit << track_bit); - if (d86f_reverse_bytes(drive)) - { - d86f[drive].track_surface_data[side][track_word] = surface_data; - } - else - { - d86f[drive].track_surface_data[side][track_word] = (surface_data & 0xFF) << 8; - d86f[drive].track_surface_data[side][track_word] |= (surface_data >> 8); - } - } - else - { - d86f[drive].last_word[side] |= bit; - current_bit = bit; - } - - encoded_data &= ~(1 << track_bit); - encoded_data |= (current_bit << track_bit); - - if (d86f_reverse_bytes(drive)) - { - d86f_handler[drive].encoded_data(drive, side)[track_word] = encoded_data; - } - else - { - d86f_handler[drive].encoded_data(drive, side)[track_word] = (encoded_data & 0xFF) << 8; - d86f_handler[drive].encoded_data(drive, side)[track_word] |= (encoded_data >> 8); - } -} - -static uint8_t decodefm(int drive, uint16_t dat) -{ - uint8_t temp = 0; - /* We write the encoded bytes in big endian, so we process the two 8-bit halves swapped here. */ - if (dat & 0x0001) temp |= 1; - if (dat & 0x0004) temp |= 2; - if (dat & 0x0010) temp |= 4; - if (dat & 0x0040) temp |= 8; - if (dat & 0x0100) temp |= 16; - if (dat & 0x0400) temp |= 32; - if (dat & 0x1000) temp |= 64; - if (dat & 0x4000) temp |= 128; - return temp; -} - -void fdd_calccrc(uint8_t byte, crc_t *crc_var) -{ - crc_var->word = (crc_var->word << 8) ^ CRCTable[(crc_var->word >> 8)^byte]; -} - -static void d86f_calccrc(int drive, uint8_t byte) -{ - fdd_calccrc(byte, &(d86f[drive].calc_crc)); -} - -int d86f_word_is_aligned(int drive, int side, uint32_t base_pos) -{ - uint32_t adjusted_track_pos = d86f[drive].track_pos; - - if (base_pos == 0xFFFFFFFF) - { - return 0; - } - - /* This is very important, it makes sure alignment is detected correctly even across the index hole of a track whose length is not divisible by 16. */ - if (adjusted_track_pos < base_pos) - { - adjusted_track_pos += d86f_handler[drive].get_raw_size(drive, side); - } - - if ((adjusted_track_pos & 15) == (base_pos & 15)) - { + rate = fdc_get_bit_rate(d86f_fdc); + hole = (d86f_handler[drive].disk_flags(drive) & 6) >> 1; + switch (hole) { + case 0: /* DD */ + if (!rate && (fdd_get_flags(drive) & 0x10)) return 1; + if ((rate < 1) || (rate > 2)) return 0; return 1; - } - else - { - return 0; - } + + case 1: /* HD */ + if (rate != 0) return 0; + return 1; + + case 2: /* ED */ + if (rate != 3) return 0; + return 1; + + case 3: /* ED with 2000 kbps support */ + if (rate < 3) return 0; + return 1; + } + + return 1; //FIXME: should be 0 for error? } + +int +d86f_hole(int drive) +{ + if (((d86f_handler[drive].disk_flags(drive) >> 1) & 3) == 3) + return 2; + + return (d86f_handler[drive].disk_flags(drive) >> 1) & 3; +} + + +uint8_t +d86f_get_encoding(int drive) +{ + return (d86f_track_flags(drive) & 0x18) >> 3; +} + + +double +d86f_byteperiod(int drive) +{ + switch (d86f_track_flags(drive) & 0x0f) { + case 0x02: /* 125 kbps, FM */ + return 4.0; + + case 0x01: /* 150 kbps, FM */ + return 20.0 / 6.0; + + case 0x0a: /* 250 kbps, MFM */ + case 0x00: /* 250 kbps, FM */ + return 2.0; + + case 0x09: /* 300 kbps, MFM */ + return 10.0 / 6.0; + + case 0x08: /* 500 kbps, MFM */ + return 1.0; + + case 0x0b: /* 1000 kbps, MFM */ + return 0.5; + + case 0x0d: /* 2000 kbps, MFM */ + return 0.25; + + default: + break; + } + + return 2.0; +} + + +int +d86f_is_mfm(int drive) +{ + return (d86f_track_flags(drive) & 8) ? 1 : 0; +} + + +uint32_t +d86f_get_data_len(int drive) +{ + d86f_t *dev = d86f[drive]; + + if (dev->req_sector.id.n) { + if (dev->req_sector.id.n == 8) return 32768; + return (128 << ((uint32_t) dev->req_sector.id.n)); + } else { + if (fdc_get_dtl(d86f_fdc) < 128) + return fdc_get_dtl(d86f_fdc); + else + return (128 << ((uint32_t) dev->req_sector.id.n)); + } +} + + +uint32_t +d86f_has_extra_bit_cells(int drive) +{ + return (d86f_handler[drive].disk_flags(drive) >> 7) & 1; +} + + +uint32_t +d86f_header_size(int drive) +{ + return 8; +} + + +static uint16_t +d86f_encode_get_data(uint8_t dat) +{ + uint16_t temp; + temp = 0; + + if (dat & 0x01) temp |= 1; + if (dat & 0x02) temp |= 4; + if (dat & 0x04) temp |= 16; + if (dat & 0x08) temp |= 64; + if (dat & 0x10) temp |= 256; + if (dat & 0x20) temp |= 1024; + if (dat & 0x40) temp |= 4096; + if (dat & 0x80) temp |= 16384; + + return temp; +} + + +static uint16_t +d86f_encode_get_clock(uint8_t dat) +{ + uint16_t temp; + temp = 0; + + if (dat & 0x01) temp |= 2; + if (dat & 0x02) temp |= 8; + if (dat & 0x40) temp |= 32; + if (dat & 0x08) temp |= 128; + if (dat & 0x10) temp |= 512; + if (dat & 0x20) temp |= 2048; + if (dat & 0x40) temp |= 8192; + if (dat & 0x80) temp |= 32768; + + return temp; +} + + +int +d86f_format_conditions(int drive) +{ + return d86f_valid_bit_rate(drive); +} + + +int +d86f_wrong_densel(int drive) +{ + int is_3mode = 0; + + if ((fdd_get_flags(drive) & 7) == 3) + is_3mode = 1; + + switch (d86f_hole(drive)) { + case 0: + default: + if (fdd_is_dd(drive)) + return 0; + if (fdd_get_densel(drive)) + return 1; + else + return 0; + break; + + case 1: + if (fdd_is_dd(drive)) + return 1; + if (fdd_get_densel(drive)) + return 0; + else { + if (is_3mode) + return 0; + else + return 1; + } + break; + + case 2: + if (fdd_is_dd(drive) || !fdd_is_ed(drive)) + return 1; + if (fdd_get_densel(drive)) + return 0; + else + return 1; + break; + } +} + + +int +d86f_can_format(int drive) +{ + int temp; + + temp = !writeprot[drive]; + temp = temp && !fdc_get_swwp(d86f_fdc); + temp = temp && fdd_can_read_medium(real_drive(d86f_fdc, drive)); + temp = temp && d86f_handler[drive].format_conditions(drive); /* Allows proxied formats to add their own extra conditions to formatting. */ + temp = temp && !d86f_wrong_densel(drive); + + return temp; +} + + +uint16_t +d86f_encode_byte(int drive, int sync, decoded_t b, decoded_t prev_b) +{ + uint8_t encoding = d86f_get_encoding(drive); + uint8_t bits89AB = prev_b.nibbles.nibble0; + uint8_t bits7654 = b.nibbles.nibble1; + uint8_t bits3210 = b.nibbles.nibble0; + uint16_t encoded_7654, encoded_3210, result; + + if (encoding > 1) return 0xff; + + if (sync) { + result = d86f_encode_get_data(b.byte); + if (encoding) { + switch(b.byte) { + case 0xa1: + return result | d86f_encode_get_clock(0x0a); + + case 0xc2: + return result | d86f_encode_get_clock(0x14); + + case 0xf8: + return result | d86f_encode_get_clock(0x03); + + case 0xfb: + case 0xfe: + return result | d86f_encode_get_clock(0x00); + + case 0xfc: + return result | d86f_encode_get_clock(0x01); + } + } else { + switch(b.byte) { + case 0xf8: + case 0xfb: + case 0xfe: + return result | d86f_encode_get_clock(0xc7); + + case 0xfc: + return result | d86f_encode_get_clock(0xd7); + } + } + } + + bits3210 += ((bits7654 & 3) << 4); + bits7654 += ((bits89AB & 3) << 4); + encoded_3210 = (encoding == 1) ? encoded_mfm[bits3210] : encoded_fm[bits3210]; + encoded_7654 = (encoding == 1) ? encoded_mfm[bits7654] : encoded_fm[bits7654]; + result = (encoded_7654 << 8) | encoded_3210; + + return result; +} + + +static int +d86f_get_bitcell_period(int drive) +{ + double rate = 0.0; + int mfm = 0; + int tflags = 0; + double rpm = 0; + double size = 8000.0; + + tflags = d86f_track_flags(drive); + + mfm = (tflags & 8) ? 1 : 0; + rpm = ((tflags & 0xE0) == 0x20) ? 360.0 : 300.0; + + switch (tflags & 7) { + case 0: + rate = 500.0; + break; + + case 1: + rate = 300.0; + break; + + case 2: + rate = 250.0; + break; + + case 3: + rate = 1000.0; + break; + + case 5: + rate = 2000.0; + break; + } + + if (! mfm) + rate /= 2.0; + size = (size * 250.0) / rate; + size = (size * 300.0) / rpm; + size = (size * fdd_getrpm(real_drive(d86f_fdc, drive))) / 300.0; + + return (int)size; +} + + +int +d86f_can_read_address(int drive) +{ + int temp; + + temp = (fdc_get_bitcell_period(d86f_fdc) == d86f_get_bitcell_period(drive)); + temp = temp && fdd_can_read_medium(real_drive(d86f_fdc, drive)); + temp = temp && (fdc_is_mfm(d86f_fdc) == d86f_is_mfm(drive)); + temp = temp && (d86f_get_encoding(drive) <= 1); + + return temp; +} + + +void +d86f_get_bit(int drive, int side) +{ + d86f_t *dev = d86f[drive]; + uint32_t track_word; + uint32_t track_bit; + uint16_t encoded_data; + uint16_t surface_data = 0; + uint16_t current_bit; + uint16_t surface_bit; + + track_word = dev->track_pos >> 4; + + /* We need to make sure we read the bits from MSB to LSB. */ + track_bit = 15 - (dev->track_pos & 15); + + if (d86f_reverse_bytes(drive)) { + /* Image is in reverse endianness, read the data as is. */ + encoded_data = d86f_handler[drive].encoded_data(drive, side)[track_word]; + } else { + /* We store the words as big endian, so we need to convert them to little endian when reading. */ + encoded_data = (d86f_handler[drive].encoded_data(drive, side)[track_word] & 0xFF) << 8; + encoded_data |= (d86f_handler[drive].encoded_data(drive, side)[track_word] >> 8); + } + + if (d86f_has_surface_desc(drive)) { + if (d86f_reverse_bytes(drive)) { + surface_data = dev->track_surface_data[side][track_word] & 0xFF; + } else { + surface_data = (dev->track_surface_data[side][track_word] & 0xFF) << 8; + surface_data |= (dev->track_surface_data[side][track_word] >> 8); + } + } + + current_bit = (encoded_data >> track_bit) & 1; + dev->last_word[side] <<= 1; + + if (d86f_has_surface_desc(drive)) { + surface_bit = (surface_data >> track_bit) & 1; + if (! surface_bit) { + if (! current_bit) { + /* Bit is 0 and is not set to fuzzy, we add it as read. */ + dev->last_word[side] |= 1; + } else { + /* Bit is 1 and is not set to fuzzy, we add it as read. */ + dev->last_word[side] |= 1; + } + } else { + if (current_bit) { + /* Bit is 1 and is set to fuzzy, we randomly generate it. */ + dev->last_word[side] |= (random_generate() & 1); + } + } + } else { + dev->last_word[side] |= current_bit; + } +} + + +void +d86f_put_bit(int drive, int side, int bit) +{ + d86f_t *dev = d86f[drive]; + uint32_t track_word; + uint32_t track_bit; + uint16_t encoded_data; + uint16_t surface_data = 0; + uint16_t current_bit; + uint16_t surface_bit; + + if (fdc_get_diswr(d86f_fdc)) + return; + + track_word = dev->track_pos >> 4; + + /* We need to make sure we read the bits from MSB to LSB. */ + track_bit = 15 - (dev->track_pos & 15); + + if (d86f_reverse_bytes(drive)) { + /* Image is in reverse endianness, read the data as is. */ + encoded_data = d86f_handler[drive].encoded_data(drive, side)[track_word]; + } else { + /* We store the words as big endian, so we need to convert them to little endian when reading. */ + encoded_data = (d86f_handler[drive].encoded_data(drive, side)[track_word] & 0xFF) << 8; + encoded_data |= (d86f_handler[drive].encoded_data(drive, side)[track_word] >> 8); + } + + if (d86f_has_surface_desc(drive)) { + if (d86f_reverse_bytes(drive)) { + surface_data = dev->track_surface_data[side][track_word] & 0xFF; + } else { + surface_data = (dev->track_surface_data[side][track_word] & 0xFF) << 8; + surface_data |= (dev->track_surface_data[side][track_word] >> 8); + } + } + + current_bit = (encoded_data >> track_bit) & 1; + dev->last_word[side] <<= 1; + + if (d86f_has_surface_desc(drive)) { + surface_bit = (surface_data >> track_bit) & 1; + if (! surface_bit) { + if (! current_bit) { + /* Bit is 0 and is not set to fuzzy, we overwrite it as is. */ + dev->last_word[side] |= bit; + current_bit = bit; + } else { + /* Bit is 1 and is not set to fuzzy, we overwrite it as is. */ + dev->last_word[side] |= bit; + current_bit = bit; + } + } else { + if (current_bit) { + /* Bit is 1 and is set to fuzzy, we overwrite it with a non-fuzzy bit. */ + dev->last_word[side] |= bit; + current_bit = bit; + surface_bit = 0; + } + } + + surface_data &= ~(1 << track_bit); + surface_data |= (surface_bit << track_bit); + if (d86f_reverse_bytes(drive)) { + dev->track_surface_data[side][track_word] = surface_data; + } else { + dev->track_surface_data[side][track_word] = (surface_data & 0xFF) << 8; + dev->track_surface_data[side][track_word] |= (surface_data >> 8); + } + } else { + dev->last_word[side] |= bit; + current_bit = bit; + } + + encoded_data &= ~(1 << track_bit); + encoded_data |= (current_bit << track_bit); + + if (d86f_reverse_bytes(drive)) { + d86f_handler[drive].encoded_data(drive, side)[track_word] = encoded_data; + } else { + d86f_handler[drive].encoded_data(drive, side)[track_word] = (encoded_data & 0xFF) << 8; + d86f_handler[drive].encoded_data(drive, side)[track_word] |= (encoded_data >> 8); + } +} + + +static uint8_t +decodefm(int drive, uint16_t dat) +{ + uint8_t temp = 0; + + /* + * We write the encoded bytes in big endian, so we + * process the two 8-bit halves swapped here. + */ + if (dat & 0x0001) temp |= 1; + if (dat & 0x0004) temp |= 2; + if (dat & 0x0010) temp |= 4; + if (dat & 0x0040) temp |= 8; + if (dat & 0x0100) temp |= 16; + if (dat & 0x0400) temp |= 32; + if (dat & 0x1000) temp |= 64; + if (dat & 0x4000) temp |= 128; + + return temp; +} + + +void +fdd_calccrc(uint8_t byte, crc_t *crc_var) +{ + crc_var->word = (crc_var->word << 8) ^ + CRCTable[(crc_var->word >> 8)^byte]; +} + + +static void +d86f_calccrc(d86f_t *dev, uint8_t byte) +{ + fdd_calccrc(byte, &(dev->calc_crc)); +} + + +int +d86f_word_is_aligned(int drive, int side, uint32_t base_pos) +{ + d86f_t *dev = d86f[drive]; + uint32_t adjusted_track_pos = dev->track_pos; + + if (base_pos == 0xFFFFFFFF) return 0; + + /* + * This is very important, it makes sure alignment is detected + * correctly even across the index hole of a track whose length + * is not divisible by 16. + */ + if (adjusted_track_pos < base_pos) { + adjusted_track_pos += d86f_handler[drive].get_raw_size(drive, side); + } + + if ((adjusted_track_pos & 15) == (base_pos & 15)) return 1; + + return 0; +} + + /* State 1: Find sector ID */ -void d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_am, uint16_t other_am, uint16_t ignore_other_am) +void +d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_am, uint16_t other_am, uint16_t ignore_other_am) { - d86f_get_bit(drive, side); + d86f_t *dev = d86f[drive]; - if (d86f[drive].last_word[side] == req_am) - { - d86f[drive].calc_crc.word = 0xFFFF; - fdd_calccrc(decodefm(drive, d86f[drive].last_word[side]), &(d86f[drive].calc_crc)); - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; - d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1; - d86f[drive].state++; - return; - } + d86f_get_bit(drive, side); - if ((ignore_other_am & 2) && (d86f[drive].last_word[side] == other_am)) - { - d86f[drive].calc_crc.word = 0xFFFF; - fdd_calccrc(decodefm(drive, d86f[drive].last_word[side]), &(d86f[drive].calc_crc)); - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; - if (ignore_other_am & 1) - { - /* Skip mode, let's go back to finding ID. */ - d86f[drive].state -= 2; - } - else - { - /* Not skip mode, process the sector anyway. */ - fdc_set_wrong_am(d86f_fdc); - d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1; - d86f[drive].state++; - } - return; + if (dev->last_word[side] == req_am) { + dev->calc_crc.word = 0xFFFF; + fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc)); + find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; + find->sync_pos = 0xFFFFFFFF; + dev->preceding_bit[side] = dev->last_word[side] & 1; + dev->state++; + return; + } + + if ((ignore_other_am & 2) && (dev->last_word[side] == other_am)) { + dev->calc_crc.word = 0xFFFF; + fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc)); + find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; + find->sync_pos = 0xFFFFFFFF; + if (ignore_other_am & 1) { + /* Skip mode, let's go back to finding ID. */ + dev->state -= 2; + } else { + /* Not skip mode, process the sector anyway. */ + fdc_set_wrong_am(d86f_fdc); + dev->preceding_bit[side] = dev->last_word[side] & 1; + dev->state++; } + } } + /* When writing in FM mode, we find the beginning of the address mark by looking for 352 (22 * 16) set bits (gap fill = 0xFF, 0xFFFF FM-encoded). */ -void d86f_write_find_address_mark_fm(int drive, int side, find_t *find) +void +d86f_write_find_address_mark_fm(int drive, int side, find_t *find) { - d86f_get_bit(drive, side); + d86f_t *dev = d86f[drive]; - if (d86f[drive].last_word[side] & 1) - { - find->sync_marks++; - if (find->sync_marks == 352) - { - d86f[drive].calc_crc.word = 0xFFFF; - d86f[drive].preceding_bit[side] = 1; - find->sync_marks = 0; - d86f[drive].state++; - return; - } + d86f_get_bit(drive, side); + + if (dev->last_word[side] & 1) { + find->sync_marks++; + if (find->sync_marks == 352) { + dev->calc_crc.word = 0xFFFF; + dev->preceding_bit[side] = 1; + find->sync_marks = 0; + dev->state++; + return; } + } - /* If we hadn't found enough set bits but have found a clear bit, null the counter of set bits. */ - if (!(d86f[drive].last_word[side] & 1)) - { + /* If we hadn't found enough set bits but have found a clear bit, null the counter of set bits. */ + if (!(dev->last_word[side] & 1)) { + find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; + find->sync_pos = 0xFFFFFFFF; + } +} + + +void +d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_am, uint16_t other_am, uint16_t ignore_other_am) +{ + d86f_t *dev = d86f[drive]; + + d86f_get_bit(drive, side); + + if (dev->last_word[side] == 0x4489) { + find->sync_marks++; + find->sync_pos = dev->track_pos; + return; + } + + if ((dev->last_word[side] == req_am) && (find->sync_marks >= 3)) { + if (d86f_word_is_aligned(drive, side, find->sync_pos)) { + dev->calc_crc.word = 0xCDB4; + fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc)); + find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; + find->sync_pos = 0xFFFFFFFF; + dev->preceding_bit[side] = dev->last_word[side] & 1; + dev->state++; + return; + } + } + + if ((ignore_other_am & 2) && (dev->last_word[side] == other_am) && (find->sync_marks >= 3)) { + if (d86f_word_is_aligned(drive, side, find->sync_pos)) { + dev->calc_crc.word = 0xCDB4; + fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc)); + find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; + find->sync_pos = 0xFFFFFFFF; + if (ignore_other_am & 1) { + /* Skip mode, let's go back to finding ID. */ + dev->state -= 2; + } else { + /* Not skip mode, process the sector anyway. */ + fdc_set_wrong_am(d86f_fdc); + dev->preceding_bit[side] = dev->last_word[side] & 1; + dev->state++; + } + return; + } + } + + if (dev->last_word[side] != 0x4489) { + if (d86f_word_is_aligned(drive, side, find->sync_pos)) { find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; find->sync_pos = 0xFFFFFFFF; } + } } -void d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_am, uint16_t other_am, uint16_t ignore_other_am) -{ - d86f_get_bit(drive, side); - - if (d86f[drive].last_word[side] == 0x4489) - { - find->sync_marks++; - find->sync_pos = d86f[drive].track_pos; - - return; - } - - if ((d86f[drive].last_word[side] == req_am) && (find->sync_marks >= 3)) - { - if (d86f_word_is_aligned(drive, side, find->sync_pos)) - { - d86f[drive].calc_crc.word = 0xCDB4; - fdd_calccrc(decodefm(drive, d86f[drive].last_word[side]), &(d86f[drive].calc_crc)); - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; - d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1; - d86f[drive].state++; - return; - } - } - - if ((ignore_other_am & 2) && (d86f[drive].last_word[side] == other_am) && (find->sync_marks >= 3)) - { - if (d86f_word_is_aligned(drive, side, find->sync_pos)) - { - d86f[drive].calc_crc.word = 0xCDB4; - fdd_calccrc(decodefm(drive, d86f[drive].last_word[side]), &(d86f[drive].calc_crc)); - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; - if (ignore_other_am & 1) - { - /* Skip mode, let's go back to finding ID. */ - d86f[drive].state -= 2; - } - else - { - /* Not skip mode, process the sector anyway. */ - fdc_set_wrong_am(d86f_fdc); - d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1; - d86f[drive].state++; - } - return; - } - } - - if (d86f[drive].last_word[side] != 0x4489) - { - if (d86f_word_is_aligned(drive, side, find->sync_pos)) - { - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; - } - } -} /* When writing in MFM mode, we find the beginning of the address mark by looking for 3 0xA1 sync bytes. */ -void d86f_write_find_address_mark_mfm(int drive, int side, find_t *find) +void +d86f_write_find_address_mark_mfm(int drive, int side, find_t *find) { - d86f_get_bit(drive, side); + d86f_t *dev = d86f[drive]; - if (d86f[drive].last_word[side] == 0x4489) - { - find->sync_marks++; - find->sync_pos = d86f[drive].track_pos; - if (find->sync_marks == 3) - { - d86f[drive].calc_crc.word = 0xCDB4; - d86f[drive].preceding_bit[side] = 1; - find->sync_marks = 0; - d86f[drive].state++; + d86f_get_bit(drive, side); + + if (dev->last_word[side] == 0x4489) { + find->sync_marks++; + find->sync_pos = dev->track_pos; + if (find->sync_marks == 3) { + dev->calc_crc.word = 0xCDB4; + dev->preceding_bit[side] = 1; + find->sync_marks = 0; + dev->state++; + return; + } + } + + /* If we hadn't found enough address mark sync marks, null the counter. */ + if (dev->last_word[side] != 0x4489) { + if (d86f_word_is_aligned(drive, side, find->sync_pos)) { + find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; + find->sync_pos = 0xFFFFFFFF; + } + } +} + + +/* State 2: Read sector ID and CRC*/ +void +d86f_read_sector_id(int drive, int side, int match) +{ + d86f_t *dev = d86f[drive]; + + if (dev->id_find.bits_obtained) { + if (! (dev->id_find.bits_obtained & 15)) { + /* We've got a byte. */ + if (dev->id_find.bytes_obtained < 4) { + dev->last_sector.byte_array[dev->id_find.bytes_obtained] = decodefm(drive, dev->last_word[side]); + fdd_calccrc(dev->last_sector.byte_array[dev->id_find.bytes_obtained], &(dev->calc_crc)); + } else if ((dev->id_find.bytes_obtained >= 4) && (dev->id_find.bytes_obtained < 6)) { + dev->track_crc.bytes[(dev->id_find.bytes_obtained & 1) ^ 1] = decodefm(drive, dev->last_word[side]); + } + dev->id_find.bytes_obtained++; + + if (dev->id_find.bytes_obtained == 6) { + /* We've got the ID. */ + if (dev->calc_crc.word != dev->track_crc.word) { + dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = 0; + d86f_log("86F: ID CRC error: %04X != %04X (%08X)\n", dev->track_crc.word, dev->calc_crc.word, dev->last_sector.dword); + if ((dev->state != STATE_02_READ_ID) && (dev->state != STATE_0A_READ_ID)) { + dev->error_condition = 0; + dev->state = STATE_IDLE; + fdc_finishread(d86f_fdc); + fdc_headercrcerror(d86f_fdc); + } else if (dev->state == STATE_0A_READ_ID) { + dev->state--; + } else { + dev->error_condition |= 1; /* Mark that there was an ID CRC error. */ + dev->state++; + } + } else if ((dev->calc_crc.word == dev->track_crc.word) && (dev->state == STATE_0A_READ_ID)) { + /* CRC is valid and this is a read sector ID command. */ + dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = dev->error_condition = 0; + fdc_sectorid(d86f_fdc, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n, 0, 0); + dev->state = STATE_IDLE; + } else { + /* CRC is valid. */ + dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = 0; + dev->id_found++; + if ((dev->last_sector.dword == dev->req_sector.dword) || !match) { + d86f_handler[drive].set_sector(drive, side, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n); + if (dev->state == STATE_02_READ_ID) { + /* READ TRACK command, we need some special handling here. */ + /* Code corrected: Only the C, H, and N portions of the sector ID are compared, the R portion (the sector number) is ignored. */ + if ((dev->last_sector.id.c != fdc_get_read_track_sector(d86f_fdc).id.c) || (dev->last_sector.id.h != fdc_get_read_track_sector(d86f_fdc).id.h) || (dev->last_sector.id.n != fdc_get_read_track_sector(d86f_fdc).id.n)) { + dev->error_condition |= 4; /* Mark that the sector ID is not the one expected by the FDC. */ + /* Make sure we use the sector size from the FDC. */ + dev->last_sector.id.n = fdc_get_read_track_sector(d86f_fdc).id.n; + } + + /* If the two ID's are identical, then we do not need to do anything regarding the sector size. */ + } + dev->state++; + } else { + if (dev->last_sector.id.c != dev->req_sector.id.c) { + if (dev->last_sector.id.c == 0xFF) { + dev->error_condition |= 8; + } else { + dev->error_condition |= 0x10; + } + } + + dev->state--; + } + } + } + } + } + + d86f_get_bit(drive, side); + + dev->id_find.bits_obtained++; +} + + +uint8_t +d86f_get_data(int drive, int base) +{ + d86f_t *dev = d86f[drive]; + int data; + + if (dev->data_find.bytes_obtained < (d86f_get_data_len(drive) + base)) { + data = fdc_getdata(d86f_fdc, dev->data_find.bytes_obtained == (d86f_get_data_len(drive) + base - 1)); + if ((data & DMA_OVER) || (data == -1)) { + dev->dma_over++; + if (data == -1) + data = 0; + else + data &= 0xff; + } + } else { + data = 0; + } + + return data; +} + + +void +d86f_compare_byte(int drive, uint8_t received_byte, uint8_t disk_byte) +{ + d86f_t *dev = d86f[drive]; + + switch(fdc_get_compare_condition(d86f_fdc)) { + case 0: /* SCAN EQUAL */ + if ((received_byte == disk_byte) || (received_byte == 0xFF)) + dev->satisfying_bytes++; + break; + + case 1: /* SCAN LOW OR EQUAL */ + if ((received_byte <= disk_byte) || (received_byte == 0xFF)) + dev->satisfying_bytes++; + break; + + case 2: /* SCAN HIGH OR EQUAL */ + if ((received_byte >= disk_byte) || (received_byte == 0xFF)) + dev->satisfying_bytes++; + break; + } +} + + +/* State 4: Read sector data and CRC*/ +void +d86f_read_sector_data(int drive, int side) +{ + d86f_t *dev = d86f[drive]; + int data = 0; + int recv_data = 0; + int read_status = 0; + uint32_t sector_len = dev->last_sector.id.n; + uint32_t crc_pos = 0; + sector_len = 1 << (7 + sector_len); + crc_pos = sector_len + 2; + + if (dev->data_find.bits_obtained) { + if (!(dev->data_find.bits_obtained & 15)) { + /* We've got a byte. */ + if (dev->data_find.bytes_obtained < sector_len) { + data = decodefm(drive, dev->last_word[side]); + if (dev->state == STATE_11_SCAN_DATA) { + /* Scan/compare command. */ + recv_data = d86f_get_data(drive, 0); + d86f_compare_byte(drive, recv_data, data); + } else { + if (dev->data_find.bytes_obtained < d86f_get_data_len(drive)) { + if (dev->state != STATE_16_VERIFY_DATA) { + read_status = fdc_data(d86f_fdc, data); + if (read_status == -1) { + dev->dma_over++; + } + } + } + } + fdd_calccrc(data, &(dev->calc_crc)); + } else if (dev->data_find.bytes_obtained < crc_pos) { + dev->track_crc.bytes[(dev->data_find.bytes_obtained - sector_len) ^ 1] = decodefm(drive, dev->last_word[side]); + } + dev->data_find.bytes_obtained++; + + if (dev->data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc))) { + /* We've got the data. */ + if (dev->dma_over > 1) { + dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; + dev->error_condition = 0; + dev->state = STATE_IDLE; + fdc_finishread(d86f_fdc); + fdc_overrun(d86f_fdc); + + d86f_get_bit(drive, side); + + dev->data_find.bits_obtained++; + return; + } + + if ((dev->calc_crc.word != dev->track_crc.word) && (dev->state != STATE_02_READ_DATA)) { + d86f_log("86F: Data CRC error: %04X != %04X (%08X)\n", dev->track_crc.word, dev->calc_crc.word, dev->last_sector.dword); + dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; + dev->error_condition = 0; + dev->state = STATE_IDLE; + fdc_finishread(d86f_fdc); + fdc_datacrcerror(d86f_fdc); + } else if ((dev->calc_crc.word != dev->track_crc.word) && (dev->state == STATE_02_READ_DATA)) { + dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; + dev->error_condition |= 2; /* Mark that there was a data error. */ + dev->state = STATE_IDLE; + fdc_track_finishread(d86f_fdc, dev->error_condition); + } else { + /* CRC is valid. */ + dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; + dev->error_condition = 0; + if (dev->state == STATE_11_SCAN_DATA) { + dev->state = STATE_IDLE; + fdc_sector_finishcompare(d86f_fdc, (dev->satisfying_bytes == ((128 << ((uint32_t) dev->last_sector.id.n)) - 1)) ? 1 : 0); + } else { + dev->state = STATE_IDLE; + fdc_sector_finishread(d86f_fdc); + } + } + } + } + } + + d86f_get_bit(drive, side); + + dev->data_find.bits_obtained++; +} + + +void +d86f_write_sector_data(int drive, int side, int mfm, uint16_t am) +{ + d86f_t *dev = d86f[drive]; + uint16_t bit_pos; + uint16_t temp; + uint32_t sector_len = dev->last_sector.id.n; + uint32_t crc_pos = 0; + sector_len = (1 << (7 + sector_len)) + 1; + crc_pos = sector_len + 2; + + if (! (dev->data_find.bits_obtained & 15)) { + if (dev->data_find.bytes_obtained < crc_pos) { + if (! dev->data_find.bytes_obtained) { + /* We're writing the address mark. */ + dev->current_byte[side] = am; + } else if (dev->data_find.bytes_obtained < sector_len) { + /* We're in the data field of the sector, read byte from FDC and request new byte. */ + dev->current_byte[side] = d86f_get_data(drive, 1); + if (! fdc_get_diswr(d86f_fdc)) + d86f_handler[drive].write_data(drive, side, dev->data_find.bytes_obtained - 1, dev->current_byte[side]); + } else { + /* We're in the data field of the sector, use a CRC byte. */ + dev->current_byte[side] = dev->calc_crc.bytes[(dev->data_find.bytes_obtained & 1)]; + } + + dev->current_bit[side] = (15 - (dev->data_find.bits_obtained & 15)) >> 1; + + /* Write the bit. */ + temp = (dev->current_byte[side] >> dev->current_bit[side]) & 1; + if ((!temp && !dev->preceding_bit[side]) || !mfm) { + temp |= 2; + } + + /* This is an even bit, so write the clock. */ + if (! dev->data_find.bytes_obtained) { + /* Address mark, write bit directly. */ + d86f_put_bit(drive, side, am >> 15); + } else { + d86f_put_bit(drive, side, temp >> 1); + } + + if (dev->data_find.bytes_obtained < sector_len) { + /* This is a data byte, so CRC it. */ + if (! dev->data_find.bytes_obtained) { + fdd_calccrc(decodefm(drive, am), &(dev->calc_crc)); + } else { + fdd_calccrc(dev->current_byte[side], &(dev->calc_crc)); + } + } + } + } else { + if (dev->data_find.bytes_obtained < crc_pos) { + /* Encode the bit. */ + bit_pos = 15 - (dev->data_find.bits_obtained & 15); + dev->current_bit[side] = bit_pos >> 1; + + temp = (dev->current_byte[side] >> dev->current_bit[side]) & 1; + if ((!temp && !dev->preceding_bit[side]) || !mfm) { + temp |= 2; + } + + if (! dev->data_find.bytes_obtained) { + /* Address mark, write directly. */ + d86f_put_bit(drive, side, am >> bit_pos); + if (! (bit_pos & 1)) { + dev->preceding_bit[side] = am >> bit_pos; + } + } else { + if (bit_pos & 1) { + /* Clock bit */ + d86f_put_bit(drive, side, temp >> 1); + } else { + /* Data bit */ + d86f_put_bit(drive, side, temp & 1); + dev->preceding_bit[side] = temp & 1; + } + } + } + + if ((dev->data_find.bits_obtained & 15) == 15) { + dev->data_find.bytes_obtained++; + + if (dev->data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc))) { + if (dev->dma_over > 1) { + dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; + dev->error_condition = 0; + dev->state = STATE_IDLE; + fdc_finishread(d86f_fdc); + fdc_overrun(d86f_fdc); + + dev->data_find.bits_obtained++; + return; + } + + /* We've written the data. */ + dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; + dev->error_condition = 0; + dev->state = STATE_IDLE; + d86f_handler[drive].writeback(drive); + fdc_sector_finishread(d86f_fdc); return; } } + } - /* If we hadn't found enough address mark sync marks, null the counter. */ - if (d86f[drive].last_word[side] != 0x4489) - { - if (d86f_word_is_aligned(drive, side, find->sync_pos)) - { - find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; - find->sync_pos = 0xFFFFFFFF; - } - } + dev->data_find.bits_obtained++; } -/* State 2: Read sector ID and CRC*/ -void d86f_read_sector_id(int drive, int side, int match) -{ - if (d86f[drive].id_find.bits_obtained) - { - if (!(d86f[drive].id_find.bits_obtained & 15)) - { - /* We've got a byte. */ - if (d86f[drive].id_find.bytes_obtained < 4) - { - d86f[drive].last_sector.byte_array[d86f[drive].id_find.bytes_obtained] = decodefm(drive, d86f[drive].last_word[side]); - fdd_calccrc(d86f[drive].last_sector.byte_array[d86f[drive].id_find.bytes_obtained], &(d86f[drive].calc_crc)); - } - else if ((d86f[drive].id_find.bytes_obtained >= 4) && (d86f[drive].id_find.bytes_obtained < 6)) - { - d86f[drive].track_crc.bytes[(d86f[drive].id_find.bytes_obtained & 1) ^ 1] = decodefm(drive, d86f[drive].last_word[side]); - } - d86f[drive].id_find.bytes_obtained++; - - if (d86f[drive].id_find.bytes_obtained == 6) - { - /* We've got the ID. */ - if (d86f[drive].calc_crc.word != d86f[drive].track_crc.word) - { - d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = 0; - d86f_log("86F: ID CRC error: %04X != %04X (%08X)\n", d86f[drive].track_crc.word, d86f[drive].calc_crc.word, d86f[drive].last_sector.dword); - if ((d86f[drive].state != STATE_02_READ_ID) && (d86f[drive].state != STATE_0A_READ_ID)) - { - d86f[drive].error_condition = 0; - d86f[drive].state = STATE_IDLE; - fdc_finishread(d86f_fdc); - fdc_headercrcerror(d86f_fdc); - } - else if (d86f[drive].state == STATE_0A_READ_ID) - { - d86f[drive].state--; - } - else - { - d86f[drive].error_condition |= 1; /* Mark that there was an ID CRC error. */ - d86f[drive].state++; - } - } - else if ((d86f[drive].calc_crc.word == d86f[drive].track_crc.word) && (d86f[drive].state == STATE_0A_READ_ID)) - { - /* CRC is valid and this is a read sector ID command. */ - 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_fdc, 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; - } - else - { - /* CRC is valid. */ - d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = 0; - d86f[drive].id_found++; - if ((d86f[drive].last_sector.dword == d86f[drive].req_sector.dword) || !match) - { - 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); - if (d86f[drive].state == STATE_02_READ_ID) - { - /* READ TRACK command, we need some special handling here. */ - /* Code corrected: Only the C, H, and N portions of the sector ID are compared, the R portion (the sector number) is ignored. */ - if ((d86f[drive].last_sector.id.c != fdc_get_read_track_sector(d86f_fdc).id.c) || (d86f[drive].last_sector.id.h != fdc_get_read_track_sector(d86f_fdc).id.h) || (d86f[drive].last_sector.id.n != fdc_get_read_track_sector(d86f_fdc).id.n)) - { - d86f[drive].error_condition |= 4; /* Mark that the sector ID is not the one expected by the FDC. */ - /* Make sure we use the sector size from the FDC. */ - d86f[drive].last_sector.id.n = fdc_get_read_track_sector(d86f_fdc).id.n; - } - /* If the two ID's are identical, then we do not need to do anything regarding the sector size. */ - } - d86f[drive].state++; - } - else - { - if (d86f[drive].last_sector.id.c != d86f[drive].req_sector.id.c) - { - if (d86f[drive].last_sector.id.c == 0xFF) - { - d86f[drive].error_condition |= 8; - } - else - { - d86f[drive].error_condition |= 0x10; - } - } - - d86f[drive].state--; - } - } - } - } - } - - d86f_get_bit(drive, side); - - d86f[drive].id_find.bits_obtained++; -} - -uint8_t d86f_get_data(int drive, int base) -{ - int data; - - if (d86f[drive].data_find.bytes_obtained < (d86f_get_data_len(drive) + base)) - { - data = fdc_getdata(d86f_fdc, d86f[drive].data_find.bytes_obtained == (d86f_get_data_len(drive) + base - 1)); - if ((data & DMA_OVER) || (data == -1)) - { - d86f[drive].dma_over++; - if (data == -1) - { - data = 0; - } - else - { - data &= 0xff; - } - } - } - else - { - data = 0; - } - - return data; -} - -void d86f_compare_byte(int drive, uint8_t received_byte, uint8_t disk_byte) -{ - switch(fdc_get_compare_condition(d86f_fdc)) - { - case 0: /* SCAN EQUAL */ - if ((received_byte == disk_byte) || (received_byte == 0xFF)) - { - d86f[drive].satisfying_bytes++; - } - break; - case 1: /* SCAN LOW OR EQUAL */ - if ((received_byte <= disk_byte) || (received_byte == 0xFF)) - { - d86f[drive].satisfying_bytes++; - } - break; - case 2: /* SCAN HIGH OR EQUAL */ - if ((received_byte >= disk_byte) || (received_byte == 0xFF)) - { - d86f[drive].satisfying_bytes++; - } - break; - } -} - -/* State 4: Read sector data and CRC*/ -void d86f_read_sector_data(int drive, int side) -{ - int data = 0; - int recv_data = 0; - int read_status = 0; - uint32_t sector_len = d86f[drive].last_sector.id.n; - uint32_t crc_pos = 0; - sector_len = 1 << (7 + sector_len); - crc_pos = sector_len + 2; - - if (d86f[drive].data_find.bits_obtained) - { - if (!(d86f[drive].data_find.bits_obtained & 15)) - { - /* We've got a byte. */ - if (d86f[drive].data_find.bytes_obtained < sector_len) - { - data = decodefm(drive, d86f[drive].last_word[side]); - if (d86f[drive].state == STATE_11_SCAN_DATA) - { - /* Scan/compare command. */ - recv_data = d86f_get_data(drive, 0); - d86f_compare_byte(drive, recv_data, data); - } - else - { - if (d86f[drive].data_find.bytes_obtained < d86f_get_data_len(drive)) - { - if (d86f[drive].state != STATE_16_VERIFY_DATA) - { - read_status = fdc_data(d86f_fdc, data); - if (read_status == -1) - { - d86f[drive].dma_over++; - } - } - } - } - fdd_calccrc(data, &(d86f[drive].calc_crc)); - } - else if (d86f[drive].data_find.bytes_obtained < crc_pos) - { - d86f[drive].track_crc.bytes[(d86f[drive].data_find.bytes_obtained - sector_len) ^ 1] = decodefm(drive, d86f[drive].last_word[side]); - } - d86f[drive].data_find.bytes_obtained++; - - if (d86f[drive].data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc))) - { - /* We've got the data. */ - 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(d86f_fdc); - fdc_overrun(d86f_fdc); - - d86f_get_bit(drive, side); - - d86f[drive].data_find.bits_obtained++; - return; - } - - if ((d86f[drive].calc_crc.word != d86f[drive].track_crc.word) && (d86f[drive].state != STATE_02_READ_DATA)) - { - d86f_log("86F: Data CRC error: %04X != %04X (%08X)\n", d86f[drive].track_crc.word, d86f[drive].calc_crc.word, d86f[drive].last_sector.dword); - 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(d86f_fdc); - fdc_datacrcerror(d86f_fdc); - } - else if ((d86f[drive].calc_crc.word != d86f[drive].track_crc.word) && (d86f[drive].state == STATE_02_READ_DATA)) - { - d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0; - d86f[drive].error_condition |= 2; /* Mark that there was a data error. */ - d86f[drive].state = STATE_IDLE; - fdc_track_finishread(d86f_fdc, d86f[drive].error_condition); - } - else - { - /* 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_fdc, (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(d86f_fdc); - } - } - } - } - } - - d86f_get_bit(drive, side); - - d86f[drive].data_find.bits_obtained++; -} - -void d86f_write_sector_data(int drive, int side, int mfm, uint16_t am) -{ - uint16_t bit_pos; - uint16_t temp; - uint32_t sector_len = d86f[drive].last_sector.id.n; - uint32_t crc_pos = 0; - sector_len = (1 << (7 + sector_len)) + 1; - crc_pos = sector_len + 2; - - if (!(d86f[drive].data_find.bits_obtained & 15)) - { - if (d86f[drive].data_find.bytes_obtained < crc_pos) - { - if (!d86f[drive].data_find.bytes_obtained) - { - /* We're writing the address mark. */ - d86f[drive].current_byte[side] = am; - } - else if (d86f[drive].data_find.bytes_obtained < sector_len) - { - /* We're in the data field of the sector, read byte from FDC and request new byte. */ - d86f[drive].current_byte[side] = d86f_get_data(drive, 1); - if (!fdc_get_diswr(d86f_fdc)) - d86f_handler[drive].write_data(drive, side, d86f[drive].data_find.bytes_obtained - 1, d86f[drive].current_byte[side]); - } - else - { - /* We're in the data field of the sector, use a CRC byte. */ - d86f[drive].current_byte[side] = d86f[drive].calc_crc.bytes[(d86f[drive].data_find.bytes_obtained & 1)]; - } - - d86f[drive].current_bit[side] = (15 - (d86f[drive].data_find.bits_obtained & 15)) >> 1; - - /* Write the bit. */ - temp = (d86f[drive].current_byte[side] >> d86f[drive].current_bit[side]) & 1; - if ((!temp && !d86f[drive].preceding_bit[side]) || !mfm) - { - temp |= 2; - } - - /* This is an even bit, so write the clock. */ - if (!d86f[drive].data_find.bytes_obtained) - { - /* Address mark, write bit directly. */ - d86f_put_bit(drive, side, am >> 15); - } - else - { - d86f_put_bit(drive, side, temp >> 1); - } - - if (d86f[drive].data_find.bytes_obtained < sector_len) - { - /* This is a data byte, so CRC it. */ - if (!d86f[drive].data_find.bytes_obtained) - { - fdd_calccrc(decodefm(drive, am), &(d86f[drive].calc_crc)); - } - else - { - fdd_calccrc(d86f[drive].current_byte[side], &(d86f[drive].calc_crc)); - } - } - } - } - else - { - if (d86f[drive].data_find.bytes_obtained < crc_pos) - { - /* Encode the bit. */ - bit_pos = 15 - (d86f[drive].data_find.bits_obtained & 15); - d86f[drive].current_bit[side] = bit_pos >> 1; - - temp = (d86f[drive].current_byte[side] >> d86f[drive].current_bit[side]) & 1; - if ((!temp && !d86f[drive].preceding_bit[side]) || !mfm) - { - temp |= 2; - } - - if (!d86f[drive].data_find.bytes_obtained) - { - /* Address mark, write directly. */ - d86f_put_bit(drive, side, am >> bit_pos); - if (!(bit_pos & 1)) - { - d86f[drive].preceding_bit[side] = am >> bit_pos; - } - } - else - { - if (bit_pos & 1) - { - /* Clock bit */ - d86f_put_bit(drive, side, temp >> 1); - } - else - { - /* Data bit */ - d86f_put_bit(drive, side, temp & 1); - d86f[drive].preceding_bit[side] = temp & 1; - } - } - } - - if ((d86f[drive].data_find.bits_obtained & 15) == 15) - { - d86f[drive].data_find.bytes_obtained++; - - if (d86f[drive].data_find.bytes_obtained == (crc_pos + fdc_get_gap(d86f_fdc))) - { - 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(d86f_fdc); - fdc_overrun(d86f_fdc); - - d86f[drive].data_find.bits_obtained++; - return; - } - - /* 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(d86f_fdc); - return; - } - } - } - - d86f[drive].data_find.bits_obtained++; -} void d86f_advance_bit(int drive, int side) { - d86f[drive].track_pos++; - d86f[drive].track_pos %= d86f_handler[drive].get_raw_size(drive, side); + d86f_t *dev = d86f[drive]; - if (d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side)) - { - d86f_handler[drive].read_revolution(drive); + dev->track_pos++; + dev->track_pos %= d86f_handler[drive].get_raw_size(drive, side); - if (d86f[drive].state != STATE_IDLE) - { - d86f[drive].index_count++; + if (dev->track_pos == d86f_handler[drive].index_hole_pos(drive, side)) { + d86f_handler[drive].read_revolution(drive); + + if (dev->state != STATE_IDLE) + dev->index_count++; + } +} + + +void +d86f_advance_word(int drive, int side) +{ + d86f_t *dev = d86f[drive]; + + dev->track_pos += 16; + dev->track_pos %= d86f_handler[drive].get_raw_size(drive, side); + + if ((dev->track_pos == d86f_handler[drive].index_hole_pos(drive, side)) && (dev->state != STATE_IDLE)) + dev->index_count++; +} + + +void +d86f_spin_to_index(int drive, int side) +{ + d86f_t *dev = d86f[drive]; + + d86f_get_bit(drive, side); + d86f_get_bit(drive, side ^ 1); + + d86f_advance_bit(drive, side); + + if (dev->track_pos == d86f_handler[drive].index_hole_pos(drive, side)) { + if ((dev->state == STATE_0D_SPIN_TO_INDEX) || (dev->state == STATE_0D_NOP_SPIN_TO_INDEX)) { + /* When starting format, reset format state to the beginning. */ + dev->preceding_bit[side] = 1; + dev->format_state = FMT_PRETRK_GAP0; + } + + /* This is to make sure both READ TRACK and FORMAT TRACK command don't end prematurely. */ + dev->index_count = 0; + dev->state++; + } +} + + +void +d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, uint32_t pos) +{ + d86f_t *dev = d86f[drive]; + uint16_t encoded_byte = 0, mask_data, mask_surface, mask_hole, mask_fuzzy; + decoded_t dbyte, dpbyte; + + if (fdc_get_diswr(d86f_fdc)) return; + + dbyte.byte = byte & 0xff; + dpbyte.byte = dev->preceding_bit[side] & 0xff; + + if (type == 0) { + /* Byte write. */ + encoded_byte = d86f_encode_byte(drive, 0, dbyte, dpbyte); + if (! d86f_reverse_bytes(drive)) { + mask_data = encoded_byte >> 8; + encoded_byte &= 0xFF; + encoded_byte <<= 8; + encoded_byte |= mask_data; + } + } else { + /* Word write. */ + encoded_byte = byte; + if (d86f_reverse_bytes(drive)) { + mask_data = encoded_byte >> 8; + encoded_byte &= 0xFF; + encoded_byte <<= 8; + encoded_byte |= mask_data; + } + } + + dev->preceding_bit[side] = encoded_byte & 1; + + if (d86f_has_surface_desc(drive)) { + mask_data = dev->track_encoded_data[side][pos] ^= 0xFFFF; + mask_surface = dev->track_surface_data[side][pos]; + mask_hole = (mask_surface & mask_data) ^ 0xFFFF; /* This will retain bits that are both fuzzy and 0, therefore physical holes. */ + encoded_byte &= mask_hole; /* Filter out physical hole bits from the encoded data. */ + mask_data ^= 0xFFFF; /* Invert back so bits 1 are 1 again. */ + mask_fuzzy = (mask_surface & mask_data) ^ 0xFFFF; /* All fuzzy bits are 0. */ + dev->track_surface_data[side][pos] &= mask_fuzzy; /* Remove fuzzy bits (but not hole bits) from the surface mask, making them regular again. */ + } + + dev->track_encoded_data[side][pos] = encoded_byte; + dev->last_word[side] = encoded_byte; +} + + +void +d86f_write_direct(int drive, int side, uint16_t byte, uint8_t type) +{ + d86f_t *dev = d86f[drive]; + + d86f_write_direct_common(drive, side, byte, type, dev->track_pos >> 4); +} + + +uint16_t +endian_swap(uint16_t word) +{ + uint16_t temp; + + temp = word & 0xff; + temp <<= 8; + temp |= (word >> 8); + + return temp; +} + + +void +d86f_format_finish(int drive, int side, int mfm, uint16_t sc, uint16_t gap_fill, int do_write) +{ + d86f_t *dev = d86f[drive]; + + if (mfm && do_write) { + if (do_write && (dev->track_pos == d86f_handler[drive].index_hole_pos(drive, side))) { + d86f_write_direct_common(drive, side, gap_fill, 0, 0); + } + } + + dev->state = STATE_IDLE; + + if (do_write) + d86f_handler[drive].writeback(drive); + + dev->error_condition = 0; + dev->datac = 0; + fdc_sector_finishread(d86f_fdc); +} + + +void +d86f_format_turbo_finish(int drive, int side, int do_write) +{ + d86f_t *dev = d86f[drive]; + + dev->state = STATE_IDLE; + + if (do_write) + d86f_handler[drive].writeback(drive); + + dev->error_condition = 0; + dev->datac = 0; + fdc_sector_finishread(d86f_fdc); +} + + +void +d86f_format_track(int drive, int side, int do_write) +{ + d86f_t *dev = d86f[drive]; + int data; + uint16_t max_len; + + int mfm; + uint16_t sc = 0; + uint16_t dtl = 0; + int gap_sizes[4] = { 0, 0, 0, 0 }; + int am_len = 0; + int sync_len = 0; + uint16_t iam_mfm[4] = { 0x2452, 0x2452, 0x2452, 0x5255 }; + uint16_t idam_mfm[4] = { 0x8944, 0x8944, 0x8944, 0x5455 }; + uint16_t dataam_mfm[4] = { 0x8944, 0x8944, 0x8944, 0x4555 }; + uint16_t iam_fm = 0xFAF7; + uint16_t idam_fm = 0x7EF5; + uint16_t dataam_fm = 0x6FF5; + uint16_t gap_fill = 0x4E; + + mfm = d86f_is_mfm(drive); + am_len = mfm ? 4 : 1; + gap_sizes[0] = mfm ? 80 : 40; + gap_sizes[1] = mfm ? 50 : 26; + gap_sizes[2] = fdc_get_gap2(d86f_fdc, real_drive(d86f_fdc, drive)); + gap_sizes[3] = fdc_get_gap(d86f_fdc); + sync_len = mfm ? 12 : 6; + sc = fdc_get_format_sectors(d86f_fdc); + dtl = 128 << fdc_get_format_n(d86f_fdc); + gap_fill = mfm ? 0x4E : 0xFF; + + switch(dev->format_state) { + case FMT_POSTTRK_GAP4: + max_len = 60000; + if (do_write) + d86f_write_direct(drive, side, gap_fill, 0); + break; + + case FMT_PRETRK_GAP0: + max_len = gap_sizes[0]; + if (do_write) + d86f_write_direct(drive, side, gap_fill, 0); + break; + + case FMT_SECTOR_ID_SYNC: + max_len = sync_len; + if (dev->datac <= 3) { + data = fdc_getdata(d86f_fdc, 0); + if (data != -1) + data &= 0xff; + if ((data == -1) && (dev->datac < 3)) + data = 0; + dev->format_sector_id.byte_array[dev->datac] = data & 0xff; + if (dev->datac == 3) + fdc_stop_id_request(d86f_fdc); } - } -} + /*FALLTHROUGH*/ -void d86f_advance_word(int drive, int side) -{ - d86f[drive].track_pos += 16; - d86f[drive].track_pos %= d86f_handler[drive].get_raw_size(drive, side); + case FMT_PRETRK_SYNC: + case FMT_SECTOR_DATA_SYNC: + max_len = sync_len; + if (do_write) + d86f_write_direct(drive, side, 0x00, 0); + break; - if ((d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side)) && (d86f[drive].state != STATE_IDLE)) d86f[drive].index_count++; -} - -void d86f_spin_to_index(int drive, int side) -{ - d86f_get_bit(drive, side); - d86f_get_bit(drive, side ^ 1); - - d86f_advance_bit(drive, side); - - if (d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side)) - { - if ((d86f[drive].state == STATE_0D_SPIN_TO_INDEX) || (d86f[drive].state == STATE_0D_NOP_SPIN_TO_INDEX)) - { - /* When starting format, reset format state to the beginning. */ - d86f[drive].preceding_bit[side] = 1; - d86f[drive].format_state = FMT_PRETRK_GAP0; + case FMT_PRETRK_IAM: + max_len = am_len; + if (do_write) { + if (mfm) + d86f_write_direct(drive, side, iam_mfm[dev->datac], 1); + else + d86f_write_direct(drive, side, iam_fm, 1); } - /* This is to make sure both READ TRACK and FORMAT TRACK command don't end prematurely. */ - d86f[drive].index_count = 0; - d86f[drive].state++; - } -} + break; -void d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, uint32_t pos) -{ - uint16_t encoded_byte = 0, mask_data, mask_surface, mask_hole, mask_fuzzy; - decoded_t dbyte, dpbyte; + case FMT_PRETRK_GAP1: + max_len = gap_sizes[1]; + if (do_write) + d86f_write_direct(drive, side, gap_fill, 0); + break; - if (fdc_get_diswr(d86f_fdc)) - return; - - dbyte.byte = byte & 0xff; - dpbyte.byte = d86f[drive].preceding_bit[side] & 0xff; - - if (type == 0) - { - /* Byte write. */ - encoded_byte = d86f_encode_byte(drive, 0, dbyte, dpbyte); - if (!d86f_reverse_bytes(drive)) - { - mask_data = encoded_byte >> 8; - encoded_byte &= 0xFF; - encoded_byte <<= 8; - encoded_byte |= mask_data; + case FMT_SECTOR_IDAM: + max_len = am_len; + if (mfm) { + if (do_write) + d86f_write_direct(drive, side, idam_mfm[dev->datac], 1); + d86f_calccrc(dev, (dev->datac < 3) ? 0xA1 : 0xFE); + } else { + if (do_write) + d86f_write_direct(drive, side, idam_fm, 1); + d86f_calccrc(dev, 0xFE); } - } - else - { - /* Word write. */ - encoded_byte = byte; - if (d86f_reverse_bytes(drive)) - { - mask_data = encoded_byte >> 8; - encoded_byte &= 0xFF; - encoded_byte <<= 8; - encoded_byte |= mask_data; + break; + + case FMT_SECTOR_ID: + max_len = 4; + if (do_write) { + d86f_write_direct(drive, side, dev->format_sector_id.byte_array[dev->datac], 0); + d86f_calccrc(dev, dev->format_sector_id.byte_array[dev->datac]); + } else { + if (dev->datac == 3) { + d86f_handler[drive].set_sector(drive, side, dev->format_sector_id.id.c, dev->format_sector_id.id.h, dev->format_sector_id.id.r, dev->format_sector_id.id.n); + } } - } + break; - d86f[drive].preceding_bit[side] = encoded_byte & 1; + case FMT_SECTOR_ID_CRC: + case FMT_SECTOR_DATA_CRC: + max_len = 2; + if (do_write) + d86f_write_direct(drive, side, dev->calc_crc.bytes[dev->datac ^ 1], 0); + break; - if (d86f_has_surface_desc(drive)) - { - mask_data = d86f[drive].track_encoded_data[side][pos] ^= 0xFFFF; - mask_surface = d86f[drive].track_surface_data[side][pos]; - mask_hole = (mask_surface & mask_data) ^ 0xFFFF; /* This will retain bits that are both fuzzy and 0, therefore physical holes. */ - encoded_byte &= mask_hole; /* Filter out physical hole bits from the encoded data. */ - mask_data ^= 0xFFFF; /* Invert back so bits 1 are 1 again. */ - mask_fuzzy = (mask_surface & mask_data) ^ 0xFFFF; /* All fuzzy bits are 0. */ - d86f[drive].track_surface_data[side][pos] &= mask_fuzzy; /* Remove fuzzy bits (but not hole bits) from the surface mask, making them regular again. */ - } + case FMT_SECTOR_GAP2: + max_len = gap_sizes[2]; + if (do_write) + d86f_write_direct(drive, side, gap_fill, 0); + break; - d86f[drive].track_encoded_data[side][pos] = encoded_byte; - d86f[drive].last_word[side] = encoded_byte; -} - -void d86f_write_direct(int drive, int side, uint16_t byte, uint8_t type) -{ - d86f_write_direct_common(drive, side, byte, type, d86f[drive].track_pos >> 4); -} - -uint16_t endian_swap(uint16_t word) -{ - uint16_t temp; - - temp = word & 0xff; - temp <<= 8; - temp |= (word >> 8); - return temp; -} - -void d86f_format_finish(int drive, int side, int mfm, uint16_t sc, uint16_t gap_fill, int do_write) -{ - if (mfm && do_write) - { - if (do_write && (d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side))) - { - d86f_write_direct_common(drive, side, gap_fill, 0, 0); + case FMT_SECTOR_DATAAM: + max_len = am_len; + if (mfm) { + if (do_write) + d86f_write_direct(drive, side, dataam_mfm[dev->datac], 1); + d86f_calccrc(dev, (dev->datac < 3) ? 0xA1 : 0xFB); + } else { + if (do_write) + d86f_write_direct(drive, side, dataam_fm, 1); + d86f_calccrc(dev, 0xFB); } - } + break; - d86f[drive].state = STATE_IDLE; + case FMT_SECTOR_DATA: + max_len = dtl; + if (do_write) { + d86f_write_direct(drive, side, dev->fill, 0); + d86f_handler[drive].write_data(drive, side, dev->datac, dev->fill); + } + d86f_calccrc(dev, dev->fill); + break; - if (do_write) - { - d86f_handler[drive].writeback(drive); - } + case FMT_SECTOR_GAP3: + max_len = gap_sizes[3]; + if (do_write) + d86f_write_direct(drive, side, gap_fill, 0); + break; - d86f[drive].error_condition = 0; - d86f[drive].datac = 0; - fdc_sector_finishread(d86f_fdc); -} + default: + max_len = 0; + break; + } -void d86f_format_turbo_finish(int drive, int side, int do_write) -{ - d86f[drive].state = STATE_IDLE; + dev->datac++; - if (do_write) - { - d86f_handler[drive].writeback(drive); - } + d86f_advance_word(drive, side); - d86f[drive].error_condition = 0; - d86f[drive].datac = 0; - fdc_sector_finishread(d86f_fdc); -} + if ((dev->index_count) && ((dev->format_state < FMT_SECTOR_ID_SYNC) || (dev->format_state > FMT_SECTOR_GAP3))) { + d86f_format_finish(drive, side, mfm, sc, gap_fill, do_write); + return; + } -void d86f_format_track(int drive, int side, int do_write) -{ - int data; - uint16_t max_len; + if (dev->datac >= max_len) { + dev->datac = 0; + dev->format_state++; - int mfm; - uint16_t sc = 0; - uint16_t dtl = 0; - int gap_sizes[4] = { 0, 0, 0, 0 }; - int am_len = 0; - int sync_len = 0; - uint16_t iam_mfm[4] = { 0x2452, 0x2452, 0x2452, 0x5255 }; - uint16_t idam_mfm[4] = { 0x8944, 0x8944, 0x8944, 0x5455 }; - uint16_t dataam_mfm[4] = { 0x8944, 0x8944, 0x8944, 0x4555 }; - uint16_t iam_fm = 0xFAF7; - uint16_t idam_fm = 0x7EF5; - uint16_t dataam_fm = 0x6FF5; - uint16_t gap_fill = 0x4E; - - mfm = d86f_is_mfm(drive); - am_len = mfm ? 4 : 1; - gap_sizes[0] = mfm ? 80 : 40; - gap_sizes[1] = mfm ? 50 : 26; - gap_sizes[2] = fdc_get_gap2(d86f_fdc, real_drive(d86f_fdc, drive)); - gap_sizes[3] = fdc_get_gap(d86f_fdc); - sync_len = mfm ? 12 : 6; - sc = fdc_get_format_sectors(d86f_fdc); - dtl = 128 << fdc_get_format_n(d86f_fdc); - gap_fill = mfm ? 0x4E : 0xFF; - - switch(d86f[drive].format_state) - { - case FMT_POSTTRK_GAP4: - max_len = 60000; - if (do_write) d86f_write_direct(drive, side, gap_fill, 0); - break; - case FMT_PRETRK_GAP0: - max_len = gap_sizes[0]; - if (do_write) d86f_write_direct(drive, side, gap_fill, 0); - break; + switch (dev->format_state) { case FMT_SECTOR_ID_SYNC: - max_len = sync_len; - if (d86f[drive].datac <= 3) - { - data = fdc_getdata(d86f_fdc, 0); - if (data != -1) - { - data &= 0xff; - } - if ((data == -1) && (d86f[drive].datac < 3)) - { - data = 0; - } - d86f[drive].format_sector_id.byte_array[d86f[drive].datac] = data & 0xff; - if (d86f[drive].datac == 3) - { - fdc_stop_id_request(d86f_fdc); - } - } - case FMT_PRETRK_SYNC: - case FMT_SECTOR_DATA_SYNC: - max_len = sync_len; - if (do_write) d86f_write_direct(drive, side, 0x00, 0); - break; - case FMT_PRETRK_IAM: - max_len = am_len; - if (do_write) - { - if (mfm) - { - d86f_write_direct(drive, side, iam_mfm[d86f[drive].datac], 1); - } - else - { - d86f_write_direct(drive, side, iam_fm, 1); - } - } - break; - case FMT_PRETRK_GAP1: - max_len = gap_sizes[1]; - if (do_write) d86f_write_direct(drive, side, gap_fill, 0); + fdc_request_next_sector_id(d86f_fdc); break; + case FMT_SECTOR_IDAM: - max_len = am_len; - if (mfm) - { - if (do_write) d86f_write_direct(drive, side, idam_mfm[d86f[drive].datac], 1); - d86f_calccrc(drive, (d86f[drive].datac < 3) ? 0xA1 : 0xFE); - } - else - { - if (do_write) d86f_write_direct(drive, side, idam_fm, 1); - d86f_calccrc(drive, 0xFE); - } - break; - case FMT_SECTOR_ID: - max_len = 4; - if (do_write) - { - d86f_write_direct(drive, side, d86f[drive].format_sector_id.byte_array[d86f[drive].datac], 0); - d86f_calccrc(drive, d86f[drive].format_sector_id.byte_array[d86f[drive].datac]); - } - else - { - if (d86f[drive].datac == 3) - { - 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); - } - } - break; - case FMT_SECTOR_ID_CRC: - case FMT_SECTOR_DATA_CRC: - max_len = 2; - if (do_write) d86f_write_direct(drive, side, d86f[drive].calc_crc.bytes[d86f[drive].datac ^ 1], 0); - break; - case FMT_SECTOR_GAP2: - max_len = gap_sizes[2]; - if (do_write) d86f_write_direct(drive, side, gap_fill, 0); - break; case FMT_SECTOR_DATAAM: - max_len = am_len; - if (mfm) - { - if (do_write) d86f_write_direct(drive, side, dataam_mfm[d86f[drive].datac], 1); - d86f_calccrc(drive, (d86f[drive].datac < 3) ? 0xA1 : 0xFB); + dev->calc_crc.word = 0xffff; + break; + + case FMT_POSTTRK_CHECK: + if (dev->index_count) { + d86f_format_finish(drive, side, mfm, sc, gap_fill, do_write); + return; } - else - { - if (do_write) d86f_write_direct(drive, side, dataam_fm, 1); - d86f_calccrc(drive, 0xFB); - } - break; - case FMT_SECTOR_DATA: - max_len = dtl; - if (do_write) - { - d86f_write_direct(drive, side, d86f[drive].fill, 0); - d86f_handler[drive].write_data(drive, side, d86f[drive].datac, d86f[drive].fill); - } - d86f_calccrc(drive, d86f[drive].fill); - break; - case FMT_SECTOR_GAP3: - max_len = gap_sizes[3]; - if (do_write) d86f_write_direct(drive, side, gap_fill, 0); - break; - default: - max_len = 0; - break; - } - - d86f[drive].datac++; - - d86f_advance_word(drive, side); - - if ((d86f[drive].index_count) && ((d86f[drive].format_state < FMT_SECTOR_ID_SYNC) || (d86f[drive].format_state > FMT_SECTOR_GAP3))) - { - d86f_format_finish(drive, side, mfm, sc, gap_fill, do_write); - return; - } - - if (d86f[drive].datac >= max_len) - { - d86f[drive].datac = 0; - d86f[drive].format_state++; - - switch (d86f[drive].format_state) - { - case FMT_SECTOR_ID_SYNC: + dev->sector_count++; + if (dev->sector_count < sc) { + /* Sector within allotted amount, change state to SECTOR_ID_SYNC. */ + dev->format_state = FMT_SECTOR_ID_SYNC; fdc_request_next_sector_id(d86f_fdc); break; - case FMT_SECTOR_IDAM: - case FMT_SECTOR_DATAAM: - d86f[drive].calc_crc.word = 0xffff; + } else { + dev->format_state = FMT_POSTTRK_GAP4; + dev->sector_count = 0; break; - case FMT_POSTTRK_CHECK: - if (d86f[drive].index_count) - { - d86f_format_finish(drive, side, mfm, sc, gap_fill, do_write); - return; - } - d86f[drive].sector_count++; - if (d86f[drive].sector_count < sc) - { - /* Sector within allotted amount, change state to SECTOR_ID_SYNC. */ - d86f[drive].format_state = FMT_SECTOR_ID_SYNC; - fdc_request_next_sector_id(d86f_fdc); - break; - } - else - { - d86f[drive].format_state = FMT_POSTTRK_GAP4; - d86f[drive].sector_count = 0; - break; - } - } - } -} - -void d86f_format_track_normal(int drive, int side) -{ - d86f_format_track(drive, side, (d86f[drive].version == D86FVER)); -} - -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 < (128UL << d86f[drive].last_sector.id.n)) - { - if (d86f[drive].state != STATE_16_VERIFY_DATA) - { - read_status = fdc_data(d86f_fdc, 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(d86f_fdc); - fdc_overrun(d86f_fdc); - 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_fdc, (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(d86f_fdc); - } + break; } + } } -void d86f_turbo_write(int drive, int side) + +void +d86f_format_track_normal(int drive, int side) { - uint8_t dat = 0; + d86f_t *dev = d86f[drive]; - dat = d86f_get_data(drive, 1); - d86f_handler[drive].write_data(drive, side, d86f[drive].turbo_pos, dat); + d86f_format_track(drive, side, (dev->version == D86FVER)); +} - 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); +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_t *dev = d86f[drive]; + + dev->last_sector.id.c = c; + dev->last_sector.id.h = h; + dev->last_sector.id.r = r; + dev->last_sector.id.n = n; +} + + +void +d86f_turbo_read(int drive, int side) +{ + d86f_t *dev = d86f[drive]; + uint8_t dat = 0; + int recv_data = 0; + int read_status = 0; + + dat = d86f_handler[drive].read_data(drive, side, dev->turbo_pos); + dev->turbo_pos++; + + if (dev->state == STATE_11_SCAN_DATA) { + /* Scan/compare command. */ + recv_data = d86f_get_data(drive, 0); + d86f_compare_byte(drive, recv_data, dat); + } else { + if (dev->data_find.bytes_obtained < (128UL << dev->last_sector.id.n)) { + if (dev->state != STATE_16_VERIFY_DATA) { + read_status = fdc_data(d86f_fdc, dat); + if (read_status == -1) + dev->dma_over++; + } + } + } + + if (dev->dma_over > 1) { + dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; + dev->error_condition = 0; + dev->state = STATE_IDLE; + fdc_finishread(d86f_fdc); + fdc_overrun(d86f_fdc); + return; + } + + if (dev->turbo_pos >= (128 << dev->last_sector.id.n)) { + /* CRC is valid. */ + dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; + dev->error_condition = 0; + if (dev->state == STATE_11_SCAN_DATA) { + dev->state = STATE_IDLE; + fdc_sector_finishcompare(d86f_fdc, (dev->satisfying_bytes == ((128 << ((uint32_t) dev->last_sector.id.n)) - 1)) ? 1 : 0); + } else { + dev->state = STATE_IDLE; fdc_sector_finishread(d86f_fdc); - return; } + } } -void d86f_turbo_format(int drive, int side, int nop) + +void +d86f_turbo_write(int drive, int side) { - int dat; - int i = 0; + d86f_t *dev = d86f[drive]; + uint8_t dat = 0; - uint16_t sc = 0; - uint16_t dtl = 0; + dat = d86f_get_data(drive, 1); + d86f_handler[drive].write_data(drive, side, dev->turbo_pos, dat); - sc = fdc_get_format_sectors(d86f_fdc); - dtl = 128 << fdc_get_format_n(d86f_fdc); + dev->turbo_pos++; - if (d86f[drive].datac <= 3) - { - dat = fdc_getdata(d86f_fdc, 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_fdc); - 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(d86f_fdc); - } - else - { - d86f[drive].state = STATE_IDLE; - d86f_format_turbo_finish(drive, side, nop); - } - } + if (dev->turbo_pos >= (128 << dev->last_sector.id.n)) { + /* We've written the data. */ + dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; + dev->error_condition = 0; + dev->state = STATE_IDLE; + d86f_handler[drive].writeback(drive); + fdc_sector_finishread(d86f_fdc); + } } -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; - } +void +d86f_turbo_format(int drive, int side, int nop) +{ + d86f_t *dev = d86f[drive]; + int dat; + uint16_t sc; + uint16_t dtl; + int i; + + sc = fdc_get_format_sectors(d86f_fdc); + dtl = 128 << fdc_get_format_n(d86f_fdc); + + if (dev->datac <= 3) { + dat = fdc_getdata(d86f_fdc, 0); + if (dat != -1) + dat &= 0xff; + if ((dat == -1) && (dev->datac < 3)) + dat = 0; + dev->format_sector_id.byte_array[dev->datac] = dat & 0xff; + if (dev->datac == 3) { + fdc_stop_id_request(d86f_fdc); + d86f_handler[drive].set_sector(drive, side, dev->format_sector_id.id.c, dev->format_sector_id.id.h, dev->format_sector_id.id.r, dev->format_sector_id.id.n); } - return 0; + } else if (dev->datac == 4) { + if (! nop) { + for (i = 0; i < dtl; i++) + d86f_handler[drive].write_data(drive, side, i, dev->fill); + } + + dev->sector_count++; + } + + dev->datac++; + + if (dev->datac == 6) { + dev->datac = 0; + + if (dev->sector_count < sc) { + /* Sector within allotted amount. */ + fdc_request_next_sector_id(d86f_fdc); + } else { + dev->state = STATE_IDLE; + d86f_format_turbo_finish(drive, side, nop); + } + } } -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)) - { - if (!d86f_can_read_address(drive)) - { - d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0; - fdc_noidam(d86f_fdc); - d86f[drive].state = STATE_IDLE; - return; - } - } - 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_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); - d86f[drive].state = STATE_IDLE; - return; - } - d86f[drive].last_sector.id.c = fdc_get_read_track_sector(d86f_fdc).id.c; - d86f[drive].last_sector.id.h = fdc_get_read_track_sector(d86f_fdc).id.h; - d86f[drive].last_sector.id.r = fdc_get_read_track_sector(d86f_fdc).id.r; - d86f[drive].last_sector.id.n = fdc_get_read_track_sector(d86f_fdc).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_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); - 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_fdc, 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: +int +d86f_sector_is_present(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) +{ + d86f_t *dev = d86f[drive]; + sector_t *s, *t; + + if (dev->last_side_sector[side]) { + s = dev->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_poll(int drive) + +void +d86f_turbo_poll(int drive, int side) { - int side = 0; - int mfm = 1; + d86f_t *dev = d86f[drive]; - side = fdd_get_head(drive); - if (!fdd_is_double_sided(drive)) - { - side = 0; - } - - mfm = fdc_is_mfm(d86f_fdc); - - if ((d86f[drive].state & 0xF8) == 0xE8) - { - if (!d86f_can_format(drive)) - { - d86f[drive].state = STATE_SECTOR_NOT_FOUND; - } - } - - if (fdd_get_turbo(drive) && (d86f[drive].version == 0x0063)) - { - d86f_turbo_poll(drive, side); - return; - } - - if ((d86f[drive].state != STATE_IDLE) && (d86f[drive].state != STATE_SECTOR_NOT_FOUND) && ((d86f[drive].state & 0xF8) != 0xE8)) - { - if (!d86f_can_read_address(drive)) - { - - d86f[drive].state = STATE_SECTOR_NOT_FOUND; - } - } - - if ((d86f[drive].state != STATE_02_SPIN_TO_INDEX) && (d86f[drive].state != STATE_0D_SPIN_TO_INDEX)) - { - d86f_get_bit(drive, side ^ 1); - } - - switch(d86f[drive].state) - { - case STATE_02_SPIN_TO_INDEX: - case STATE_0D_SPIN_TO_INDEX: - case STATE_0D_NOP_SPIN_TO_INDEX: - d86f_spin_to_index(drive, side); - return; - case STATE_02_FIND_ID: - case STATE_05_FIND_ID: - case STATE_09_FIND_ID: - case STATE_06_FIND_ID: - case STATE_0A_FIND_ID: - case STATE_0C_FIND_ID: - case STATE_11_FIND_ID: - case STATE_16_FIND_ID: - if (mfm) - { - d86f_find_address_mark_mfm(drive, side, &(d86f[drive].id_find), 0x5554, 0, 0); - } - else - { - d86f_find_address_mark_fm(drive, side, &(d86f[drive].id_find), 0xF57E, 0, 0); - } - break; - case STATE_0A_READ_ID: - case STATE_02_READ_ID: - d86f_read_sector_id(drive, side, 0); - break; - 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_read_sector_id(drive, side, 1); - break; - case STATE_02_FIND_DATA: - if (mfm) - { - d86f_find_address_mark_mfm(drive, side, &(d86f[drive].data_find), 0x5545, 0x554A, 2); - } - else - { - d86f_find_address_mark_fm(drive, side, &(d86f[drive].data_find), 0xF56F, 0xF56A, 2); - } - break; - case STATE_06_FIND_DATA: - case STATE_11_FIND_DATA: - case STATE_16_FIND_DATA: - if (mfm) - { - d86f_find_address_mark_mfm(drive, side, &(d86f[drive].data_find), 0x5545, 0x554A, fdc_is_sk(d86f_fdc) | 2); - } - else - { - d86f_find_address_mark_fm(drive, side, &(d86f[drive].data_find), 0xF56F, 0xF56A, fdc_is_sk(d86f_fdc) | 2); - } - break; - case STATE_05_FIND_DATA: - case STATE_09_FIND_DATA: - if (mfm) - { - d86f_write_find_address_mark_mfm(drive, side, &(d86f[drive].data_find)); - } - else - { - d86f_write_find_address_mark_fm(drive, side, &(d86f[drive].data_find)); - } - break; - case STATE_0C_FIND_DATA: - if (mfm) - { - d86f_find_address_mark_mfm(drive, side, &(d86f[drive].data_find), 0x554A, 0x5545, fdc_is_sk(d86f_fdc) | 2); - } - else - { - d86f_find_address_mark_fm(drive, side, &(d86f[drive].data_find), 0xF56A, 0xF56F, fdc_is_sk(d86f_fdc) | 2); - } - 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_read_sector_data(drive, side); - break; - case STATE_05_WRITE_DATA: - if (mfm) - { - d86f_write_sector_data(drive, side, mfm, 0x5545); - } - else - { - d86f_write_sector_data(drive, side, mfm, 0xF56F); - } - break; - case STATE_09_WRITE_DATA: - if (mfm) - { - d86f_write_sector_data(drive, side, mfm, 0x554A); - } - else - { - d86f_write_sector_data(drive, side, mfm, 0xF56A); - } - break; - case STATE_0D_FORMAT_TRACK: - if (!(d86f[drive].track_pos & 15)) - { - d86f_format_track_normal(drive, side); - } - return; - case STATE_0D_NOP_FORMAT_TRACK: - if (!(d86f[drive].track_pos & 15)) - { - d86f_format_track_nop(drive, side); - } - return; - case STATE_IDLE: - case STATE_SECTOR_NOT_FOUND: - default: - d86f_get_bit(drive, side); - break; - } - - d86f_advance_bit(drive, side); - - if (d86f_wrong_densel(drive) && (d86f[drive].state != STATE_IDLE)) - { - d86f[drive].state = STATE_IDLE; + if ((dev->state != STATE_IDLE) && (dev->state != STATE_SECTOR_NOT_FOUND) && ((dev->state & 0xF8) != 0xE8)) { + if (! d86f_can_read_address(drive)) { + dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = dev->error_condition = 0; fdc_noidam(d86f_fdc); + dev->state = STATE_IDLE; return; } + } - if ((d86f[drive].index_count == 2) && (d86f[drive].state != STATE_IDLE)) - { - switch(d86f[drive].state) - { - case STATE_0A_FIND_ID: - case STATE_SECTOR_NOT_FOUND: - d86f[drive].state = STATE_IDLE; - fdc_noidam(d86f_fdc); - 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 = STATE_IDLE; - fdc_nodataam(d86f_fdc); - break; - case STATE_02_SPIN_TO_INDEX: - case STATE_02_READ_DATA: - case STATE_05_WRITE_DATA: - case STATE_06_READ_DATA: - case STATE_09_WRITE_DATA: - case STATE_0C_READ_DATA: - case STATE_0D_SPIN_TO_INDEX: - case STATE_0D_FORMAT_TRACK: - case STATE_11_SCAN_DATA: - case STATE_16_VERIFY_DATA: - /* In these states, we should *NEVER* care about how many index pulses there have been. */ - break; - default: - d86f[drive].state = STATE_IDLE; - if (d86f[drive].id_found) - { - if (d86f[drive].error_condition & 0x18) - { - if ((d86f[drive].error_condition & 0x18) == 0x08) - { - fdc_badcylinder(d86f_fdc); - } - if ((d86f[drive].error_condition & 0x10) == 0x10) - { - fdc_wrongcylinder(d86f_fdc); - } - } - else - { - fdc_nosector(d86f_fdc); - } - } - else - { - fdc_noidam(d86f_fdc); - } - break; + switch(dev->state) { + case STATE_0D_SPIN_TO_INDEX: + case STATE_0D_NOP_SPIN_TO_INDEX: + dev->sector_count = 0; + dev->datac = 5; + /*FALLTHROUGH*/ + + case STATE_02_SPIN_TO_INDEX: + dev->state++; + return; + + case STATE_02_FIND_ID: + 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)) { + dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = dev->error_condition = 0; + fdc_nosector(d86f_fdc); + dev->state = STATE_IDLE; + return; } - } -} + dev->last_sector.id.c = fdc_get_read_track_sector(d86f_fdc).id.c; + dev->last_sector.id.h = fdc_get_read_track_sector(d86f_fdc).id.h; + dev->last_sector.id.r = fdc_get_read_track_sector(d86f_fdc).id.r; + dev->last_sector.id.n = fdc_get_read_track_sector(d86f_fdc).id.n; + d86f_handler[drive].set_sector(drive, side, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n); + dev->turbo_pos = 0; + dev->state++; + return; -#if 0 -void d86f_poll(int drive) -{ - int i = 0; - for (i = 0; i < 16; i++) - { - d86f_bit_poll(drive); - } -} - -void d86f_poll() -{ - int drive = 0; - drive = fdc_get_drive(d86f_fdc); - d86f_poll_per_drive(drive); -} -#endif - -void d86f_reset_index_hole_pos(int drive, int side) -{ - d86f[drive].index_hole_pos[side] = 0; -} - -uint16_t d86f_prepare_pretrack(int drive, int side, int iso) -{ - uint16_t i, pos; - - int mfm = 0; - int real_gap0_len = 0; - int sync_len = 0; - int real_gap1_len = 0; - uint16_t gap_fill = 0; - uint32_t raw_size = 0; - uint16_t iam_fm = 0xFAF7; - uint16_t iam_mfm = 0x5255; - - mfm = d86f_is_mfm(drive); - real_gap0_len = mfm ? 80 : 40; - sync_len = mfm ? 12 : 6; - real_gap1_len = mfm ? 50 : 26; - gap_fill = mfm ? 0x4E : 0xFF; - raw_size = d86f_handler[drive].get_raw_size(drive, side) >> 4; - - 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); - } - - pos = 0; - - if (!iso) - { - for (i = 0; i < real_gap0_len; i++) - { - d86f_write_direct_common(drive, side, gap_fill, 0, pos); - pos = (pos + 1) % raw_size; - } - for (i = 0; i < sync_len; i++) - { - d86f_write_direct_common(drive, side, 0, 0, pos); - pos = (pos + 1) % raw_size; + 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_sector_is_present(drive, side, + dev->req_sector.id.c, + dev->req_sector.id.h, + dev->req_sector.id.r, + dev->req_sector.id.n)) { + dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = dev->error_condition = 0; + fdc_nosector(d86f_fdc); + dev->state = STATE_IDLE; + return; } + dev->last_sector.id.c = dev->req_sector.id.c; + dev->last_sector.id.h = dev->req_sector.id.h; + dev->last_sector.id.r = dev->req_sector.id.r; + dev->last_sector.id.n = dev->req_sector.id.n; + d86f_handler[drive].set_sector(drive, side, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n); + /*FALLTHROUGH*/ + + case STATE_0A_FIND_ID: + dev->turbo_pos = 0; + dev->state++; + return; + + case STATE_0A_READ_ID: + dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = dev->error_condition = 0; + fdc_sectorid(d86f_fdc, dev->last_sector.id.c, dev->last_sector.id.h, dev->last_sector.id.r, dev->last_sector.id.n, 0, 0); + dev->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: + dev->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: + dev->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) +{ + d86f_t *dev = d86f[drive]; + int mfm, side; + + side = fdd_get_head(drive); + if (! fdd_is_double_sided(drive)) + side = 0; + + mfm = fdc_is_mfm(d86f_fdc); + + if ((dev->state & 0xF8) == 0xE8) { + if (! d86f_can_format(drive)) + dev->state = STATE_SECTOR_NOT_FOUND; + } + + if (fdd_get_turbo(drive) && (dev->version == 0x0063)) { + d86f_turbo_poll(drive, side); + return; + } + + if ((dev->state != STATE_IDLE) && (dev->state != STATE_SECTOR_NOT_FOUND) && ((dev->state & 0xF8) != 0xE8)) { + if (! d86f_can_read_address(drive)) + dev->state = STATE_SECTOR_NOT_FOUND; + } + + if ((dev->state != STATE_02_SPIN_TO_INDEX) && (dev->state != STATE_0D_SPIN_TO_INDEX)) + d86f_get_bit(drive, side ^ 1); + + switch(dev->state) { + case STATE_02_SPIN_TO_INDEX: + case STATE_0D_SPIN_TO_INDEX: + case STATE_0D_NOP_SPIN_TO_INDEX: + d86f_spin_to_index(drive, side); + return; + + case STATE_02_FIND_ID: + case STATE_05_FIND_ID: + case STATE_09_FIND_ID: + case STATE_06_FIND_ID: + case STATE_0A_FIND_ID: + case STATE_0C_FIND_ID: + case STATE_11_FIND_ID: + case STATE_16_FIND_ID: if (mfm) - { - for (i = 0; i < 3; i++) - { - d86f_write_direct_common(drive, side, 0x2452, 1, pos); - pos = (pos + 1) % raw_size; - } - } - d86f_write_direct_common(drive, side, mfm ? iam_mfm : iam_fm, 1, pos); - pos = (pos + 1) % raw_size; - } - for (i = 0; i < real_gap1_len; i++) - { - d86f_write_direct_common(drive, side, gap_fill, 0, pos); - pos = (pos + 1) % raw_size; - } - - return pos; -} - -uint16_t d86f_prepare_sector(int drive, int side, int prev_pos, uint8_t *id_buf, uint8_t *data_buf, int data_len, int gap2, int gap3, int deleted, int bad_crc) -{ - uint16_t pos; - - int i; - sector_t *s; - - int real_gap2_len = gap2; - int real_gap3_len = gap3; - int mfm = 0; - int sync_len = 0; - uint16_t gap_fill = 0; - uint32_t raw_size = 0; - uint16_t idam_fm = 0x7EF5; - uint16_t dataam_fm = 0x6FF5; - uint16_t datadam_fm = 0x6AF5; - uint16_t idam_mfm = 0x5455; - uint16_t dataam_mfm = 0x4555; - uint16_t datadam_mfm = 0x4A55; - - if (fdd_get_turbo(drive) && (d86f[drive].version == 0x0063)) { - 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); - - gap_fill = mfm ? 0x4E : 0xFF; - raw_size = d86f_handler[drive].get_raw_size(drive, side) >> 4; - - pos = prev_pos; - - sync_len = mfm ? 12 : 6; - - for (i = 0; i < sync_len; i++) - { - d86f_write_direct_common(drive, side, 0, 0, pos); - pos = (pos + 1) % raw_size; - } - d86f[drive].calc_crc.word = 0xffff; - if (mfm) - { - for (i = 0; i < 3; i++) - { - d86f_write_direct_common(drive, side, 0x8944, 1, pos); - pos = (pos + 1) % raw_size; - d86f_calccrc(drive, 0xA1); - } - } - d86f_write_direct_common(drive, side, mfm ? idam_mfm : idam_fm, 1, pos); - pos = (pos + 1) % raw_size; - d86f_calccrc(drive, 0xFE); - for (i = 0; i < 4; i++) - { - d86f_write_direct_common(drive, side, id_buf[i], 0, pos); - pos = (pos + 1) % raw_size; - d86f_calccrc(drive, id_buf[i]); - } - for (i = 1; i >= 0; i--) - { - d86f_write_direct_common(drive, side, d86f[drive].calc_crc.bytes[i], 0, pos); - pos = (pos + 1) % raw_size; - } - for (i = 0; i < real_gap2_len; i++) - { - d86f_write_direct_common(drive, side, gap_fill, 0, pos); - pos = (pos + 1) % raw_size; - } - for (i = 0; i < sync_len; i++) - { - d86f_write_direct_common(drive, side, 0, 0, pos); - pos = (pos + 1) % raw_size; - } - d86f[drive].calc_crc.word = 0xffff; - if (mfm) - { - for (i = 0; i < 3; i++) - { - d86f_write_direct_common(drive, side, 0x8944, 1, pos); - pos = (pos + 1) % raw_size; - d86f_calccrc(drive, 0xA1); - } - } - d86f_write_direct_common(drive, side, mfm ? (deleted ? datadam_mfm : dataam_mfm) : (deleted ? datadam_fm : dataam_fm), 1, pos); - pos = (pos + 1) % raw_size; - d86f_calccrc(drive, deleted ? 0xF8 : 0xFB); - for (i = 0; i < data_len; i++) - { - d86f_write_direct_common(drive, side, data_buf[i], 0, pos); - pos = (pos + 1) % raw_size; - d86f_calccrc(drive, data_buf[i]); - } - if (bad_crc) - { - d86f[drive].calc_crc.word ^= 0xffff; - } - for (i = 1; i >= 0; i--) - { - d86f_write_direct_common(drive, side, d86f[drive].calc_crc.bytes[i], 0, pos); - pos = (pos + 1) % raw_size; - } - for (i = 0; i < real_gap3_len; i++) - { - d86f_write_direct_common(drive, side, gap_fill, 0, pos); - pos = (pos + 1) % raw_size; - } - - return pos; -} - -/* Note on handling of tracks on thick track drives: - - On seek, encoded data is constructed from both (track << 1) and ((track << 1) + 1); - - Any bits that differ are treated as thus: - - Both are regular but contents differ -> Output is fuzzy; - - One is regular and one is fuzzy -> Output is fuzzy; - - Both are fuzzy -> Output is fuzzy; - - Both are physical holes -> Output is a physical hole; - - One is regular and one is a physical hole -> Output is puzzy, the hole half is handled appropriately on writeback; - - One is fuzzy and one is a physical hole -> Output is puzzy, the hole half is handled appropriately on writeback; - - On write back, apart from the above notes, the final two tracks are written; - - Destination ALWAYS has surface data even if the image does not. - In case of a thin track drive, tracks are handled normally. */ - -void d86f_construct_encoded_buffer(int drive, int side) -{ - uint32_t i = 0; - /* *_fuzm are fuzzy bit masks, *_holm are hole masks, dst_neim are masks is mask for bits that are neither fuzzy nor holes in both, - and src1_d and src2_d are filtered source data. */ - uint16_t src1_fuzm, src2_fuzm, dst_fuzm, src1_holm, src2_holm, dst_holm, dst_neim, src1_d, src2_d; - uint32_t len; - uint16_t *dst = d86f[drive].track_encoded_data[side]; - uint16_t *dst_s = d86f[drive].track_surface_data[side]; - uint16_t *src1 = d86f[drive].thin_track_encoded_data[0][side]; - uint16_t *src1_s = d86f[drive].thin_track_surface_data[0][side]; - uint16_t *src2 = d86f[drive].thin_track_encoded_data[1][side]; - uint16_t *src2_s = d86f[drive].thin_track_surface_data[1][side]; - len = d86f_get_array_size(drive, side); - - for (i = 0; i < len; i++) - { - /* The two bits differ. */ - if (d86f_has_surface_desc(drive)) - { - /* Source image has surface description data, so we have some more handling to do. */ - src1_fuzm = src1[i] & src1_s[i]; - src2_fuzm = src2[i] & src2_s[i]; - dst_fuzm = src1_fuzm | src2_fuzm; /* The bits that remain set are fuzzy in either one or - the other or both. */ - src1_holm = src1[i] | (src1_s[i] ^ 0xffff); - src2_holm = src2[i] | (src2_s[i] ^ 0xffff); - dst_holm = (src1_holm & src2_holm) ^ 0xffff; /* The bits that remain set are holes in both. */ - dst_neim = (dst_fuzm | dst_holm) ^ 0xffff; /* The bits that remain set are those that are neither - fuzzy nor are holes in both. */ - src1_d = src1[i] & dst_neim; - src2_d = src2[i] & dst_neim; - - dst_s[i] = (dst_neim ^ 0xffff); /* The set bits are those that are either fuzzy or are - holes in both. */ - dst[i] = (src1_d | src2_d); /* Initial data is remaining data from Source 1 and - Source 2. */ - dst[i] |= dst_fuzm; /* Add to it the fuzzy bytes (holes have surface bit set - but data bit clear). */ - } + d86f_find_address_mark_mfm(drive, side, &(dev->id_find), 0x5554, 0, 0); else - { - /* No surface data, the handling is much simpler - a simple OR. */ - dst[i] = src1[i] | src2[i]; - dst_s[i] = 0; + d86f_find_address_mark_fm(drive, side, &(dev->id_find), 0xF57E, 0, 0); + break; + + case STATE_0A_READ_ID: + case STATE_02_READ_ID: + d86f_read_sector_id(drive, side, 0); + break; + + 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_read_sector_id(drive, side, 1); + break; + + case STATE_02_FIND_DATA: + if (mfm) + d86f_find_address_mark_mfm(drive, side, &(dev->data_find), 0x5545, 0x554A, 2); + else + d86f_find_address_mark_fm(drive, side, &(dev->data_find), 0xF56F, 0xF56A, 2); + break; + + case STATE_06_FIND_DATA: + case STATE_11_FIND_DATA: + case STATE_16_FIND_DATA: + if (mfm) + d86f_find_address_mark_mfm(drive, side, &(dev->data_find), 0x5545, 0x554A, fdc_is_sk(d86f_fdc) | 2); + else + d86f_find_address_mark_fm(drive, side, &(dev->data_find), 0xF56F, 0xF56A, fdc_is_sk(d86f_fdc) | 2); + break; + + case STATE_05_FIND_DATA: + case STATE_09_FIND_DATA: + if (mfm) + d86f_write_find_address_mark_mfm(drive, side, &(dev->data_find)); + else + d86f_write_find_address_mark_fm(drive, side, &(dev->data_find)); + break; + + case STATE_0C_FIND_DATA: + if (mfm) + d86f_find_address_mark_mfm(drive, side, &(dev->data_find), 0x554A, 0x5545, fdc_is_sk(d86f_fdc) | 2); + else + d86f_find_address_mark_fm(drive, side, &(dev->data_find), 0xF56A, 0xF56F, fdc_is_sk(d86f_fdc) | 2); + 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_read_sector_data(drive, side); + break; + + case STATE_05_WRITE_DATA: + if (mfm) + d86f_write_sector_data(drive, side, mfm, 0x5545); + else + d86f_write_sector_data(drive, side, mfm, 0xF56F); + break; + + case STATE_09_WRITE_DATA: + if (mfm) + d86f_write_sector_data(drive, side, mfm, 0x554A); + else + d86f_write_sector_data(drive, side, mfm, 0xF56A); + break; + + case STATE_0D_FORMAT_TRACK: + if (! (dev->track_pos & 15)) + d86f_format_track_normal(drive, side); + return; + + case STATE_0D_NOP_FORMAT_TRACK: + if (! (dev->track_pos & 15)) + d86f_format_track_nop(drive, side); + return; + + case STATE_IDLE: + case STATE_SECTOR_NOT_FOUND: + default: + d86f_get_bit(drive, side); + break; + } + + d86f_advance_bit(drive, side); + + if (d86f_wrong_densel(drive) && (dev->state != STATE_IDLE)) { + dev->state = STATE_IDLE; + fdc_noidam(d86f_fdc); + return; + } + + if ((dev->index_count == 2) && (dev->state != STATE_IDLE)) { + switch(dev->state) { + case STATE_0A_FIND_ID: + case STATE_SECTOR_NOT_FOUND: + dev->state = STATE_IDLE; + fdc_noidam(d86f_fdc); + 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: + + dev->state = STATE_IDLE; + fdc_nodataam(d86f_fdc); + break; + + case STATE_02_SPIN_TO_INDEX: + case STATE_02_READ_DATA: + case STATE_05_WRITE_DATA: + case STATE_06_READ_DATA: + case STATE_09_WRITE_DATA: + case STATE_0C_READ_DATA: + case STATE_0D_SPIN_TO_INDEX: + case STATE_0D_FORMAT_TRACK: + case STATE_11_SCAN_DATA: + case STATE_16_VERIFY_DATA: + /* In these states, we should *NEVER* care about how many index pulses there have been. */ + break; + + default: + dev->state = STATE_IDLE; + if (dev->id_found) { + if (dev->error_condition & 0x18) { + if ((dev->error_condition & 0x18) == 0x08) + fdc_badcylinder(d86f_fdc); + if ((dev->error_condition & 0x10) == 0x10) + fdc_wrongcylinder(d86f_fdc); + else + fdc_nosector(d86f_fdc); + } + } else { + fdc_noidam(d86f_fdc); + } + break; + } + } +} + + +void +d86f_reset_index_hole_pos(int drive, int side) +{ + d86f_t *dev = d86f[drive]; + + dev->index_hole_pos[side] = 0; +} + + +uint16_t +d86f_prepare_pretrack(int drive, int side, int iso) +{ + d86f_t *dev = d86f[drive]; + uint16_t i, pos; + int mfm; + int real_gap0_len; + int sync_len; + int real_gap1_len; + uint16_t gap_fill; + uint32_t raw_size; + uint16_t iam_fm = 0xFAF7; + uint16_t iam_mfm = 0x5255; + + mfm = d86f_is_mfm(drive); + real_gap0_len = mfm ? 80 : 40; + sync_len = mfm ? 12 : 6; + real_gap1_len = mfm ? 50 : 26; + gap_fill = mfm ? 0x4E : 0xFF; + raw_size = d86f_handler[drive].get_raw_size(drive, side) >> 4; + + dev->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); + + pos = 0; + + if (! iso) { + for (i = 0; i < real_gap0_len; i++) { + d86f_write_direct_common(drive, side, gap_fill, 0, pos); + pos = (pos + 1) % raw_size; + } + for (i = 0; i < sync_len; i++) { + d86f_write_direct_common(drive, side, 0, 0, pos); + pos = (pos + 1) % raw_size; + } + if (mfm) { + for (i = 0; i < 3; i++) { + d86f_write_direct_common(drive, side, 0x2452, 1, pos); + pos = (pos + 1) % raw_size; } } + + d86f_write_direct_common(drive, side, mfm ? iam_mfm : iam_fm, 1, pos); + pos = (pos + 1) % raw_size; + } + + for (i = 0; i < real_gap1_len; i++) { + d86f_write_direct_common(drive, side, gap_fill, 0, pos); + pos = (pos + 1) % raw_size; + } + + return pos; } + +uint16_t +d86f_prepare_sector(int drive, int side, int prev_pos, uint8_t *id_buf, uint8_t *data_buf, int data_len, int gap2, int gap3, int deleted, int bad_crc) +{ + d86f_t *dev = d86f[drive]; + uint16_t pos; + int i; + sector_t *s; + + int real_gap2_len = gap2; + int real_gap3_len = gap3; + int mfm; + int sync_len; + uint16_t gap_fill; + uint32_t raw_size; + uint16_t idam_fm = 0x7EF5; + uint16_t dataam_fm = 0x6FF5; + uint16_t datadam_fm = 0x6AF5; + uint16_t idam_mfm = 0x5455; + uint16_t dataam_mfm = 0x4555; + uint16_t datadam_mfm = 0x4A55; + + if (fdd_get_turbo(drive) && (dev->version == 0x0063)) { + 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 (dev->last_side_sector[side]) + s->prev = dev->last_side_sector[side]; + dev->last_side_sector[side] = s; + } + + mfm = d86f_is_mfm(drive); + + gap_fill = mfm ? 0x4E : 0xFF; + raw_size = d86f_handler[drive].get_raw_size(drive, side) >> 4; + + pos = prev_pos; + + sync_len = mfm ? 12 : 6; + + for (i = 0; i < sync_len; i++) { + d86f_write_direct_common(drive, side, 0, 0, pos); + pos = (pos + 1) % raw_size; + } + dev->calc_crc.word = 0xffff; + if (mfm) { + for (i = 0; i < 3; i++) { + d86f_write_direct_common(drive, side, 0x8944, 1, pos); + pos = (pos + 1) % raw_size; + d86f_calccrc(dev, 0xA1); + } + } + d86f_write_direct_common(drive, side, mfm ? idam_mfm : idam_fm, 1, pos); + pos = (pos + 1) % raw_size; + d86f_calccrc(dev, 0xFE); + for (i = 0; i < 4; i++) { + d86f_write_direct_common(drive, side, id_buf[i], 0, pos); + pos = (pos + 1) % raw_size; + d86f_calccrc(dev, id_buf[i]); + } + for (i = 1; i >= 0; i--) { + d86f_write_direct_common(drive, side, dev->calc_crc.bytes[i], 0, pos); + pos = (pos + 1) % raw_size; + } + for (i = 0; i < real_gap2_len; i++) { + d86f_write_direct_common(drive, side, gap_fill, 0, pos); + pos = (pos + 1) % raw_size; + } + for (i = 0; i < sync_len; i++) { + d86f_write_direct_common(drive, side, 0, 0, pos); + pos = (pos + 1) % raw_size; + } + dev->calc_crc.word = 0xffff; + if (mfm) { + for (i = 0; i < 3; i++) { + d86f_write_direct_common(drive, side, 0x8944, 1, pos); + pos = (pos + 1) % raw_size; + d86f_calccrc(dev, 0xA1); + } + } + d86f_write_direct_common(drive, side, mfm ? (deleted ? datadam_mfm : dataam_mfm) : (deleted ? datadam_fm : dataam_fm), 1, pos); + pos = (pos + 1) % raw_size; + d86f_calccrc(dev, deleted ? 0xF8 : 0xFB); + for (i = 0; i < data_len; i++) { + d86f_write_direct_common(drive, side, data_buf[i], 0, pos); + pos = (pos + 1) % raw_size; + d86f_calccrc(dev, data_buf[i]); + } + if (bad_crc) + dev->calc_crc.word ^= 0xffff; + for (i = 1; i >= 0; i--) { + d86f_write_direct_common(drive, side, dev->calc_crc.bytes[i], 0, pos); + pos = (pos + 1) % raw_size; + } + for (i = 0; i < real_gap3_len; i++) { + d86f_write_direct_common(drive, side, gap_fill, 0, pos); + pos = (pos + 1) % raw_size; + } + + return pos; +} + + +/* + * Note on handling of tracks on thick track drives: + * + * - On seek, encoded data is constructed from both (track << 1) and + * ((track << 1) + 1); + * + * - Any bits that differ are treated as thus: + * - Both are regular but contents differ -> Output is fuzzy; + * - One is regular and one is fuzzy -> Output is fuzzy; + * - Both are fuzzy -> Output is fuzzy; + * - Both are physical holes -> Output is a physical hole; + * - One is regular and one is a physical hole -> Output is puzzy, + * the hole half is handled appropriately on writeback; + * - One is fuzzy and one is a physical hole -> Output is puzzy, + * the hole half is handled appropriately on writeback; + * - On write back, apart from the above notes, the final two tracks + * are written; + * - Destination ALWAYS has surface data even if the image does not. + * + * In case of a thin track drive, tracks are handled normally. + */ +void +d86f_construct_encoded_buffer(int drive, int side) +{ + d86f_t *dev = d86f[drive]; + uint32_t i = 0; + + /* *_fuzm are fuzzy bit masks, *_holm are hole masks, dst_neim are masks is mask for bits that are neither fuzzy nor holes in both, + and src1_d and src2_d are filtered source data. */ + uint16_t src1_fuzm, src2_fuzm, dst_fuzm, src1_holm, src2_holm, dst_holm, dst_neim, src1_d, src2_d; + uint32_t len; + uint16_t *dst = dev->track_encoded_data[side]; + uint16_t *dst_s = dev->track_surface_data[side]; + uint16_t *src1 = dev->thin_track_encoded_data[0][side]; + uint16_t *src1_s = dev->thin_track_surface_data[0][side]; + uint16_t *src2 = dev->thin_track_encoded_data[1][side]; + uint16_t *src2_s = dev->thin_track_surface_data[1][side]; + len = d86f_get_array_size(drive, side); + + for (i = 0; i < len; i++) { + /* The two bits differ. */ + if (d86f_has_surface_desc(drive)) { + /* Source image has surface description data, so we have some more handling to do. */ + src1_fuzm = src1[i] & src1_s[i]; + src2_fuzm = src2[i] & src2_s[i]; + dst_fuzm = src1_fuzm | src2_fuzm; /* The bits that remain set are fuzzy in either one or + the other or both. */ + src1_holm = src1[i] | (src1_s[i] ^ 0xffff); + src2_holm = src2[i] | (src2_s[i] ^ 0xffff); + dst_holm = (src1_holm & src2_holm) ^ 0xffff; /* The bits that remain set are holes in both. */ + dst_neim = (dst_fuzm | dst_holm) ^ 0xffff; /* The bits that remain set are those that are neither + fuzzy nor are holes in both. */ + src1_d = src1[i] & dst_neim; + src2_d = src2[i] & dst_neim; + + dst_s[i] = (dst_neim ^ 0xffff); /* The set bits are those that are either fuzzy or are + holes in both. */ + dst[i] = (src1_d | src2_d); /* Initial data is remaining data from Source 1 and + Source 2. */ + dst[i] |= dst_fuzm; /* Add to it the fuzzy bytes (holes have surface bit set + but data bit clear). */ + } else { + /* No surface data, the handling is much simpler - a simple OR. */ + dst[i] = src1[i] | src2[i]; + dst_s[i] = 0; + } + } +} + + /* Decomposition is easier since we at most have to care about the holes. */ -void d86f_decompose_encoded_buffer(int drive, int side) +void +d86f_decompose_encoded_buffer(int drive, int side) { - uint32_t i = 0; - uint16_t temp, temp2; - uint32_t len; - uint16_t *dst = d86f[drive].track_encoded_data[side]; - uint16_t *src1 = d86f[drive].thin_track_encoded_data[0][side]; - uint16_t *src1_s = d86f[drive].thin_track_surface_data[0][side]; - uint16_t *src2 = d86f[drive].thin_track_encoded_data[1][side]; - uint16_t *src2_s = d86f[drive].thin_track_surface_data[1][side]; - len = d86f_get_array_size(drive, side); + d86f_t *dev = d86f[drive]; + uint32_t i = 0; + uint16_t temp, temp2; + uint32_t len; + uint16_t *dst = dev->track_encoded_data[side]; + uint16_t *src1 = dev->thin_track_encoded_data[0][side]; + uint16_t *src1_s = dev->thin_track_surface_data[0][side]; + uint16_t *src2 = dev->thin_track_encoded_data[1][side]; + uint16_t *src2_s = dev->thin_track_surface_data[1][side]; + len = d86f_get_array_size(drive, side); - for (i = 0; i < len; i++) - { - if (d86f_has_surface_desc(drive)) - { - /* Source image has surface description data, so we have some more handling to do. - We need hole masks for both buffers. Holes have data bit clear and surface bit set. */ - temp = src1[i] & (src1_s[i] ^ 0xffff); - temp2 = src2[i] & (src2_s[i] ^ 0xffff); - src1[i] = dst[i] & temp; - src1_s[i] = temp ^ 0xffff; - src2[i] = dst[i] & temp2; - src2_s[i] = temp2 ^ 0xffff; - } - else - { - src1[i] = src2[i] = dst[i]; - } + for (i = 0; i < len; i++) { + if (d86f_has_surface_desc(drive)) { + /* Source image has surface description data, so we have some more handling to do. + We need hole masks for both buffers. Holes have data bit clear and surface bit set. */ + temp = src1[i] & (src1_s[i] ^ 0xffff); + temp2 = src2[i] & (src2_s[i] ^ 0xffff); + src1[i] = dst[i] & temp; + src1_s[i] = temp ^ 0xffff; + src2[i] = dst[i] & temp2; + src2_s[i] = temp2 ^ 0xffff; + } else { + src1[i] = src2[i] = dst[i]; } + } } -int d86f_track_header_size(int drive) + +int +d86f_track_header_size(int drive) { - int temp = 6; - if (d86f_has_extra_bit_cells(drive)) - { - temp += 4; - } - return temp; + int temp = 6; + + if (d86f_has_extra_bit_cells(drive)) + temp += 4; + + return temp; } -void d86f_read_track(int drive, int track, int thin_track, int side, uint16_t *da, uint16_t *sa) -{ - int logical_track = 0; - int array_size = 0; - if (d86f_get_sides(drive) == 2) - { - logical_track = ((track + thin_track) << 1) + side; - } +void +d86f_read_track(int drive, int track, int thin_track, int side, uint16_t *da, uint16_t *sa) +{ + d86f_t *dev = d86f[drive]; + int logical_track = 0; + int array_size = 0; + + if (d86f_get_sides(drive) == 2) + logical_track = ((track + thin_track) << 1) + side; else - { - logical_track = track + thin_track; - } + logical_track = track + thin_track; - if (d86f[drive].track_offset[logical_track]) - { - if (!thin_track) - { - fseek(d86f[drive].f, d86f[drive].track_offset[logical_track], SEEK_SET); - fread(&(d86f[drive].side_flags[side]), 2, 1, d86f[drive].f); - if (d86f_has_extra_bit_cells(drive)) - { - fread(&(d86f[drive].extra_bit_cells[side]), 4, 1, d86f[drive].f); - if (d86f[drive].extra_bit_cells[side] < -32768) - { - d86f[drive].extra_bit_cells[side] = -32768; - } - if (d86f[drive].extra_bit_cells[side] > 32768) - { - d86f[drive].extra_bit_cells[side] = 32768; - } - } - else - { - d86f[drive].extra_bit_cells[side] = 0; - } - fread(&(d86f[drive].index_hole_pos[side]), 4, 1, d86f[drive].f); + if (dev->track_offset[logical_track]) { + if (! thin_track) { + fseek(dev->f, dev->track_offset[logical_track], SEEK_SET); + fread(&(dev->side_flags[side]), 2, 1, dev->f); + if (d86f_has_extra_bit_cells(drive)) { + fread(&(dev->extra_bit_cells[side]), 4, 1, dev->f); + if (dev->extra_bit_cells[side] < -32768) + dev->extra_bit_cells[side] = -32768; + if (dev->extra_bit_cells[side] > 32768) + dev->extra_bit_cells[side] = 32768; + } else { + dev->extra_bit_cells[side] = 0; } - else - { - fseek(d86f[drive].f, d86f[drive].track_offset[logical_track] + d86f_track_header_size(drive), SEEK_SET); - } - array_size = d86f_get_array_size(drive, side) << 1; - if (d86f_has_surface_desc(drive)) - { - fread(sa, 1, array_size, d86f[drive].f); - } - fread(da, 1, array_size, d86f[drive].f); + fread(&(dev->index_hole_pos[side]), 4, 1, dev->f); + } else { + fseek(dev->f, dev->track_offset[logical_track] + d86f_track_header_size(drive), SEEK_SET); } - else - { - if (!thin_track) - { - switch((d86f[drive].disk_flags >> 1) & 3) - { - case 0: - default: - d86f[drive].side_flags[side] = 0x0A; - break; - case 1: - d86f[drive].side_flags[side] = 0x00; - break; - case 2: - case 3: - d86f[drive].side_flags[side] = 0x03; - break; - } - d86f[drive].extra_bit_cells[side] = 0; - } - } -} - -void d86f_zero_track(int drive) -{ - int sides, side; - sides = d86f_get_sides(drive); - - for (side = 0; side < sides; side++) - { - if (d86f_has_surface_desc(drive)) - { - memset(d86f[drive].track_surface_data[side], 0, 106096); - } - memset(d86f[drive].track_encoded_data[side], 0, 106096); - } -} - -void d86f_seek(int drive, int track) -{ - int sides; - int side, thin_track; - sides = d86f_get_sides(drive); - - /* If the drive has thick tracks, shift the track number by 1. */ - if (!fdd_doublestep_40(drive)) - { - track <<= 1; - - for (thin_track = 0; thin_track < sides; thin_track++) - { - for (side = 0; side < sides; side++) - { - if (d86f_has_surface_desc(drive)) - { - memset(d86f[drive].thin_track_surface_data[thin_track][side], 0, 106096); - } - memset(d86f[drive].thin_track_encoded_data[thin_track][side], 0, 106096); - } - } - } - - d86f_zero_track(drive); - - d86f[drive].cur_track = track; - - if (!fdd_doublestep_40(drive)) - { - for (side = 0; side < sides; side++) - { - for (thin_track = 0; thin_track < 2; thin_track++) - { - d86f_read_track(drive, track, thin_track, side, d86f[drive].thin_track_encoded_data[thin_track][side], d86f[drive].thin_track_surface_data[thin_track][side]); - } - - d86f_construct_encoded_buffer(drive, side); - } - } - else - { - for (side = 0; side < sides; side++) - { - d86f_read_track(drive, track, 0, side, d86f[drive].track_encoded_data[side], d86f[drive].track_surface_data[side]); - } - } - - d86f[drive].state = STATE_IDLE; -} - -void d86f_write_track(int drive, FILE **f, int side, uint16_t *da0, uint16_t *sa0) -{ - uint16_t side_flags = d86f_handler[drive].side_flags(drive); - uint32_t extra_bit_cells = d86f_handler[drive].extra_bit_cells(drive, side); - uint32_t index_hole_pos = d86f_handler[drive].index_hole_pos(drive, side); - - fwrite(&side_flags, 1, 2, *f); - - if (d86f_has_extra_bit_cells(drive)) - { - fwrite(&extra_bit_cells, 1, 4, *f); - } - - fwrite(&index_hole_pos, 1, 4, *f); - + array_size = d86f_get_array_size(drive, side) << 1; if (d86f_has_surface_desc(drive)) - { - fwrite(sa0, 1, d86f_get_array_size(drive, side) << 1, *f); + fread(sa, 1, array_size, dev->f); + fread(da, 1, array_size, dev->f); + } else { + if (! thin_track) { + switch((dev->disk_flags >> 1) & 3) { + case 0: + default: + dev->side_flags[side] = 0x0A; + break; + + case 1: + dev->side_flags[side] = 0x00; + break; + + case 2: + case 3: + dev->side_flags[side] = 0x03; + break; + } + dev->extra_bit_cells[side] = 0; } - - fwrite(da0, 1, d86f_get_array_size(drive, side) << 1, *f); + } } -int d86f_get_track_table_size(int drive) + +void +d86f_zero_track(int drive) { - int temp = 2048; + d86f_t *dev = d86f[drive]; + int sides, side; + sides = d86f_get_sides(drive); - if (d86f_get_sides(drive) == 1) - { - temp >>= 1; - } - - return temp; + for (side = 0; side < sides; side++) { + if (d86f_has_surface_desc(drive)) + memset(dev->track_surface_data[side], 0, 106096); + memset(dev->track_encoded_data[side], 0, 106096); + } } -void d86f_set_cur_track(int drive, int track) + +void +d86f_seek(int drive, int track) { - d86f[drive].cur_track = track; -} + d86f_t *dev = d86f[drive]; + int sides; + int side, thin_track; + sides = d86f_get_sides(drive); -void d86f_write_tracks(int drive, FILE **f, uint32_t *track_table) -{ - int sides; - int side, thin_track; - int logical_track = 0; - sides = d86f_get_sides(drive); - uint32_t *tbl = d86f[drive].track_offset; - if (track_table) - tbl = track_table; - int fdd_side = fdd_get_head(drive); + /* If the drive has thick tracks, shift the track number by 1. */ + if (! fdd_doublestep_40(drive)) { + track <<= 1; - if (!fdd_doublestep_40(drive)) - { - for (side = 0; side < sides; side++) - { - fdd_set_head(drive, side); - d86f_decompose_encoded_buffer(drive, side); - - for (thin_track = 0; thin_track < 2; thin_track++) - { - if (sides == 2) - { - logical_track = ((d86f[drive].cur_track + thin_track) << 1) + side; - } - else - { - logical_track = d86f[drive].cur_track + thin_track; - } - if (track_table && !tbl[logical_track]) - { - fseek(*f, 0, SEEK_END); - track_table[logical_track] = ftell(*f); - } - if (tbl[logical_track]) - { - fseek(*f, tbl[logical_track], SEEK_SET); - d86f_write_track(drive, f, side, d86f[drive].thin_track_encoded_data[thin_track][side], d86f[drive].thin_track_surface_data[thin_track][side]); - } - } + for (thin_track = 0; thin_track < sides; thin_track++) { + for (side = 0; side < sides; side++) { + if (d86f_has_surface_desc(drive)) + memset(dev->thin_track_surface_data[thin_track][side], 0, 106096); + memset(dev->thin_track_encoded_data[thin_track][side], 0, 106096); } } - else - { - for (side = 0; side < sides; side++) - { - fdd_set_head(drive, side); + } + + d86f_zero_track(drive); + + dev->cur_track = track; + + if (! fdd_doublestep_40(drive)) { + for (side = 0; side < sides; side++) { + for (thin_track = 0; thin_track < 2; thin_track++) + d86f_read_track(drive, track, thin_track, side, dev->thin_track_encoded_data[thin_track][side], dev->thin_track_surface_data[thin_track][side]); + + d86f_construct_encoded_buffer(drive, side); + } + } else { + for (side = 0; side < sides; side++) + d86f_read_track(drive, track, 0, side, dev->track_encoded_data[side], dev->track_surface_data[side]); + } + + dev->state = STATE_IDLE; +} + + +void +d86f_write_track(int drive, FILE **f, int side, uint16_t *da0, uint16_t *sa0) +{ + uint16_t side_flags = d86f_handler[drive].side_flags(drive); + uint32_t extra_bit_cells = d86f_handler[drive].extra_bit_cells(drive, side); + uint32_t index_hole_pos = d86f_handler[drive].index_hole_pos(drive, side); + + fwrite(&side_flags, 1, 2, *f); + + if (d86f_has_extra_bit_cells(drive)) + fwrite(&extra_bit_cells, 1, 4, *f); + + fwrite(&index_hole_pos, 1, 4, *f); + + if (d86f_has_surface_desc(drive)) + fwrite(sa0, 1, d86f_get_array_size(drive, side) << 1, *f); + + fwrite(da0, 1, d86f_get_array_size(drive, side) << 1, *f); +} + + +int +d86f_get_track_table_size(int drive) +{ + int temp = 2048; + + if (d86f_get_sides(drive) == 1) + temp >>= 1; + + return temp; +} + + +void +d86f_set_cur_track(int drive, int track) +{ + d86f_t *dev = d86f[drive]; + + dev->cur_track = track; +} + + +void +d86f_write_tracks(int drive, FILE **f, uint32_t *track_table) +{ + d86f_t *dev = d86f[drive]; + int sides; + int side, thin_track; + int logical_track = 0; + sides = d86f_get_sides(drive); + uint32_t *tbl = dev->track_offset; + int fdd_side = fdd_get_head(drive); + + if (track_table) + tbl = track_table; + + if (! fdd_doublestep_40(drive)) { + for (side = 0; side < sides; side++) { + fdd_set_head(drive, side); + d86f_decompose_encoded_buffer(drive, side); + + for (thin_track = 0; thin_track < 2; thin_track++) { if (sides == 2) - { - logical_track = (d86f[drive].cur_track << 1) + side; - } + logical_track = ((dev->cur_track + thin_track) << 1) + side; else - { - logical_track = d86f[drive].cur_track; - } - if (track_table && !tbl[logical_track]) - { + logical_track = dev->cur_track + thin_track; + + if (track_table && !tbl[logical_track]) { fseek(*f, 0, SEEK_END); track_table[logical_track] = ftell(*f); } - if (tbl[logical_track]) - { + if (tbl[logical_track]) { fseek(*f, tbl[logical_track], SEEK_SET); - d86f_write_track(drive, f, side, d86f[drive].track_encoded_data[side], d86f[drive].track_surface_data[side]); + d86f_write_track(drive, f, side, dev->thin_track_encoded_data[thin_track][side], dev->thin_track_surface_data[thin_track][side]); } } } + } else { + for (side = 0; side < sides; side++) { + fdd_set_head(drive, side); + if (sides == 2) + logical_track = (dev->cur_track << 1) + side; + else + logical_track = dev->cur_track; - fdd_set_head(drive, fdd_side); -} - -void d86f_writeback(int drive) -{ - uint8_t header[32]; - int header_size; - uint32_t len; - int ret = 0; - FILE *cf; - header_size = d86f_header_size(drive); - - if (!d86f[drive].f) - { - return; - } - - /* First write the track offsets table. */ - fseek(d86f[drive].f, 0, SEEK_SET); - fread(header, 1, header_size, d86f[drive].f); - - fseek(d86f[drive].f, 8, SEEK_SET); - fwrite(d86f[drive].track_offset, 1, d86f_get_track_table_size(drive), d86f[drive].f); - - d86f_write_tracks(drive, &d86f[drive].f, NULL); - - if (d86f[drive].is_compressed) - { - /* The image is compressed. */ - - /* Open the original, compressed file. */ - cf = plat_fopen(d86f[drive].original_file_name, L"wb"); - - /* Write the header to the original file. */ - fwrite(header, 1, header_size, cf); - - fseek(d86f[drive].f, 0, SEEK_END); - len = ftell(d86f[drive].f); - len -= header_size; - - fseek(d86f[drive].f, header_size, SEEK_SET); - - /* Compress data from the temporary uncompressed file to the original, compressed file. */ - d86f[drive].filebuf = (uint8_t *) malloc(len); - d86f[drive].outbuf = (uint8_t *) malloc(len - 1); - fread(d86f[drive].filebuf, 1, len, d86f[drive].f); - ret = lzf_compress(d86f[drive].filebuf, len, d86f[drive].outbuf, len - 1); - - if (!ret) - { - d86f_log("86F: Error compressing file\n"); + if (track_table && !tbl[logical_track]) { + fseek(*f, 0, SEEK_END); + track_table[logical_track] = ftell(*f); } - fwrite(d86f[drive].outbuf, 1, ret, cf); - free(d86f[drive].outbuf); - free(d86f[drive].filebuf); + if (tbl[logical_track]) { + fseek(*f, tbl[logical_track], SEEK_SET); + d86f_write_track(drive, f, side, dev->track_encoded_data[side], dev->track_surface_data[side]); + } } + } + + fdd_set_head(drive, fdd_side); } -void d86f_stop(int drive) + +void +d86f_writeback(int drive) { - d86f[drive].state = STATE_IDLE; + d86f_t *dev = d86f[drive]; + uint8_t header[32]; + int header_size; + uint32_t len; + int ret = 0; + FILE *cf; + header_size = d86f_header_size(drive); + + if (! dev->f) return; + + /* First write the track offsets table. */ + fseek(dev->f, 0, SEEK_SET); + fread(header, 1, header_size, dev->f); + + fseek(dev->f, 8, SEEK_SET); + fwrite(dev->track_offset, 1, d86f_get_track_table_size(drive), dev->f); + + d86f_write_tracks(drive, &dev->f, NULL); + + if (dev->is_compressed) { + /* The image is compressed. */ + + /* Open the original, compressed file. */ + cf = plat_fopen(dev->original_file_name, L"wb"); + + /* Write the header to the original file. */ + fwrite(header, 1, header_size, cf); + + fseek(dev->f, 0, SEEK_END); + len = ftell(dev->f); + len -= header_size; + + fseek(dev->f, header_size, SEEK_SET); + + /* Compress data from the temporary uncompressed file to the original, compressed file. */ + dev->filebuf = (uint8_t *) malloc(len); + dev->outbuf = (uint8_t *) malloc(len - 1); + fread(dev->filebuf, 1, len, dev->f); + ret = lzf_compress(dev->filebuf, len, dev->outbuf, len - 1); + + if (! ret) + d86f_log("86F: Error compressing file\n"); + + fwrite(dev->outbuf, 1, ret, cf); + free(dev->outbuf); + free(dev->filebuf); + } } -int d86f_common_command(int drive, int sector, int track, int side, int rate, int sector_size) + +void +d86f_stop(int drive) { - d86f_log("d86f_common_command (drive %i): fdc_period=%i img_period=%i rate=%i sector=%i track=%i side=%i\n", drive, fdc_get_bitcell_period(d86f_fdc), d86f_get_bitcell_period(drive), rate, sector, track, side); + d86f_t *dev = d86f[drive]; - d86f[drive].req_sector.id.c = track; - d86f[drive].req_sector.id.h = side; - if (sector == SECTOR_FIRST) - { - d86f[drive].req_sector.id.r = 1; - } - else if (sector == SECTOR_NEXT) - { - d86f[drive].req_sector.id.r++; - } - else - { - d86f[drive].req_sector.id.r = sector; - } - d86f[drive].req_sector.id.n = sector_size; - - if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1)) - { - fdc_noidam(d86f_fdc); - d86f[drive].state = STATE_IDLE; - d86f[drive].index_count = 0; - return 0; - } - - d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = 0; - d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0; - d86f[drive].index_count = d86f[drive].error_condition = d86f[drive].satisfying_bytes = 0; - d86f[drive].id_found = 0; - d86f[drive].dma_over = 0; - - return 1; + dev->state = STATE_IDLE; } -void d86f_readsector(int drive, int sector, int track, int side, int rate, int sector_size) + +int +d86f_common_command(int drive, int sector, int track, int side, int rate, int sector_size) { - int ret = 0; + d86f_t *dev = d86f[drive]; - ret = d86f_common_command(drive, sector, track, side, rate, sector_size); - if (!ret) return; + d86f_log("d86f_common_command (drive %i): fdc_period=%i img_period=%i rate=%i sector=%i track=%i side=%i\n", drive, fdc_get_bitcell_period(d86f_fdc), d86f_get_bitcell_period(drive), rate, sector, track, side); - if (sector == SECTOR_FIRST) - d86f[drive].state = STATE_02_SPIN_TO_INDEX; - else if (sector == SECTOR_NEXT) - d86f[drive].state = STATE_02_FIND_ID; - else - d86f[drive].state = fdc_is_deleted(d86f_fdc) ? STATE_0C_FIND_ID : (fdc_is_verify(d86f_fdc) ? STATE_16_FIND_ID : STATE_06_FIND_ID); + dev->req_sector.id.c = track; + dev->req_sector.id.h = side; + if (sector == SECTOR_FIRST) { + dev->req_sector.id.r = 1; + } else if (sector == SECTOR_NEXT) { + dev->req_sector.id.r++; + } else { + dev->req_sector.id.r = sector; + } + dev->req_sector.id.n = sector_size; + + if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1)) { + fdc_noidam(d86f_fdc); + dev->state = STATE_IDLE; + dev->index_count = 0; + return 0; + } + + dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = 0; + dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; + dev->index_count = dev->error_condition = dev->satisfying_bytes = 0; + dev->id_found = 0; + dev->dma_over = 0; + + return 1; } -void d86f_writesector(int drive, int sector, int track, int side, int rate, int sector_size) -{ - int ret = 0; - if (writeprot[drive]) - { - fdc_writeprotect(d86f_fdc); - d86f[drive].state = STATE_IDLE; - d86f[drive].index_count = 0; +void +d86f_readsector(int drive, int sector, int track, int side, int rate, int sector_size) +{ + d86f_t *dev = d86f[drive]; + int ret = 0; + + ret = d86f_common_command(drive, sector, track, side, rate, sector_size); + if (! ret) return; + + if (sector == SECTOR_FIRST) + dev->state = STATE_02_SPIN_TO_INDEX; + else if (sector == SECTOR_NEXT) + dev->state = STATE_02_FIND_ID; + else + dev->state = fdc_is_deleted(d86f_fdc) ? STATE_0C_FIND_ID : (fdc_is_verify(d86f_fdc) ? STATE_16_FIND_ID : STATE_06_FIND_ID); +} + + +void +d86f_writesector(int drive, int sector, int track, int side, int rate, int sector_size) +{ + d86f_t *dev = d86f[drive]; + int ret = 0; + + if (writeprot[drive]) { + fdc_writeprotect(d86f_fdc); + dev->state = STATE_IDLE; + dev->index_count = 0; + return; + } + + ret = d86f_common_command(drive, sector, track, side, rate, sector_size); + if (! ret) return; + + dev->state = fdc_is_deleted(d86f_fdc) ? STATE_09_FIND_ID : STATE_05_FIND_ID; +} + + +void +d86f_comparesector(int drive, int sector, int track, int side, int rate, int sector_size) +{ + d86f_t *dev = d86f[drive]; + int ret = 0; + + ret = d86f_common_command(drive, sector, track, side, rate, sector_size); + if (! ret) return; + + dev->state = STATE_11_FIND_ID; +} + + +void +d86f_readaddress(int drive, int side, int rate) +{ + d86f_t *dev = d86f[drive]; + + if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1)) { + fdc_noidam(d86f_fdc); + dev->state = STATE_IDLE; + dev->index_count = 0; + return; + } + + dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = 0; + dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; + dev->index_count = dev->error_condition = dev->satisfying_bytes = 0; + dev->id_found = 0; + dev->dma_over = 0; + + dev->state = STATE_0A_FIND_ID; +} + + +void +d86f_add_track(int drive, int track, int side) +{ + d86f_t *dev = d86f[drive]; + uint32_t array_size; + int logical_track; + + array_size = d86f_get_array_size(drive, side); + array_size <<= 1; + + if (d86f_get_sides(drive) == 2) { + logical_track = (track << 1) + side; + } else { + if (side) return; - } + logical_track = track; + } - ret = d86f_common_command(drive, sector, track, side, rate, sector_size); - if (!ret) return; + if (! dev->track_offset[logical_track]) { + /* Track is absent from the file, let's add it. */ + dev->track_offset[logical_track] = dev->file_size; - d86f[drive].state = fdc_is_deleted(d86f_fdc) ? STATE_09_FIND_ID : STATE_05_FIND_ID; + dev->file_size += (array_size + 6); + if (d86f_has_extra_bit_cells(drive)) + dev->file_size += 4; + if (d86f_has_surface_desc(drive)) + dev->file_size += array_size; + } } -void d86f_comparesector(int drive, int sector, int track, int side, int rate, int sector_size) + +void +d86f_common_format(int drive, int side, int rate, uint8_t fill, int proxy) { - int ret = 0; + d86f_t *dev = d86f[drive]; + uint32_t i = 0; + uint16_t temp, temp2; + uint32_t array_size; - ret = d86f_common_command(drive, sector, track, side, rate, sector_size); - if (!ret) return; + if (writeprot[drive]) { + fdc_writeprotect(d86f_fdc); + dev->state = STATE_IDLE; + dev->index_count = 0; + return; + } - d86f[drive].state = STATE_11_FIND_ID; -} + if (! d86f_can_format(drive)) { + fdc_cannotformat(d86f_fdc); + dev->state = STATE_IDLE; + dev->index_count = 0; + return; + } -void d86f_readaddress(int drive, int side, int rate) -{ - if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1)) - { - fdc_noidam(d86f_fdc); - d86f[drive].state = STATE_IDLE; - d86f[drive].index_count = 0; - return; - } + if (!side || (d86f_get_sides(drive) == 2)) { + if (! proxy) { + d86f_reset_index_hole_pos(drive, side); - d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = 0; - d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0; - d86f[drive].index_count = d86f[drive].error_condition = d86f[drive].satisfying_bytes = 0; - d86f[drive].id_found = 0; - d86f[drive].dma_over = 0; - - d86f[drive].state = STATE_0A_FIND_ID; -} - -void d86f_add_track(int drive, int track, int side) -{ - uint32_t array_size; - int logical_track = 0; - - array_size = d86f_get_array_size(drive, side); - array_size <<= 1; - - if (d86f_get_sides(drive) == 2) - { - logical_track = (track << 1) + side; - } - else - { - if (side) - { + if (dev->cur_track > 256) { + fdc_writeprotect(d86f_fdc); + dev->state = STATE_IDLE; + dev->index_count = 0; return; } - logical_track = track; - } - if (!d86f[drive].track_offset[logical_track]) - { - /* Track is absent from the file, let's add it. */ - d86f[drive].track_offset[logical_track] = d86f[drive].file_size; + array_size = d86f_get_array_size(drive, side); - d86f[drive].file_size += (array_size + 6); - if (d86f_has_extra_bit_cells(drive)) - { - d86f[drive].file_size += 4; - } - if (d86f_has_surface_desc(drive)) - { - d86f[drive].file_size += array_size; + if (d86f_has_surface_desc(drive)) { + /* Preserve the physical holes but get rid of the fuzzy bytes. */ + for (i = 0; i < array_size; i++) { + temp = dev->track_encoded_data[side][i] ^ 0xffff; + temp2 = dev->track_surface_data[side][i]; + temp &= temp2; + dev->track_surface_data[side][i] = temp; + } } + + /* Zero the data buffer. */ + memset(dev->track_encoded_data[side], 0, array_size << 1); + + d86f_add_track(drive, dev->cur_track, side); + if (! fdd_doublestep_40(drive)) + d86f_add_track(drive, dev->cur_track + 1, side); } + } + + dev->fill = fill; + + if (! proxy) { + dev->side_flags[side] = 0; + dev->side_flags[side] |= (fdd_getrpm(real_drive(d86f_fdc, drive)) == 360) ? 0x20 : 0; + dev->side_flags[side] |= fdc_get_bit_rate(d86f_fdc); + dev->side_flags[side] |= fdc_is_mfm(d86f_fdc) ? 8 : 0; + + dev->index_hole_pos[side] = 0; + } + + dev->id_find.sync_marks = dev->id_find.bits_obtained = dev->id_find.bytes_obtained = 0; + dev->data_find.sync_marks = dev->data_find.bits_obtained = dev->data_find.bytes_obtained = 0; + dev->index_count = dev->error_condition = dev->satisfying_bytes = dev->sector_count = 0; + dev->dma_over = 0; + + if (!side || (d86f_get_sides(drive) == 2)) + dev->state = STATE_0D_SPIN_TO_INDEX; + else + dev->state = STATE_0D_NOP_SPIN_TO_INDEX; } -void d86f_common_format(int drive, int side, int rate, uint8_t fill, int proxy) + +void +d86f_proxy_format(int drive, int side, int rate, uint8_t fill) { - uint32_t i = 0; - uint16_t temp, temp2; - uint32_t array_size; + d86f_common_format(drive, side, rate, fill, 1); +} - if (writeprot[drive]) - { - fdc_writeprotect(d86f_fdc); - d86f[drive].state = STATE_IDLE; - d86f[drive].index_count = 0; - return; - } - if (!(d86f_can_format(drive))) - { - fdc_cannotformat(d86f_fdc); - d86f[drive].state = STATE_IDLE; - d86f[drive].index_count = 0; - return; - } +void +d86f_format(int drive, int side, int rate, uint8_t fill) +{ + d86f_common_format(drive, side, rate, fill, 0); +} - if (!side || (d86f_get_sides(drive) == 2)) - { - if (!proxy) - { - d86f_reset_index_hole_pos(drive, side); - if (d86f[drive].cur_track > 256) - { - fdc_writeprotect(d86f_fdc); - d86f[drive].state = STATE_IDLE; - d86f[drive].index_count = 0; - return; - } +void +d86f_common_handlers(int drive) +{ + drives[drive].readsector = d86f_readsector; + drives[drive].writesector = d86f_writesector; + drives[drive].comparesector =d86f_comparesector; + drives[drive].readaddress = d86f_readaddress; + drives[drive].byteperiod = d86f_byteperiod; + drives[drive].poll = d86f_poll; + drives[drive].format = d86f_proxy_format; + drives[drive].stop = d86f_stop; +} - array_size = d86f_get_array_size(drive, side); - if (d86f_has_surface_desc(drive)) - { - /* Preserve the physical holes but get rid of the fuzzy bytes. */ - for (i = 0; i < array_size; i++) - { - temp = d86f[drive].track_encoded_data[side][i] ^ 0xffff; - temp2 = d86f[drive].track_surface_data[side][i]; - temp &= temp2; - d86f[drive].track_surface_data[side][i] = temp; - } - } - /* Zero the data buffer. */ - memset(d86f[drive].track_encoded_data[side], 0, array_size << 1); +int +d86f_export(int drive, wchar_t *fn) +{ + uint32_t tt[512]; + d86f_t *dev = d86f[drive]; + d86f_t *temp86; + FILE *f; + int tracks = 86; + int i; + int inc = 1; + uint32_t magic = 0x46423638; + uint16_t version = 0x020B; + uint16_t disk_flags = d86f_handler[drive].disk_flags(drive); - d86f_add_track(drive, d86f[drive].cur_track, side); - if (!fdd_doublestep_40(drive)) - { - d86f_add_track(drive, d86f[drive].cur_track + 1, side); - } - } - } + memset(tt, 0, 512 * sizeof(uint32_t)); - d86f[drive].fill = fill; + f = plat_fopen(fn, L"wb"); + if (!f) + return 0; - if (!proxy) - { - d86f[drive].side_flags[side] = 0; - d86f[drive].side_flags[side] |= (fdd_getrpm(real_drive(d86f_fdc, drive)) == 360) ? 0x20 : 0; - d86f[drive].side_flags[side] |= fdc_get_bit_rate(d86f_fdc); - d86f[drive].side_flags[side] |= fdc_is_mfm(d86f_fdc) ? 8 : 0; + /* Allocate a temporary drive for conversion. */ + temp86 = (d86f_t *)malloc(sizeof(d86f_t)); + memcpy(temp86, dev, sizeof(d86f_t)); - d86f[drive].index_hole_pos[side] = 0; - } + fwrite(&magic, 4, 1, f); + fwrite(&version, 2, 1, f); + fwrite(&disk_flags, 2, 1, f); - d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = 0; - d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0; - d86f[drive].index_count = d86f[drive].error_condition = d86f[drive].satisfying_bytes = d86f[drive].sector_count = 0; - d86f[drive].dma_over = 0; + fwrite(tt, 1, ((d86f_get_sides(drive) == 2) ? 2048 : 1024), f); - if (!side || (d86f_get_sides(drive) == 2)) - { - d86f[drive].state = STATE_0D_SPIN_TO_INDEX; - } + /* In the case of a thick track drive, always increment track + by two, since two tracks are going to get output at once. */ + if (!fdd_doublestep_40(drive)) + inc = 2; + + for (i = 0; i < tracks; i += inc) { + if (inc == 2) + fdd_do_seek(drive, i >> 1); else - { - d86f[drive].state = STATE_0D_NOP_SPIN_TO_INDEX; - } + fdd_do_seek(drive, i); + dev->cur_track = i; + d86f_write_tracks(drive, &f, tt); + } + + fclose(f); + + f = plat_fopen(fn, L"rb+"); + + fseek(f, 8, SEEK_SET); + fwrite(tt, 1, ((d86f_get_sides(drive) == 2) ? 2048 : 1024), f); + + fclose(f); + + fdd_do_seek(drive, fdd_current_track(drive)); + + /* Restore the drive from temp. */ + memcpy(dev, temp86, sizeof(d86f_t)); + free(temp86); + + return 1; } -void d86f_proxy_format(int drive, int side, int rate, uint8_t fill) + +void +d86f_load(int drive, wchar_t *fn) { - d86f_common_format(drive, side, rate, fill, 1); -} + wchar_t temp_file_name[2048]; + d86f_t *dev = d86f[drive]; + uint32_t magic = 0; + uint32_t len = 0; + uint16_t temp = 0; + int i = 0; + FILE *tf; -void d86f_format(int drive, int side, int rate, uint8_t fill) -{ - d86f_common_format(drive, side, rate, fill, 0); -} + d86f_unregister(drive); -void d86f_common_handlers(int drive) -{ - drives[drive].readsector = d86f_readsector; - drives[drive].writesector = d86f_writesector; - drives[drive].comparesector=d86f_comparesector; - drives[drive].readaddress = d86f_readaddress; - drives[drive].byteperiod = d86f_byteperiod; - drives[drive].poll = d86f_poll; - drives[drive].format = d86f_proxy_format; - drives[drive].stop = d86f_stop; -} + writeprot[drive] = 0; -int d86f_export(int drive, wchar_t *fn) -{ - FILE *f; - uint32_t tt[512]; - - int tracks = 86; - int i; - int inc = 1; - - uint32_t magic = 0x46423638; - uint16_t version = 0x020B; - - uint16_t disk_flags = d86f_handler[drive].disk_flags(drive); - - uint32_t struct_size = sizeof(d86f) / (FDD_NUM + 1); - - memset(tt, 0, 512 * sizeof(uint32_t)); - - memcpy(&(d86f[4]), &(d86f[drive]), struct_size); - - f = plat_fopen(fn, L"wb"); - if (!f) - return 0; - - fwrite(&magic, 4, 1, f); - fwrite(&version, 2, 1, f); - fwrite(&disk_flags, 2, 1, f); - - fwrite(tt, 1, ((d86f_get_sides(drive) == 2) ? 2048 : 1024), f); - - /* In the case of a thick track drive, always increment track - by two, since two tracks are going to get output at once. */ - if (!fdd_doublestep_40(drive)) - inc = 2; - - for (i = 0; i < tracks; i += inc) { - if (inc == 2) - fdd_do_seek(drive, i >> 1); - else - fdd_do_seek(drive, i); - d86f[drive].cur_track = i; - d86f_write_tracks(drive, &f, tt); - } - - fclose(f); - - f = plat_fopen(fn, L"rb+"); - - fseek(f, 8, SEEK_SET); - fwrite(tt, 1, ((d86f_get_sides(drive) == 2) ? 2048 : 1024), f); - - fclose(f); - - fdd_do_seek(drive, fdd_current_track(drive)); - - memcpy(&(d86f[drive]), &(d86f[4]), struct_size); - - return 1; -} - -void d86f_load(int drive, wchar_t *fn) -{ - uint32_t magic = 0; - uint32_t len = 0; - wchar_t temp_file_name[2048]; - uint16_t temp = 0; - int i = 0; - FILE *tf; - - d86f_unregister(drive); - - writeprot[drive] = 0; - d86f[drive].f = plat_fopen(fn, L"rb+"); - if (!d86f[drive].f) - { - d86f[drive].f = plat_fopen(fn, L"rb"); - if (!d86f[drive].f) - { - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - writeprot[drive] = 1; - } - if (ui_writeprot[drive]) - { - writeprot[drive] = 1; - } - fwriteprot[drive] = writeprot[drive]; - - fseek(d86f[drive].f, 0, SEEK_END); - len = ftell(d86f[drive].f); - fseek(d86f[drive].f, 0, SEEK_SET); - - fread(&magic, 4, 1, d86f[drive].f); - - if (len < 16) - { - /* File is WAY too small, abort. */ - fclose(d86f[drive].f); - d86f[drive].f = NULL; + dev->f = plat_fopen(fn, L"rb+"); + if (! dev->f) { + dev->f = plat_fopen(fn, L"rb"); + if (! dev->f) { memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + free(dev); return; } + writeprot[drive] = 1; + } - if ((magic != 0x46423638) && (magic != 0x66623638)) - { - /* File is not of the valid format, abort. */ - d86f_log("86F: Unrecognized magic bytes: %08X\n", magic); - fclose(d86f[drive].f); - d86f[drive].f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; + if (ui_writeprot[drive]) { + writeprot[drive] = 1; + } + fwriteprot[drive] = writeprot[drive]; + + fseek(dev->f, 0, SEEK_END); + len = ftell(dev->f); + fseek(dev->f, 0, SEEK_SET); + + fread(&magic, 4, 1, dev->f); + + if (len < 16) { + /* File is WAY too small, abort. */ + fclose(dev->f); + dev->f = NULL; + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + free(dev); + return; + } + + if ((magic != 0x46423638) && (magic != 0x66623638)) { + /* File is not of the valid format, abort. */ + d86f_log("86F: Unrecognized magic bytes: %08X\n", magic); + fclose(dev->f); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + free(dev); + return; + } + + fread(&(dev->version), 2, 1, dev->f); + if (dev->version != D86FVER) { + /* File is not of a recognized format version, abort. */ + if (dev->version == 0x0063) { + d86f_log("86F: File has emulator-internal version 0.99, this version is not valid in a file\n"); + } else if ((dev->version >= 0x0100) && (dev->version < D86FVER)) { + d86f_log("86F: No longer supported development file version: %i.%02i\n", dev->version >> 8, dev->version & 0xff); + } else { + d86f_log("86F: Unrecognized file version: %i.%02i\n", dev->version >> 8, dev->version & 0xff); } + fclose(dev->f); + dev->f = NULL; + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + free(dev); + return; + } else { + d86f_log("86F: Recognized file version: %i.%02i\n", dev->version >> 8, dev->version & 0xff); + } - fread(&(d86f[drive].version), 2, 1, d86f[drive].f); - - if (d86f[drive].version != D86FVER) - { - /* File is not of a recognized format version, abort. */ - if (d86f[drive].version == 0x0063) - { - d86f_log("86F: File has emulator-internal version 0.99, this version is not valid in a file\n"); - } - else if ((d86f[drive].version >= 0x0100) && (d86f[drive].version < D86FVER)) - { - d86f_log("86F: No longer supported development file version: %i.%02i\n", d86f[drive].version >> 8, d86f[drive].version & 0xFF); - } - else - { - d86f_log("86F: Unrecognized file version: %i.%02i\n", d86f[drive].version >> 8, d86f[drive].version & 0xFF); - } - fclose(d86f[drive].f); - d86f[drive].f = NULL; - ui_sb_update_icon_state(drive, 1); - return; - } - else - { - d86f_log("86F: Recognized file version: %i.%02i\n", d86f[drive].version >> 8, d86f[drive].version & 0xFF); - } - - fread(&(d86f[drive].disk_flags), 2, 1, d86f[drive].f); - - d86f[drive].is_compressed = (magic == 0x66623638) ? 1 : 0; - - if ((len < 51052) && !d86f[drive].is_compressed) - { - /* File too small, abort. */ - fclose(d86f[drive].f); - d86f[drive].f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } + fread(&(dev->disk_flags), 2, 1, dev->f); + dev->is_compressed = (magic == 0x66623638) ? 1 : 0; + if ((len < 51052) && !dev->is_compressed) { + /* File too small, abort. */ + fclose(dev->f); + dev->f = NULL; + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + free(dev); + return; + } #ifdef DO_CRC64 - fseek(d86f[drive].f, 8, SEEK_SET); - fread(&read_crc64, 1, 8, d86f[drive].f); + fseek(dev->f, 8, SEEK_SET); + fread(&read_crc64, 1, 8, dev->f); - fseek(d86f[drive].f, 0, SEEK_SET); + fseek(dev->f, 0, SEEK_SET); - crc64 = 0xffffffffffffffff; + crc64 = 0xffffffffffffffff; - d86f[drive].filebuf = malloc(len); - fread(d86f[drive].filebuf, 1, len, d86f[drive].f); - *(uint64_t *) &(d86f[drive].filebuf[8]) = 0xffffffffffffffff; - crc64 = (uint64_t) crc64speed(0, d86f[drive].filebuf, len); - free(d86f[drive].filebuf); + dev->filebuf = malloc(len); + fread(dev->filebuf, 1, len, dev->f); + *(uint64_t *) &(dev->filebuf[8]) = 0xffffffffffffffff; + crc64 = (uint64_t) crc64speed(0, dev->filebuf, len); + free(dev->filebuf); - if (crc64 != read_crc64) - { - d86f_log("86F: CRC64 error\n"); - fclose(d86f[drive].f); - d86f[drive].f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } + if (crc64 != read_crc64) { + d86f_log("86F: CRC64 error\n"); + fclose(dev->f); + dev->f = NULL; + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + free(dev); + return; + } #endif - if (d86f[drive].is_compressed) - { - memcpy(temp_file_name, drive ? nvr_path(L"TEMP$$$1.$$$") : nvr_path(L"TEMP$$$0.$$$"), 256); - memcpy(d86f[drive].original_file_name, fn, (wcslen(fn) << 1) + 2); + if (dev->is_compressed) { + memcpy(temp_file_name, drive ? nvr_path(L"TEMP$$$1.$$$") : nvr_path(L"TEMP$$$0.$$$"), 256); + memcpy(dev->original_file_name, fn, (wcslen(fn) << 1) + 2); - fclose(d86f[drive].f); - d86f[drive].f = NULL; + fclose(dev->f); + dev->f = NULL; - d86f[drive].f = plat_fopen(temp_file_name, L"wb"); - if (!d86f[drive].f) - { - d86f_log("86F: Unable to create temporary decompressed file\n"); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - - tf = plat_fopen(fn, L"rb"); - - for (i = 0; i < 8; i++) - { - fread(&temp, 1, 2, tf); - fwrite(&temp, 1, 2, d86f[drive].f); - } - - d86f[drive].filebuf = (uint8_t *) malloc(len); - d86f[drive].outbuf = (uint8_t *) malloc(67108864); - fread(d86f[drive].filebuf, 1, len, tf); - temp = lzf_decompress(d86f[drive].filebuf, len, d86f[drive].outbuf, 67108864); - if (temp) - { - fwrite(d86f[drive].outbuf, 1, temp, d86f[drive].f); - } - free(d86f[drive].outbuf); - free(d86f[drive].filebuf); - - fclose(tf); - fclose(d86f[drive].f); - d86f[drive].f = NULL; - - if (!temp) - { - d86f_log("86F: Error decompressing file\n"); - plat_remove(temp_file_name); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - - d86f[drive].f = plat_fopen(temp_file_name, L"rb+"); - } - - if (d86f[drive].disk_flags & 0x100) - { - /* Zoned disk. */ - d86f_log("86F: Disk is zoned (Apple or Sony)\n"); - fclose(d86f[drive].f); - d86f[drive].f = NULL; - if (d86f[drive].is_compressed) - { - plat_remove(temp_file_name); - } + dev->f = plat_fopen(temp_file_name, L"wb"); + if (! dev->f) { + d86f_log("86F: Unable to create temporary decompressed file\n"); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + free(dev); return; } - if (d86f[drive].disk_flags & 0x600) - { - /* Zone type is not 0 but the disk is fixed-RPM. */ - d86f_log("86F: Disk is fixed-RPM but zone type is not 0\n"); - fclose(d86f[drive].f); - d86f[drive].f = NULL; - if (d86f[drive].is_compressed) - { - plat_remove(temp_file_name); - } + tf = plat_fopen(fn, L"rb"); + + for (i = 0; i < 8; i++) { + fread(&temp, 1, 2, tf); + fwrite(&temp, 1, 2, dev->f); + } + + dev->filebuf = (uint8_t *) malloc(len); + dev->outbuf = (uint8_t *) malloc(67108864); + fread(dev->filebuf, 1, len, tf); + temp = lzf_decompress(dev->filebuf, len, dev->outbuf, 67108864); + if (temp) { + fwrite(dev->outbuf, 1, temp, dev->f); + } + free(dev->outbuf); + free(dev->filebuf); + + fclose(tf); + fclose(dev->f); + dev->f = NULL; + + if (! temp) { + d86f_log("86F: Error decompressing file\n"); + plat_remove(temp_file_name); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + free(dev); return; } - if (!writeprot[drive]) - { - writeprot[drive] = (d86f[drive].disk_flags & 0x10) ? 1 : 0; - fwriteprot[drive] = writeprot[drive]; + dev->f = plat_fopen(temp_file_name, L"rb+"); + } + + if (dev->disk_flags & 0x100) { + /* Zoned disk. */ + d86f_log("86F: Disk is zoned (Apple or Sony)\n"); + fclose(dev->f); + dev->f = NULL; + if (dev->is_compressed) { + plat_remove(temp_file_name); + } + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + free(dev); + return; + } + + if (dev->disk_flags & 0x600) { + /* Zone type is not 0 but the disk is fixed-RPM. */ + d86f_log("86F: Disk is fixed-RPM but zone type is not 0\n"); + fclose(dev->f); + dev->f = NULL; + if (dev->is_compressed) + plat_remove(temp_file_name); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + free(dev); + return; + } + + if (!writeprot[drive]) { + writeprot[drive] = (dev->disk_flags & 0x10) ? 1 : 0; + fwriteprot[drive] = writeprot[drive]; + } + + if (writeprot[drive]) { + fclose(dev->f); + dev->f = NULL; + + if (dev->is_compressed) + dev->f = plat_fopen(temp_file_name, L"rb"); + else + dev->f = plat_fopen(fn, L"rb"); + } + + /* OK, set the drive data, other code needs it. */ + d86f[drive] = dev; + + fseek(dev->f, 8, SEEK_SET); + + fread(dev->track_offset, 1, d86f_get_track_table_size(drive), dev->f); + + if (! (dev->track_offset[0])) { + /* File has no track 0 side 0, abort. */ + d86f_log("86F: No Track 0 side 0\n"); + fclose(dev->f); + dev->f = NULL; + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + free(dev); + d86f[drive] = NULL; + return; + } + + if ((d86f_get_sides(drive) == 2) && !(dev->track_offset[1])) { + /* File is 2-sided but has no track 0 side 1, abort. */ + d86f_log("86F: No Track 0 side 1\n"); + fclose(dev->f); + dev->f = NULL; + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + free(dev); + d86f[drive] = NULL; + return; + } + + /* Load track 0 flags as default. */ + fseek(dev->f, dev->track_offset[0], SEEK_SET); + fread(&(dev->side_flags[0]), 2, 1, dev->f); + if (dev->disk_flags & 0x80) { + fread(&(dev->extra_bit_cells[0]), 4, 1, dev->f); + if (dev->extra_bit_cells[0] < -32768) dev->extra_bit_cells[0] = -32768; + if (dev->extra_bit_cells[0] > 32768) dev->extra_bit_cells[0] = 32768; + } else { + dev->extra_bit_cells[0] = 0; + } + + if (d86f_get_sides(drive) == 2) { + fseek(dev->f, dev->track_offset[1], SEEK_SET); + fread(&(dev->side_flags[1]), 2, 1, dev->f); + if (dev->disk_flags & 0x80) { + fread(&(dev->extra_bit_cells[1]), 4, 1, dev->f); + if (dev->extra_bit_cells[1] < -32768) dev->extra_bit_cells[1] = -32768; + if (dev->extra_bit_cells[1] > 32768) dev->extra_bit_cells[1] = 32768; + } else { + dev->extra_bit_cells[0] = 0; + } + } else { + switch ((dev->disk_flags >> 1) >> 3) { + case 0: + default: + dev->side_flags[1] = 0x0a; + break; + + case 1: + dev->side_flags[1] = 0x00; + break; + + case 2: + case 3: + dev->side_flags[1] = 0x03; + break; } - if (writeprot[drive]) - { - fclose(d86f[drive].f); - d86f[drive].f = NULL; + dev->extra_bit_cells[1] = 0; + } - if (d86f[drive].is_compressed) - { - d86f[drive].f = plat_fopen(temp_file_name, L"rb"); - } - else - { - d86f[drive].f = plat_fopen(fn, L"rb"); - } - } + fseek(dev->f, 0, SEEK_END); + dev->file_size = ftell(dev->f); - fseek(d86f[drive].f, 8, SEEK_SET); + fseek(dev->f, 0, SEEK_SET); - fread(d86f[drive].track_offset, 1, d86f_get_track_table_size(drive), d86f[drive].f); + d86f_register_86f(drive); - if (!(d86f[drive].track_offset[0])) - { - /* File has no track 0 side 0, abort. */ - d86f_log("86F: No Track 0 side 0\n"); - fclose(d86f[drive].f); - d86f[drive].f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } + drives[drive].seek = d86f_seek; + d86f_common_handlers(drive); + drives[drive].format = d86f_format; - if ((d86f_get_sides(drive) == 2) && !(d86f[drive].track_offset[1])) - { - /* File is 2-sided but has no track 0 side 1, abort. */ - d86f_log("86F: No Track 0 side 1\n"); - fclose(d86f[drive].f); - d86f[drive].f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - - /* Load track 0 flags as default. */ - fseek(d86f[drive].f, d86f[drive].track_offset[0], SEEK_SET); - fread(&(d86f[drive].side_flags[0]), 2, 1, d86f[drive].f); - if (d86f[drive].disk_flags & 0x80) - { - fread(&(d86f[drive].extra_bit_cells[0]), 4, 1, d86f[drive].f); - if (d86f[drive].extra_bit_cells[0] < -32768) d86f[drive].extra_bit_cells[0] = -32768; - if (d86f[drive].extra_bit_cells[0] > 32768) d86f[drive].extra_bit_cells[0] = 32768; - } - else - { - d86f[drive].extra_bit_cells[0] = 0; - } - - if (d86f_get_sides(drive) == 2) - { - fseek(d86f[drive].f, d86f[drive].track_offset[1], SEEK_SET); - fread(&(d86f[drive].side_flags[1]), 2, 1, d86f[drive].f); - if (d86f[drive].disk_flags & 0x80) - { - fread(&(d86f[drive].extra_bit_cells[1]), 4, 1, d86f[drive].f); - if (d86f[drive].extra_bit_cells[1] < -32768) d86f[drive].extra_bit_cells[1] = -32768; - if (d86f[drive].extra_bit_cells[1] > 32768) d86f[drive].extra_bit_cells[1] = 32768; - } - else - { - d86f[drive].extra_bit_cells[0] = 0; - } - } - else - { - switch ((d86f[drive].disk_flags >> 1) >> 3) - { - case 0: - default: - d86f[drive].side_flags[1] = 0x0A; - break; - case 1: - d86f[drive].side_flags[1] = 0x00; - break; - case 2: - case 3: - d86f[drive].side_flags[1] = 0x03; - break; - } - d86f[drive].extra_bit_cells[1] = 0; - } - - fseek(d86f[drive].f, 0, SEEK_END); - d86f[drive].file_size = ftell(d86f[drive].f); - - fseek(d86f[drive].f, 0, SEEK_SET); - - d86f_register_86f(drive); - - drives[drive].seek = d86f_seek; - d86f_common_handlers(drive); - drives[drive].format = d86f_format; - - d86f_log("86F: Disk is %scompressed and %s surface description data\n", d86f[drive].is_compressed ? "" : "not ", d86f_has_surface_desc(drive) ? "has" : "does not have"); + d86f_log("86F: Disk is %scompressed and does%s have surface description data\n", + dev->is_compressed ? "" : "not ", + d86f_has_surface_desc(drive) ? "" : " not"); } -void d86f_init(void) + +void +d86f_init(void) { - int i; + int i; - memset(d86f, 0, sizeof(d86f)); - d86f_setupcrc(0x1021); + setup_crc(0x1021); - for (i = 0; i < (FDD_NUM + 1); i++) - { - d86f[i].state = STATE_IDLE; - d86f_initialize_linked_lists(i); - } + for (i = 0; i < FDD_NUM; i++) + d86f[i] = NULL; } -void d86f_set_fdc(void *fdc) + +void +d86f_set_fdc(void *fdc) { - d86f_fdc = (fdc_t *) fdc; + d86f_fdc = (fdc_t *) fdc; } -void d86f_close(int drive) + +void +d86f_close(int drive) { - wchar_t temp_file_name[2048]; + wchar_t temp_file_name[2048]; + d86f_t *dev = d86f[drive]; - memcpy(temp_file_name, drive ? nvr_path(L"TEMP$$$1.$$$") : nvr_path(L"TEMP$$$0.$$$"), 26); + /* Make sure the drive is alive. */ + if (dev == NULL) return; - if (d86f[drive].f) - { - fclose(d86f[drive].f); - d86f[drive].f = NULL; - } - if (d86f[drive].is_compressed) - plat_remove(temp_file_name); + memcpy(temp_file_name, drive ? nvr_path(L"TEMP$$$1.$$$") : nvr_path(L"TEMP$$$0.$$$"), 26); + + if (dev->f) { + fclose(dev->f); + dev->f = NULL; + } + if (dev->is_compressed) + plat_remove(temp_file_name); +} + + +/* When an FDD is mounted, set up the D86F data structures. */ +void +d86f_setup(int drive) +{ + d86f_t *dev; + + /* Allocate a drive structure. */ + dev = (d86f_t *)malloc(sizeof(d86f_t)); + memset(dev, 0x00, sizeof(d86f_t)); + dev->state = STATE_IDLE; + + dev->last_side_sector[0] = NULL; + dev->last_side_sector[1] = NULL; + + /* Set the drive as active. */ + d86f[drive] = dev; +} + + +/* If an FDD is unmounted, unlink the D86F data structures. */ +void +d86f_destroy(int drive) +{ + d86f_t *dev = d86f[drive]; + + if (dev == NULL) return; + + d86f_destroy_linked_lists(drive, 0); + d86f_destroy_linked_lists(drive, 1); + + free(d86f[drive]); + d86f[drive] = NULL; } diff --git a/src/floppy/fdd_86f.h b/src/floppy/fdd_86f.h index 3293bf7..8242f5b 100644 --- a/src/floppy/fdd_86f.h +++ b/src/floppy/fdd_86f.h @@ -8,10 +8,12 @@ * * Definitions for the 86F floppy image format. * - * Version: @(#)floppy_86f.h 1.0.2 2018/03/14 + * Version: @(#)floppy_86f.h 1.0.4 2018/03/17 * - * Author: Miran Grca, + * Authors: Fred N. van Kempen, + * Miran Grca, * + * Copyright 2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. * * This program is free software; you can redistribute it and/or modify @@ -36,6 +38,9 @@ # define EMU_FLOPPY_86F_H +#define D86FVER 0x020B + + extern void d86f_init(void); extern void d86f_load(int drive, wchar_t *fn); extern void d86f_close(int drive); @@ -56,6 +61,10 @@ extern void d86f_prepare_track_layout(int drive, int side); extern void d86f_set_version(int drive, uint16_t version); extern uint16_t d86f_side_flags(int drive); extern uint16_t d86f_track_flags(int drive); +extern void d86f_initialize_last_sector_id(int drive, int c, int h, + int r, int n); +extern void d86f_initialize_linked_lists(int drive); +extern void d86f_destroy_linked_lists(int drive, int side); #define length_gap0 80 #define length_gap1 50 @@ -76,19 +85,5 @@ extern uint16_t d86f_track_flags(int drive); #define pre_data length_sync + length_am #define post_gap length_crc -#if 0 -extern int raw_tsize[2]; -extern int gap2_size[2]; -extern int gap3_size[2]; -extern int gap4_size[2]; -#endif - -#define D86FVER 0x020B - -extern void d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n); - -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_common.c b/src/floppy/fdd_common.c index d7b91c3..ca532d5 100644 --- a/src/floppy/fdd_common.c +++ b/src/floppy/fdd_common.c @@ -8,7 +8,7 @@ * * Shared code for all the floppy modules. * - * Version: @(#)fdd_common.c 1.0.1 2018/02/14 + * Version: @(#)fdd_common.c 1.0.2 2018/03/16 * * Author: Fred N. van Kempen, * @@ -42,11 +42,11 @@ #include "fdd_common.h" -uint8_t fdd_holes[6] = { 0, 0, 0, 1, 1, 2 }; +const uint8_t fdd_holes[6] = { 0, 0, 0, 1, 1, 2 }; -uint8_t fdd_rates[6] = { 2, 2, 1, 4, 0, 3 }; +const uint8_t fdd_rates[6] = { 2, 2, 1, 4, 0, 3 }; -double fdd_bit_rates_300[6] = { +const double fdd_bit_rates_300[6] = { (250.0 * 300.0) / 360.0, 250.0, 300.0, @@ -65,7 +65,7 @@ double fdd_bit_rates_300[6] = { * Disks formatted at 300 kbps @ 300 RPM can be read with any 300 RPM * single-RPM drive by setting the rate to 300 kbps. */ -uint8_t fdd_max_sectors[8][6] = { +const uint8_t fdd_max_sectors[8][6] = { { 26, 31, 38, 53, 64, 118 }, /* 128 */ { 15, 19, 23, 32, 38, 73 }, /* 256 */ { 7, 10, 12, 17, 22, 41 }, /* 512 */ @@ -76,12 +76,12 @@ uint8_t fdd_max_sectors[8][6] = { { 0, 0, 0, 0, 0, 1 } /* 16384 */ }; -uint8_t fdd_dmf_r[21] = { +const uint8_t fdd_dmf_r[21] = { 12,2,13,3,14,4,15,5,16,6,17,7,18,8,19,9,20,10,21,11,1 }; -static uint8_t fdd_gap3_sizes[5][8][48] = { +static const uint8_t fdd_gap3_sizes[5][8][48] = { { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* [0][0] */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -365,7 +365,6 @@ static uint8_t fdd_gap3_sizes[5][8][48] = { }; - int fdd_get_gap3_size(int rate, int size, int sector) { diff --git a/src/floppy/fdd_common.h b/src/floppy/fdd_common.h index 6bfd3ab..02ff783 100644 --- a/src/floppy/fdd_common.h +++ b/src/floppy/fdd_common.h @@ -8,7 +8,7 @@ * * Shared code for all the floppy modules. * - * Version: @(#)fdd_common.h 1.0.1 2018/02/14 + * Version: @(#)fdd_common.h 1.0.2 2018/03/16 * * Author: Fred N. van Kempen, * @@ -36,11 +36,11 @@ # define FDD_COMMON_H -extern uint8_t fdd_holes[6]; -extern uint8_t fdd_rates[6]; -extern double fdd_bit_rates_300[6]; -extern uint8_t fdd_max_sectors[8][6]; -extern uint8_t fdd_dmf_r[21]; +extern const uint8_t fdd_holes[6]; +extern const uint8_t fdd_rates[6]; +extern const double fdd_bit_rates_300[6]; +extern const uint8_t fdd_max_sectors[8][6]; +extern const uint8_t fdd_dmf_r[21]; extern int fdd_get_gap3_size(int rate, int size, int sector); diff --git a/src/floppy/fdd_fdi.c b/src/floppy/fdd_fdi.c index 7d9c838..d0e00ff 100644 --- a/src/floppy/fdd_fdi.c +++ b/src/floppy/fdd_fdi.c @@ -9,11 +9,13 @@ * Implementation of the FDI floppy stream image format * interface to the FDI2RAW module. * - * Version: @(#)fdd_fdi.c 1.0.1 2018/02/14 + * Version: @(#)fdd_fdi.c 1.0.2 2018/03/17 * - * Authors: Miran Grca, + * Authors: Fred N. van Kempen, + * Miran Grca, * Sarah Walker, * + * Copyright 2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. * Copyright 2008-2018 Sarah Walker. * @@ -38,6 +40,7 @@ #include #include #include +#include #include #include "../emu.h" #include "../plat.h" @@ -49,317 +52,355 @@ #include "fdi2raw.h" -static struct +typedef struct { + FILE *f; + FDI *h; + + int lasttrack; + int sides; + int track; + int tracklen[2][4]; + int trackindex[2][4]; + + uint8_t track_data[2][4][256*1024]; + uint8_t track_timing[2][4][256*1024]; +} fdi_t; + + +static fdi_t *fdi[FDD_NUM]; +static fdc_t *fdi_fdc; + + +static uint16_t +disk_flags(int drive) { - FILE *f; - FDI *h; - uint8_t track_data[2][4][256*1024]; - uint8_t track_timing[2][4][256*1024]; - - int sides; - int track; - int tracklen[2][4]; - int trackindex[2][4]; - - int lasttrack; -} fdi[FDD_NUM]; + fdi_t *dev = fdi[drive]; + uint16_t temp_disk_flags = 0x80; /* We ALWAYS claim to have extra bit cells, even if the actual amount is 0. */ -static fdc_t *fdi_fdc; + switch (fdi2raw_get_bit_rate(dev->h)) { + case 500: + temp_disk_flags |= 2; + break; -uint16_t fdi_disk_flags(int drive) -{ - uint16_t temp_disk_flags = 0x80; /* We ALWAYS claim to have extra bit cells, even if the actual amount is 0. */ + case 300: + case 250: + temp_disk_flags |= 0; + break; - switch (fdi2raw_get_bit_rate(fdi[drive].h)) - { - case 500: - temp_disk_flags |= 2; - break; - case 300: - case 250: - temp_disk_flags |= 0; - break; - case 1000: - temp_disk_flags |= 4; - break; - default: - temp_disk_flags |= 0; - } + case 1000: + temp_disk_flags |= 4; + break; - if (fdi[drive].sides == 2) - { - temp_disk_flags |= 8; - } + default: + temp_disk_flags |= 0; + } - /* Tell the 86F handler that will handle our data to handle it in reverse byte endianness. */ - temp_disk_flags |= 0x800; + if (dev->sides == 2) + temp_disk_flags |= 8; - return temp_disk_flags; + /* + * Tell the 86F handler that we will handle our + * data to handle it in reverse byte endianness. + */ + temp_disk_flags |= 0x800; + + return(temp_disk_flags); } -uint16_t fdi_side_flags(int drive) + +static uint16_t +side_flags(int drive) { - uint16_t temp_side_flags = 0; - switch (fdi2raw_get_bit_rate(fdi[drive].h)) - { - case 500: - temp_side_flags = 0; - break; - case 300: - temp_side_flags = 1; - break; - case 250: - temp_side_flags = 2; - break; - case 1000: - temp_side_flags = 3; - break; - default: - temp_side_flags = 2; - } - if (fdi2raw_get_rotation(fdi[drive].h) == 360) - { - temp_side_flags |= 0x20; - } + fdi_t *dev = fdi[drive]; + uint16_t temp_side_flags = 0; - /* Set the encoding value to match that provided by the FDC. Then if it's wrong, it will sector not found anyway. */ - temp_side_flags |= 0x08; + switch (fdi2raw_get_bit_rate(dev->h)) { + case 500: + temp_side_flags = 0; + break; - return temp_side_flags; + case 300: + temp_side_flags = 1; + break; + + case 250: + temp_side_flags = 2; + break; + + case 1000: + temp_side_flags = 3; + break; + + default: + temp_side_flags = 2; + } + + if (fdi2raw_get_rotation(dev->h) == 360) + temp_side_flags |= 0x20; + + /* + * Set the encoding value to match that provided by the FDC. + * Then if it's wrong, it will sector not found anyway. + */ + temp_side_flags |= 0x08; + + return(temp_side_flags); } -int fdi_density() -{ - if (!fdc_is_mfm(fdi_fdc)) - { - return 0; - } - switch (fdc_get_bit_rate(fdi_fdc)) - { - case 0: - return 2; - case 1: - return 1; - case 2: - return 1; - case 3: - case 5: - return 3; - default: - return 1; - } +static int +fdi_density(void) +{ + if (! fdc_is_mfm(fdi_fdc)) return(0); + + switch (fdc_get_bit_rate(fdi_fdc)) { + case 0: + return(2); + + case 1: + return(1); + + case 2: + return(1); + + case 3: + case 5: + return(3); + + default: + break; + } + + return(1); } -int32_t fdi_extra_bit_cells(int drive, int side) + +static int32_t +extra_bit_cells(int drive, int side) { - int density = 0; + fdi_t *dev = fdi[drive]; + int density = 0; + int raw_size = 0; + int is_300_rpm = 0; - int raw_size = 0; + density = fdi_density(); - int is_300_rpm = 0; + is_300_rpm = (fdd_getrpm(drive) == 300); - density = fdi_density(); + switch (fdc_get_bit_rate(fdi_fdc)) { + case 0: + raw_size = is_300_rpm ? 200000 : 166666; + break; - is_300_rpm = (fdd_getrpm(drive) == 300); + case 1: + raw_size = is_300_rpm ? 120000 : 100000; + break; - switch (fdc_get_bit_rate(fdi_fdc)) - { - case 0: - raw_size = is_300_rpm ? 200000 : 166666; - break; - case 1: - raw_size = is_300_rpm ? 120000 : 100000; - break; - case 2: - raw_size = is_300_rpm ? 100000 : 83333; - case 3: - case 5: - raw_size = is_300_rpm ? 400000 : 333333; - break; - default: - raw_size = is_300_rpm ? 100000 : 83333; + case 2: + raw_size = is_300_rpm ? 100000 : 83333; + break; + + case 3: + case 5: + raw_size = is_300_rpm ? 400000 : 333333; + break; + + default: + raw_size = is_300_rpm ? 100000 : 83333; + } + + return((dev->tracklen[side][density] - raw_size)); +} + + +static void +read_revolution(int drive) +{ + fdi_t *dev = fdi[drive]; + int c, den, side; + int track = dev->track; + + if (track > dev->lasttrack) { + for (den = 0; den < 4; den++) { + memset(dev->track_data[0][den], 0, 106096); + memset(dev->track_data[1][den], 0, 106096); + dev->tracklen[0][den] = dev->tracklen[1][den] = 100000; + } + return; + } + + for (den = 0; den < 4; den++) { + for (side = 0; side < dev->sides; side++) { + c = fdi2raw_loadtrack(dev->h, + (uint16_t *)dev->track_data[side][den], + (uint16_t *)dev->track_timing[side][den], + (track * dev->sides) + side, + &dev->tracklen[side][den], + &dev->trackindex[side][den], NULL, den); + if (! c) + memset(dev->track_data[side][den], 0, dev->tracklen[side][den]); } - return (fdi[drive].tracklen[side][density] - raw_size); -} - -int fdi_hole(int drive) -{ - switch (fdi2raw_get_bit_rate(fdi[drive].h)) - { - case 1000: - return 2; - case 500: - return 1; - default: - return 0; + if (dev->sides == 1) { + memset(dev->track_data[1][den], 0, 106096); + dev->tracklen[1][den] = 100000; } + } } -void fdi_read_revolution(int drive) + +static uint32_t +index_hole_pos(int drive, int side) { - int density; - int track = fdi[drive].track; + fdi_t *dev = fdi[drive]; + int density; - int side = 0; + density = fdi_density(); - if (track > fdi[drive].lasttrack) - { - for (density = 0; density < 4; density++) - { - memset(fdi[drive].track_data[0][density], 0, 106096); - memset(fdi[drive].track_data[1][density], 0, 106096); - fdi[drive].tracklen[0][density] = fdi[drive].tracklen[1][density] = 100000; - } - return; - } - - for (density = 0; density < 4; density++) - { - for (side = 0; side < fdi[drive].sides; side++) - { - int c = fdi2raw_loadtrack(fdi[drive].h, (uint16_t *)fdi[drive].track_data[side][density], - (uint16_t *)fdi[drive].track_timing[side][density], - (track * fdi[drive].sides) + side, - &fdi[drive].tracklen[side][density], - &fdi[drive].trackindex[side][density], NULL, density); - if (!c) - memset(fdi[drive].track_data[side][density], 0, fdi[drive].tracklen[side][density]); - } - - if (fdi[drive].sides == 1) - { - memset(fdi[drive].track_data[1][density], 0, 106096); - fdi[drive].tracklen[1][density] = 100000; - } - } + return(dev->trackindex[side][density]); } -uint32_t fdi_index_hole_pos(int drive, int side) + +static uint32_t +get_raw_size(int drive, int side) { - int density; + fdi_t *dev = fdi[drive]; + int density; - density = fdi_density(); + density = fdi_density(); - return fdi[drive].trackindex[side][density]; + return(dev->tracklen[side][density]); } -uint32_t fdi_get_raw_size(int drive, int side) + +static uint16_t * +encoded_data(int drive, int side) { - int density; + fdi_t *dev = fdi[drive]; + int density = 0; - density = fdi_density(); + density = fdi_density(); - return fdi[drive].tracklen[side][density]; + return((uint16_t *)dev->track_data[side][density]); } -uint16_t* fdi_encoded_data(int drive, int side) + +void +fdi_seek(int drive, int track) { - int density = 0; + fdi_t *dev = fdi[drive]; - density = fdi_density(); + if (fdd_doublestep_40(drive)) { + if (fdi2raw_get_tpi(dev->h) < 2) + track /= 2; + } - return (uint16_t *)fdi[drive].track_data[side][density]; -} + d86f_set_cur_track(drive, track); -void d86f_register_fdi(int drive) -{ - d86f_handler[drive].disk_flags = fdi_disk_flags; - d86f_handler[drive].side_flags = fdi_side_flags; - d86f_handler[drive].writeback = null_writeback; - d86f_handler[drive].set_sector = null_set_sector; - d86f_handler[drive].write_data = null_write_data; - d86f_handler[drive].format_conditions = null_format_conditions; - d86f_handler[drive].extra_bit_cells = fdi_extra_bit_cells; - d86f_handler[drive].encoded_data = fdi_encoded_data; - d86f_handler[drive].read_revolution = fdi_read_revolution; - 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); -} + if (dev->f == NULL) return; -void fdi_load(int drive, wchar_t *fn) -{ - char header[26]; - - writeprot[drive] = fwriteprot[drive] = 1; - fdi[drive].f = plat_fopen(fn, L"rb"); - if (!fdi[drive].f) - { - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - - d86f_unregister(drive); - - fread(header, 1, 25, fdi[drive].f); - fseek(fdi[drive].f, 0, SEEK_SET); - header[25] = 0; - if (strcmp(header, "Formatted Disk Image file") != 0) - { - /* This is a Japanese FDI file. */ - pclog("fdi_load(): Japanese FDI file detected, redirecting to IMG loader\n"); - fclose(fdi[drive].f); - fdi[drive].f = NULL; - img_load(drive, fn); - return; - } - - fdi[drive].h = fdi2raw_header(fdi[drive].f); - fdi[drive].lasttrack = fdi2raw_get_last_track(fdi[drive].h); - fdi[drive].sides = fdi2raw_get_last_head(fdi[drive].h) + 1; - - d86f_register_fdi(drive); - - drives[drive].seek = fdi_seek; - d86f_common_handlers(drive); - - pclog("Loaded as FDI\n"); -} - -void fdi_close(int drive) -{ - d86f_unregister(drive); - drives[drive].seek = NULL; - if (fdi[drive].h) - fdi2raw_header_free(fdi[drive].h); - if (fdi[drive].f) - { - fclose(fdi[drive].f); - fdi[drive].f = NULL; - } -} - -void fdi_seek(int drive, int track) -{ - if (fdd_doublestep_40(drive)) - { - if (fdi2raw_get_tpi(fdi[drive].h) < 2) - { - track /= 2; - } - } - - d86f_set_cur_track(drive, track); - - if (!fdi[drive].f) - return; - if (track < 0) - track = 0; + if (track < 0) + track = 0; #if 0 - if (track > fdi[drive].lasttrack) - track = fdi[drive].lasttrack - 1; + if (track > dev->lasttrack) + track = dev->lasttrack - 1; #endif - fdi[drive].track = track; + dev->track = track; - fdi_read_revolution(drive); + read_revolution(drive); } -void fdi_set_fdc(void *fdc) + +void +fdi_load(int drive, wchar_t *fn) { - fdi_fdc = (fdc_t *) fdc; + char header[26]; + fdi_t *dev; + + writeprot[drive] = fwriteprot[drive] = 1; + + /* Allocate a drive block. */ + dev = (fdi_t *)malloc(sizeof(fdi_t)); + memset(dev, 0x00, sizeof(fdi_t)); + + dev->f = plat_fopen(fn, L"rb"); + if (dev == NULL) { + free(dev); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } + + d86f_unregister(drive); + + fread(header, 1, 25, dev->f); + fseek(dev->f, 0, SEEK_SET); + header[25] = 0; + if (strcmp(header, "Formatted Disk Image file") != 0) { + /* This is a Japanese FDI file. */ + pclog("fdi_load(): Japanese FDI file detected, redirecting to IMG loader\n"); + fclose(dev->f); + free(dev); + img_load(drive, fn); + return; + } + + /* Set up the drive unit. */ + fdi[drive] = dev; + + dev->h = fdi2raw_header(dev->f); + dev->lasttrack = fdi2raw_get_last_track(dev->h); + dev->sides = fdi2raw_get_last_head(dev->h) + 1; + + /* Attach this format to the D86F engine. */ + d86f_handler[drive].disk_flags = disk_flags; + d86f_handler[drive].side_flags = side_flags; + d86f_handler[drive].writeback = null_writeback; + d86f_handler[drive].set_sector = null_set_sector; + d86f_handler[drive].write_data = null_write_data; + d86f_handler[drive].format_conditions = null_format_conditions; + d86f_handler[drive].extra_bit_cells = extra_bit_cells; + d86f_handler[drive].encoded_data = encoded_data; + d86f_handler[drive].read_revolution = read_revolution; + d86f_handler[drive].index_hole_pos = index_hole_pos; + d86f_handler[drive].get_raw_size = get_raw_size; + d86f_handler[drive].check_crc = 1; + d86f_set_version(drive, D86FVER); + + d86f_common_handlers(drive); + + drives[drive].seek = fdi_seek; + + pclog("Loaded as FDI\n"); +} + + +void +fdi_close(int drive) +{ + fdi_t *dev = fdi[drive]; + + if (dev == NULL) return; + + d86f_unregister(drive); + + drives[drive].seek = NULL; + + if (dev->h) + fdi2raw_header_free(dev->h); + + if (dev->f) + fclose(dev->f); + + /* Release the memory. */ + free(dev); + fdi[drive] = NULL; +} + + +void +fdi_set_fdc(void *fdc) +{ + fdi_fdc = (fdc_t *)fdc; } diff --git a/src/floppy/fdd_fdi.h b/src/floppy/fdd_fdi.h index d17def1..4808ecb 100644 --- a/src/floppy/fdd_fdi.h +++ b/src/floppy/fdd_fdi.h @@ -9,11 +9,13 @@ * Implementation of the FDI floppy stream image format * interface to the FDI2RAW module. * - * Version: @(#)floppy_fdi.h 1.0.1 2018/02/14 + * Version: @(#)floppy_fdi.h 1.0.2 2018/03/17 * - * Authors: Miran Grca, + * Authors: Fred N. van Kempen, + * Miran Grca, * Sarah Walker, * + * Copyright 2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. * Copyright 2008-2018 Sarah Walker. * @@ -39,18 +41,9 @@ # define EMU_FLOPPY_FDI_H -extern void fdi_load(int drive, wchar_t *fn); -extern void fdi_close(int drive); -extern void fdi_seek(int drive, int track); -extern void fdi_readsector(int drive, int sector, int track, int side, int density, int sector_size); -extern void fdi_writesector(int drive, int sector, int track, int side, int density, int sector_size); -extern void fdi_comparesector(int drive, int sector, int track, int side, int density, int sector_size); -extern void fdi_readaddress(int drive, int sector, int side, int density); -extern void fdi_format(int drive, int sector, int side, int density, uint8_t fill); -extern int fdi_hole(int drive); -extern double fdi_byteperiod(int drive); -extern void fdi_stop(void); -extern void fdi_poll(void); +extern void fdi_seek(int drive, int track); +extern void fdi_load(int drive, wchar_t *fn); +extern void fdi_close(int drive); #endif /*EMU_FLOPPY_FDI_H*/ diff --git a/src/floppy/fdd_imd.c b/src/floppy/fdd_imd.c index 4e974ec..244ced3 100644 --- a/src/floppy/fdd_imd.c +++ b/src/floppy/fdd_imd.c @@ -8,10 +8,12 @@ * * Implementation of the IMD floppy image format. * - * Version: @(#)fdd_imd.c 1.0.4 2018/03/14 + * Version: @(#)fdd_imd.c 1.0.5 2018/03/17 * - * Author: Miran Grca, + * Authors: Fred N. van Kempen, + * Miran Grca, * + * Copyright 2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. * * This program is free software; you can redistribute it and/or modify @@ -44,811 +46,785 @@ #include "fdc.h" -typedef struct -{ - uint8_t is_present; - uint32_t file_offs; - uint8_t params[5]; - uint32_t r_map_offs; - uint32_t c_map_offs; - uint32_t h_map_offs; - uint32_t n_map_offs; - uint32_t data_offs; - uint32_t sector_data_offs[255]; - uint32_t sector_data_size[255]; - uint32_t gap3_len; - uint16_t side_flags; +typedef struct { + uint8_t is_present; + uint32_t file_offs; + uint8_t params[5]; + uint32_t r_map_offs; + uint32_t c_map_offs; + uint32_t h_map_offs; + uint32_t n_map_offs; + uint32_t data_offs; + uint32_t sector_data_offs[255]; + uint32_t sector_data_size[255]; + uint32_t gap3_len; + uint16_t side_flags; } imd_track_t; -static struct -{ - FILE *f; - char *buffer; - uint32_t start_offs; - int track_count, sides; - int track; - uint16_t disk_flags; - int track_width; - imd_track_t tracks[256][2]; - uint16_t current_side_flags[2]; - uint8_t xdf_ordered_pos[256][2]; - uint8_t interleave_ordered_pos[256][2]; - char *current_data[2]; - uint8_t track_buffer[2][25000]; -} imd[FDD_NUM]; +typedef struct { + FILE *f; + char *buffer; + uint32_t start_offs; + int track_count, sides; + int track; + uint16_t disk_flags; + int track_width; + imd_track_t tracks[256][2]; + uint16_t current_side_flags[2]; + uint8_t xdf_ordered_pos[256][2]; + uint8_t interleave_ordered_pos[256][2]; + char *current_data[2]; + uint8_t track_buffer[2][25000]; +} imd_t; -static fdc_t *imd_fdc; -void imd_init() +static imd_t *imd[FDD_NUM]; +static fdc_t *imd_fdc; + + +static uint32_t +get_raw_tsize(int side_flags, int slower_rpm) { - memset(imd, 0, sizeof(imd)); + uint32_t size; + + switch(side_flags & 0x27) { + case 0x22: + size = slower_rpm ? 5314 : 5208; + break; + + default: + case 0x02: + case 0x21: + size = slower_rpm ? 6375 : 6250; + break; + + case 0x01: + size = slower_rpm ? 7650 : 7500; + break; + + case 0x20: + size = slower_rpm ? 10629 : 10416; + break; + + case 0x00: + size = slower_rpm ? 12750 : 12500; + break; + + case 0x23: + size = slower_rpm ? 21258 : 20833; + break; + + case 0x03: + size = slower_rpm ? 25500 : 25000; + break; + + case 0x25: + size = slower_rpm ? 42517 : 41666; + break; + + case 0x05: + size = slower_rpm ? 51000 : 50000; + break; + } + + return(size); } -void d86f_register_imd(int drive); -void imd_load(int drive, wchar_t *fn) +static int +track_is_xdf(int drive, int side, int track) { - uint32_t magic = 0; - uint32_t fsize = 0; - char *buffer; - char *buffer2; - int i = 0; - int track_spt = 0; - int sector_size = 0; - int track = 0; - int side = 0; - int extra = 0; - uint32_t last_offset = 0; - uint32_t data_size = 512; - uint32_t mfm = 0; - uint32_t pre_sector = 0; - uint32_t track_total = 0; - uint32_t raw_tsize = 0; - uint32_t minimum_gap3 = 0; - uint32_t minimum_gap4 = 0; + imd_t *dev = imd[drive]; + int i, effective_sectors, xdf_sectors; + int high_sectors, low_sectors; + int max_high_id, expected_high_count, expected_low_count; + uint8_t *r_map; + uint8_t *n_map; + char *data_base; + char *cur_data; - d86f_unregister(drive); + effective_sectors = xdf_sectors = high_sectors = low_sectors = 0; - writeprot[drive] = 0; - imd[drive].f = plat_fopen(fn, L"rb+"); - if (!imd[drive].f) - { - imd[drive].f = plat_fopen(fn, L"rb"); - if (!imd[drive].f) - { - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; + for (i = 0; i < 256; i++) + dev->xdf_ordered_pos[i][side] = 0; + + if (dev->tracks[track][side].params[2] & 0xC0) return(0); + + if ((dev->tracks[track][side].params[3] != 16) && + (dev->tracks[track][side].params[3] != 19)) return(0); + + r_map = (uint8_t *)(dev->buffer + dev->tracks[track][side].r_map_offs); + data_base = dev->buffer + dev->tracks[track][side].data_offs; + + if (! track) { + if (dev->tracks[track][side].params[4] != 2) return(0); + + if (! side) { + max_high_id = (dev->tracks[track][side].params[3] == 19) ? 0x8B : 0x88; + expected_high_count = (dev->tracks[track][side].params[3] == 19) ? 0x0B : 0x08; + expected_low_count = 8; + } else { + max_high_id = (dev->tracks[track][side].params[3] == 19) ? 0x93 : 0x90; + expected_high_count = (dev->tracks[track][side].params[3] == 19) ? 0x13 : 0x10; + expected_low_count = 0; + } + + for (i = 0; i < dev->tracks[track][side].params[3]; i++) { + if ((r_map[i] >= 0x81) && (r_map[i] <= max_high_id)) { + high_sectors++; + dev->xdf_ordered_pos[(int) r_map[i]][side] = i; } - writeprot[drive] = 1; - } - if (ui_writeprot[drive]) - { - writeprot[drive] = 1; - } - fwriteprot[drive] = writeprot[drive]; - - fseek(imd[drive].f, 0, SEEK_SET); - fread(&magic, 1, 4, imd[drive].f); - if (magic != 0x20444D49) - { - pclog("IMD: Not a valid ImageDisk image\n"); - fclose(imd[drive].f); - imd[drive].f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - else - { - pclog("IMD: Valid ImageDisk image\n"); - } - - fseek(imd[drive].f, 0, SEEK_END); - fsize = ftell(imd[drive].f); - - fseek(imd[drive].f, 0, SEEK_SET); - imd[drive].buffer = malloc(fsize); - fread(imd[drive].buffer, 1, fsize, imd[drive].f); - buffer = imd[drive].buffer; - - buffer2 = strchr(buffer, 0x1A); - if (buffer2 == NULL) - { - pclog("IMD: No ASCII EOF character\n"); - fclose(imd[drive].f); - imd[drive].f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - else - { - pclog("IMD: ASCII EOF character found at offset %08X\n", buffer2 - buffer); - } - - buffer2++; - if ((buffer2 - buffer) == fsize) - { - pclog("IMD: File ends after ASCII EOF character\n"); - fclose(imd[drive].f); - imd[drive].f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - else - { - pclog("IMD: File continues after ASCII EOF character\n"); - } - - imd[drive].start_offs = (buffer2 - buffer); - imd[drive].disk_flags = 0x00; - imd[drive].track_count = 0; - imd[drive].sides = 1; - - while(1) - { - track = buffer2[1]; - side = buffer2[2]; - if (side & 1) imd[drive].sides = 2; - extra = side & 0xC0; - side &= 0x3F; - - imd[drive].tracks[track][side].side_flags = (buffer2[0] % 3); - if (!imd[drive].tracks[track][side].side_flags) imd[drive].disk_flags |= (0x02); - imd[drive].tracks[track][side].side_flags |= (!(buffer2[0] - imd[drive].tracks[track][side].side_flags) ? 0 : 8); - mfm = imd[drive].tracks[track][side].side_flags & 8; - track_total = mfm ? 146 : 73; - pre_sector = mfm ? 60 : 42; - - track_spt = buffer2[3]; - sector_size = buffer2[4]; - if ((track_spt == 15) && (sector_size == 2)) imd[drive].tracks[track][side].side_flags |= 0x20; - if ((track_spt == 16) && (sector_size == 2)) imd[drive].tracks[track][side].side_flags |= 0x20; - if ((track_spt == 17) && (sector_size == 2)) imd[drive].tracks[track][side].side_flags |= 0x20; - if ((track_spt == 8) && (sector_size == 3)) imd[drive].tracks[track][side].side_flags |= 0x20; - if ((imd[drive].tracks[track][side].side_flags & 7) == 1) imd[drive].tracks[track][side].side_flags |= 0x20; - imd[drive].tracks[track][side].is_present = 1; - imd[drive].tracks[track][side].file_offs = (buffer2 - buffer); - memcpy(imd[drive].tracks[track][side].params, buffer2, 5); - imd[drive].tracks[track][side].r_map_offs = imd[drive].tracks[track][side].file_offs + 5; - last_offset = imd[drive].tracks[track][side].r_map_offs + track_spt; - - if (extra & 0x80) - { - imd[drive].tracks[track][side].c_map_offs = last_offset; - last_offset += track_spt; + if ((r_map[i] >= 0x01) && (r_map[i] <= 0x08)) { + low_sectors++; + dev->xdf_ordered_pos[(int) r_map[i]][side] = i; } - - if (extra & 0x40) - { - imd[drive].tracks[track][side].h_map_offs = last_offset; - last_offset += track_spt; + if ((high_sectors == expected_high_count) && (low_sectors == expected_low_count)) { + dev->current_side_flags[side] = (dev->tracks[track][side].params[3] == 19) ? 0x08 : 0x28; + return((dev->tracks[track][side].params[3] == 19) ? 2 : 1); } + return(0); + } + } else { + if (dev->tracks[track][side].params[4] != 0xFF) return(0); - if (sector_size == 0xFF) - { - imd[drive].tracks[track][side].n_map_offs = last_offset; - buffer2 = buffer + last_offset; - last_offset += track_spt; + n_map = (uint8_t *) (dev->buffer + dev->tracks[track][side].n_map_offs); - imd[drive].tracks[track][side].data_offs = last_offset; + cur_data = data_base; + for (i = 0; i < dev->tracks[track][side].params[3]; i++) { + effective_sectors++; + if (!(r_map[i]) && !(n_map[i])) + effective_sectors--; - for (i = 0; i < track_spt; i++) - { - data_size = buffer2[i]; - data_size = 128 << data_size; - imd[drive].tracks[track][side].sector_data_offs[i] = last_offset; - imd[drive].tracks[track][side].sector_data_size[i] = 1; - if (buffer[imd[drive].tracks[track][side].sector_data_offs[i]] != 0) - { - imd[drive].tracks[track][side].sector_data_size[i] += (buffer[imd[drive].tracks[track][side].sector_data_offs[i]] & 1) ? data_size : 1; - } - last_offset += imd[drive].tracks[track][side].sector_data_size[i]; - if (!(buffer[imd[drive].tracks[track][side].sector_data_offs[i]] & 1)) - { - fwriteprot[drive] = writeprot[drive] = 1; - } - track_total += (pre_sector + data_size + 2); - } - } - else - { - imd[drive].tracks[track][side].data_offs = last_offset; - - for (i = 0; i < track_spt; i++) - { - data_size = sector_size; - data_size = 128 << data_size; - imd[drive].tracks[track][side].sector_data_offs[i] = last_offset; - imd[drive].tracks[track][side].sector_data_size[i] = 1; - if (buffer[imd[drive].tracks[track][side].sector_data_offs[i]] != 0) - { - imd[drive].tracks[track][side].sector_data_size[i] += (buffer[imd[drive].tracks[track][side].sector_data_offs[i]] & 1) ? data_size : 1; - } - last_offset += imd[drive].tracks[track][side].sector_data_size[i]; - if (!(buffer[imd[drive].tracks[track][side].sector_data_offs[i]] & 1)) - { - fwriteprot[drive] = writeprot[drive] = 1; - } - track_total += (pre_sector + data_size + 2); - } - } - buffer2 = buffer + last_offset; - - /* Leaving even GAP4: 80 : 40 */ - /* Leaving only GAP1: 96 : 47 */ - /* Not leaving even GAP1: 146 : 73 */ - raw_tsize = td0_get_raw_tsize(imd[drive].tracks[track][side].side_flags, 0); - minimum_gap3 = 12 * track_spt; - if ((raw_tsize - track_total + (mfm ? 146 : 73)) < (minimum_gap3 + minimum_gap4)) - { - /* If we can't fit the sectors with a reasonable minimum gap at perfect RPM, let's try 2% slower. */ - raw_tsize = td0_get_raw_tsize(imd[drive].tracks[track][side].side_flags, 1); - /* Set disk flags so that rotation speed is 2% slower. */ - imd[drive].disk_flags |= (3 << 5); - if ((raw_tsize - track_total + (mfm ? 146 : 73)) < (minimum_gap3 + minimum_gap4)) - { - /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ - pclog("IMD: Unable to fit the %i sectors in a track\n", track_spt); - fclose(imd[drive].f); - imd[drive].f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - } - imd[drive].tracks[track][side].gap3_len = (raw_tsize - track_total - minimum_gap4 + (mfm ? 146 : 73)) / track_spt; - - imd[drive].track_count++; - - if (last_offset >= fsize) - { - break; + if (r_map[i] == (n_map[i] | 0x80)) { + xdf_sectors++; + dev->xdf_ordered_pos[(int) r_map[i]][side] = i; } + cur_data += (128 << ((uint32_t) n_map[i])); } - imd[drive].track_width = 0; - if (imd[drive].track_count > 43) imd[drive].track_width = 1; /* If the image has more than 43 tracks, then the tracks are thin (96 tpi). */ - if (imd[drive].sides == 2) imd[drive].disk_flags |= 8; /* If the has 2 sides, mark it as such. */ + if ((effective_sectors == 3) && (xdf_sectors == 3)) { + dev->current_side_flags[side] = 0x28; + return(1); /* 5.25" 2HD XDF */ + } - d86f_register_imd(drive); + if ((effective_sectors == 4) && (xdf_sectors == 4)) { + dev->current_side_flags[side] = 0x08; + return(2); /* 3.5" 2HD XDF */ + } - drives[drive].seek = imd_seek; + return(0); + } - d86f_common_handlers(drive); + return(0); } -void imd_close(int drive) + +static int +track_is_interleave(int drive, int side, int track) { - int i = 0; - d86f_unregister(drive); - if (imd[drive].f) - { - free(imd[drive].buffer); - for (i = 0; i < 256; i++) - { - memset(&(imd[drive].tracks[i][0]), 0, sizeof(imd_track_t)); - memset(&(imd[drive].tracks[i][1]), 0, sizeof(imd_track_t)); - } - fclose(imd[drive].f); - imd[drive].f = NULL; + imd_t *dev = imd[drive]; + int i, effective_sectors; + char *r_map; + int track_spt; + + effective_sectors = 0; + + for (i = 0; i < 256; i++) + dev->interleave_ordered_pos[i][side] = 0; + + track_spt = dev->tracks[track][side].params[3]; + + r_map = dev->buffer + dev->tracks[track][side].r_map_offs; + + if (dev->tracks[track][side].params[2] & 0xC0) return(0); + + if (track_spt != 21) return(0); + + if (dev->tracks[track][side].params[4] != 2) return(0); + + for (i = 0; i < track_spt; i++) { + if ((r_map[i] >= 1) && (r_map[i] <= track_spt)) { + effective_sectors++; + dev->interleave_ordered_pos[(int) r_map[i]][side] = i; } + } + + if (effective_sectors == track_spt) return(1); + + return(0); } -int imd_track_is_xdf(int drive, int side, int track) + +static void +sector_to_buffer(int drive, int track, int side, uint8_t *buffer, int sector, int len) { - int i, effective_sectors, xdf_sectors; - int high_sectors, low_sectors; - int max_high_id, expected_high_count, expected_low_count; - uint8_t *r_map; - uint8_t *n_map; - char *data_base; - char *cur_data; + imd_t *dev = imd[drive]; + int type = dev->buffer[dev->tracks[track][side].sector_data_offs[sector]]; - effective_sectors = xdf_sectors = high_sectors = low_sectors = 0; - - for (i = 0; i < 256; i++) - { - imd[drive].xdf_ordered_pos[i][side] = 0; - } - - if (imd[drive].tracks[track][side].params[2] & 0xC0) - { - return 0; - } - if ((imd[drive].tracks[track][side].params[3] != 16) && (imd[drive].tracks[track][side].params[3] != 19)) - { - return 0; - } - r_map = (uint8_t *) (imd[drive].buffer + imd[drive].tracks[track][side].r_map_offs); - data_base = imd[drive].buffer + imd[drive].tracks[track][side].data_offs; - - if (!track) - { - if (imd[drive].tracks[track][side].params[4] != 2) - { - return 0; - } - if (!side) - { - max_high_id = (imd[drive].tracks[track][side].params[3] == 19) ? 0x8B : 0x88; - expected_high_count = (imd[drive].tracks[track][side].params[3] == 19) ? 0x0B : 0x08; - expected_low_count = 8; - } - else - { - max_high_id = (imd[drive].tracks[track][side].params[3] == 19) ? 0x93 : 0x90; - expected_high_count = (imd[drive].tracks[track][side].params[3] == 19) ? 0x13 : 0x10; - expected_low_count = 0; - } - for (i = 0; i < imd[drive].tracks[track][side].params[3]; i++) - { - if ((r_map[i] >= 0x81) && (r_map[i] <= max_high_id)) - { - high_sectors++; - imd[drive].xdf_ordered_pos[(int) r_map[i]][side] = i; - } - if ((r_map[i] >= 0x01) && (r_map[i] <= 0x08)) - { - low_sectors++; - imd[drive].xdf_ordered_pos[(int) r_map[i]][side] = i; - } - if ((high_sectors == expected_high_count) && (low_sectors == expected_low_count)) - { - imd[drive].current_side_flags[side] = (imd[drive].tracks[track][side].params[3] == 19) ? 0x08 : 0x28; - return (imd[drive].tracks[track][side].params[3] == 19) ? 2 : 1; - } - return 0; - } - } - else - { - if (imd[drive].tracks[track][side].params[4] != 0xFF) - { - return 0; - } - - n_map = (uint8_t *) (imd[drive].buffer + imd[drive].tracks[track][side].n_map_offs); - - cur_data = data_base; - for (i = 0; i < imd[drive].tracks[track][side].params[3]; i++) - { - effective_sectors++; - if (!(r_map[i]) && !(n_map[i])) - { - effective_sectors--; - } - if (r_map[i] == (n_map[i] | 0x80)) - { - xdf_sectors++; - imd[drive].xdf_ordered_pos[(int) r_map[i]][side] = i; - } - cur_data += (128 << ((uint32_t) n_map[i])); - } - if ((effective_sectors == 3) && (xdf_sectors == 3)) - { - imd[drive].current_side_flags[side] = 0x28; - return 1; /* 5.25" 2HD XDF */ - } - if ((effective_sectors == 4) && (xdf_sectors == 4)) - { - imd[drive].current_side_flags[side] = 0x08; - return 2; /* 3.5" 2HD XDF */ - } - return 0; - } - - return 0; + if (type == 0) + memset(buffer, 0x00, len); + else { + if (type & 1) + memcpy(buffer, &(dev->buffer[dev->tracks[track][side].sector_data_offs[sector] + 1]), len); + else + memset(buffer, dev->buffer[dev->tracks[track][side].sector_data_offs[sector] + 1], len); + } } -int imd_track_is_interleave(int drive, int side, int track) + +static void +imd_seek(int drive, int track) { - int i, effective_sectors; - char *r_map; - int track_spt; + uint32_t track_buf_pos[2] = { 0, 0 }; + uint8_t id[4] = { 0, 0, 0, 0 }; + uint8_t type, deleted, bad_crc; + imd_t *dev = imd[drive]; + int sector, current_pos; + int side, c = 0, h, n; + int ssize = 512; + int track_rate = 0; + int track_gap2 = 22; + int track_gap3 = 12; + int xdf_type = 0; + int interleave_type = 0; + int is_trackx = 0; + int xdf_spt = 0; + int xdf_sector = 0; + int ordered_pos = 0; + int real_sector = 0; + int actual_sector = 0; + char *c_map = NULL; + char *h_map = NULL; + char *r_map; + char *n_map = NULL; + uint8_t *data; - effective_sectors = 0; + if (dev->f == NULL) return; - for (i = 0; i < 256; i++) - { - imd[drive].interleave_ordered_pos[i][side] = 0; - } + if (!dev->track_width && fdd_doublestep_40(drive)) + track /= 2; - track_spt = imd[drive].tracks[track][side].params[3]; + d86f_set_cur_track(drive, track); - r_map = imd[drive].buffer + imd[drive].tracks[track][side].r_map_offs; + is_trackx = (track == 0) ? 0 : 1; - if (imd[drive].tracks[track][side].params[2] & 0xC0) - { - return 0; - } - if (track_spt != 21) - { - return 0; - } - if (imd[drive].tracks[track][side].params[4] != 2) - { - return 0; - } + dev->track = track; - for (i = 0; i < track_spt; i++) - { - if ((r_map[i] >= 1) && (r_map[i] <= track_spt)) - { - effective_sectors++; - imd[drive].interleave_ordered_pos[(int) r_map[i]][side] = i; - } - } + dev->current_side_flags[0] = dev->tracks[track][0].side_flags; + dev->current_side_flags[1] = dev->tracks[track][1].side_flags; - if (effective_sectors == track_spt) - { - return 1; - } - return 0; -} + d86f_reset_index_hole_pos(drive, 0); + d86f_reset_index_hole_pos(drive, 1); -void imd_sector_to_buffer(int drive, int track, int side, uint8_t *buffer, int sector, int len) -{ - int type = imd[drive].buffer[imd[drive].tracks[track][side].sector_data_offs[sector]]; - if (type == 0) - { - memset(buffer, 0, len); - } - else - { - if (type & 1) - { - memcpy(buffer, &(imd[drive].buffer[imd[drive].tracks[track][side].sector_data_offs[sector] + 1]), len); - } - else - { - memset(buffer, imd[drive].buffer[imd[drive].tracks[track][side].sector_data_offs[sector] + 1], len); - } - } -} + d86f_destroy_linked_lists(drive, 0); + d86f_destroy_linked_lists(drive, 1); -void imd_seek(int drive, int track) -{ - int side; - - uint8_t id[4] = { 0, 0, 0, 0 }; - uint8_t type, deleted, bad_crc; - - int sector, current_pos; - - int c = 0; - int h = 0; - int n = 0; - int ssize = 512; - - int track_rate = 0; - - int track_gap2 = 22; - int track_gap3 = 12; - - int xdf_type = 0; - int interleave_type = 0; - - int is_trackx = 0; - - int xdf_spt = 0; - int xdf_sector = 0; - - int ordered_pos = 0; - - int real_sector = 0; - int actual_sector = 0; - - char *c_map = NULL; - char *h_map = NULL; - char *r_map; - char *n_map = NULL; - uint8_t *data; - uint32_t track_buf_pos[2] = { 0, 0 }; - - if (!imd[drive].f) - return; - - if (!imd[drive].track_width && fdd_doublestep_40(drive)) - track /= 2; - - d86f_set_cur_track(drive, track); - - is_trackx = (track == 0) ? 0 : 1; - - imd[drive].track = track; - - imd[drive].current_side_flags[0] = imd[drive].tracks[track][0].side_flags; - imd[drive].current_side_flags[1] = imd[drive].tracks[track][1].side_flags; - - d86f_reset_index_hole_pos(drive, 0); - d86f_reset_index_hole_pos(drive, 1); - - d86f_destroy_linked_lists(drive, 0); - d86f_destroy_linked_lists(drive, 1); - - if (track > imd[drive].track_count) - { - d86f_zero_track(drive); - return; - } - - for (side = 0; side < imd[drive].sides; side++) - { - track_rate = imd[drive].current_side_flags[side] & 7; - if (!track_rate && (imd[drive].current_side_flags[side] & 0x20)) track_rate = 4; - if ((imd[drive].current_side_flags[side] & 0x27) == 0x21) track_rate = 2; - - r_map = imd[drive].buffer + imd[drive].tracks[track][side].r_map_offs; - h = imd[drive].tracks[track][side].params[2]; - if (h & 0x80) - { - c_map = imd[drive].buffer + imd[drive].tracks[track][side].c_map_offs; - } - else - { - c = imd[drive].tracks[track][side].params[1]; - } - if (h & 0x40) - { - h_map = imd[drive].buffer + imd[drive].tracks[track][side].h_map_offs; - } - n = imd[drive].tracks[track][side].params[4]; - if (n == 0xFF) - { - n_map = imd[drive].buffer + imd[drive].tracks[track][side].n_map_offs; - track_gap3 = gap3_sizes[track_rate][(int) n_map[0]][imd[drive].tracks[track][side].params[3]]; - } - else - { - track_gap3 = gap3_sizes[track_rate][n][imd[drive].tracks[track][side].params[3]]; - } - if (!track_gap3) - { - track_gap3 = imd[drive].tracks[track][side].gap3_len; - } - - xdf_type = imd_track_is_xdf(drive, side, track); - - interleave_type = imd_track_is_interleave(drive, side, track); - - current_pos = d86f_prepare_pretrack(drive, side, 0); - - if (!xdf_type) - { - for (sector = 0; sector < imd[drive].tracks[track][side].params[3]; sector++) - { - if (interleave_type == 0) - { - real_sector = r_map[sector]; - actual_sector = sector; - } - else - { - real_sector = dmf_r[sector]; - actual_sector = imd[drive].interleave_ordered_pos[real_sector][side]; - } - id[0] = (h & 0x80) ? c_map[actual_sector] : c; - id[1] = (h & 0x40) ? h_map[actual_sector] : (h & 1); - id[2] = real_sector; - id[3] = (n == 0xFF) ? n_map[actual_sector] : n; - ssize = 128 << ((uint32_t) id[3]); - data = imd[drive].track_buffer[side] + track_buf_pos[side]; - type = imd[drive].buffer[imd[drive].tracks[track][side].sector_data_offs[actual_sector]]; - type = (type >> 1) & 7; - deleted = bad_crc = 0; - if ((type == 2) || (type == 4)) deleted = 1; - if ((type == 3) || (type == 4)) bad_crc = 1; - - 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 - { - xdf_type--; - xdf_spt = xdf_physical_sectors[xdf_type][is_trackx]; - for (sector = 0; sector < xdf_spt; sector++) - { - xdf_sector = (side * xdf_spt) + sector; - id[0] = track; - id[1] = side; - id[2] = xdf_disk_layout[xdf_type][is_trackx][xdf_sector].id.r; - id[3] = is_trackx ? (id[2] & 7) : 2; - ssize = 128 << ((uint32_t) id[3]); - ordered_pos = imd[drive].xdf_ordered_pos[id[2]][side]; - - data = imd[drive].track_buffer[side] + track_buf_pos[side]; - type = imd[drive].buffer[imd[drive].tracks[track][side].sector_data_offs[ordered_pos]]; - type = (type >> 1) & 7; - deleted = bad_crc = 0; - if ((type == 2) || (type == 4)) deleted = 1; - if ((type == 3) || (type == 4)) bad_crc = 1; - imd_sector_to_buffer(drive, track, side, data, ordered_pos, ssize); - - if (is_trackx) - { - current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[xdf_type][xdf_sector], id, data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], deleted, bad_crc); - } - else - { - current_pos = d86f_prepare_sector(drive, side, current_pos, id, data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], 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]); - } - } - } - } -} - -uint16_t imd_disk_flags(int drive) -{ - return imd[drive].disk_flags; -} - -uint16_t imd_side_flags(int drive) -{ - int side = 0; - uint16_t sflags = 0; - side = fdd_get_head(drive); - sflags = imd[drive].current_side_flags[side]; - return sflags; -} - -void imd_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) -{ - int i = 0; - int track = imd[drive].track; - int sc = 0; - int sh = 0; - int sn = 0; - char *c_map = 0, *h_map = 0, *r_map = 0, *n_map = 0; - uint8_t id[4] = { 0, 0, 0, 0 }; - sc = imd[drive].tracks[track][side].params[1]; - sh = imd[drive].tracks[track][side].params[2]; - sn = imd[drive].tracks[track][side].params[4]; - if (sh & 0x80) - { - c_map = imd[drive].buffer + imd[drive].tracks[track][side].c_map_offs; - } - if (sh & 0x40) - { - h_map = imd[drive].buffer + imd[drive].tracks[track][side].h_map_offs; - } - r_map = imd[drive].buffer + imd[drive].tracks[track][side].r_map_offs; - if (sn == 0xFF) - { - n_map = imd[drive].buffer + imd[drive].tracks[track][side].n_map_offs; - } - if (c != imd[drive].track) return; - for (i = 0; i < imd[drive].tracks[track][side].params[3]; i++) - { - id[0] = (sh & 0x80) ? c_map[i] : sc; - id[1] = (sh & 0x40) ? h_map[i] : (sh & 1); - id[2] = r_map[i]; - id[3] = (sn == 0xFF) ? n_map[i] : sn; - if ((id[0] == c) && - (id[1] == h) && - (id[2] == r) && - (id[3] == n)) - { - imd[drive].current_data[side] = imd[drive].buffer + imd[drive].tracks[track][side].sector_data_offs[i]; - } - } + if (track > dev->track_count) { + d86f_zero_track(drive); return; -} + } -void imd_writeback(int drive) -{ - int side; - int track = imd[drive].track; + for (side = 0; side < dev->sides; side++) { + track_rate = dev->current_side_flags[side] & 7; + if (!track_rate && (dev->current_side_flags[side] & 0x20)) + track_rate = 4; + if ((dev->current_side_flags[side] & 0x27) == 0x21) + track_rate = 2; - int i = 0; + r_map = dev->buffer + dev->tracks[track][side].r_map_offs; + h = dev->tracks[track][side].params[2]; + if (h & 0x80) + c_map = dev->buffer + dev->tracks[track][side].c_map_offs; + else + c = dev->tracks[track][side].params[1]; - char *n_map = 0; + if (h & 0x40) + h_map = dev->buffer + dev->tracks[track][side].h_map_offs; - uint8_t h, n, spt; - uint32_t ssize; - - if (writeprot[drive]) - { - return; + n = dev->tracks[track][side].params[4]; + if (n == 0xFF) { + n_map = dev->buffer + dev->tracks[track][side].n_map_offs; + track_gap3 = gap3_sizes[track_rate][(int) n_map[0]][dev->tracks[track][side].params[3]]; + } else { + track_gap3 = gap3_sizes[track_rate][n][dev->tracks[track][side].params[3]]; } - for (side = 0; side < imd[drive].sides; side++) - { - if (imd[drive].tracks[track][side].is_present) - { - fseek(imd[drive].f, imd[drive].tracks[track][side].file_offs, SEEK_SET); - h = imd[drive].tracks[track][side].params[2]; - spt = imd[drive].tracks[track][side].params[3]; - n = imd[drive].tracks[track][side].params[4]; - fwrite(imd[drive].tracks[track][side].params, 1, 5, imd[drive].f); - if (h & 0x80) - { - fwrite(imd[drive].buffer + imd[drive].tracks[track][side].c_map_offs, 1, spt, imd[drive].f); - } - if (h & 0x40) - { - fwrite(imd[drive].buffer + imd[drive].tracks[track][side].h_map_offs, 1, spt, imd[drive].f); - } - if (n == 0xFF) - { - n_map = imd[drive].buffer + imd[drive].tracks[track][side].n_map_offs; - fwrite(n_map, 1, spt, imd[drive].f); - } - for (i = 0; i < spt; i++) - { - ssize = (n == 0xFF) ? n_map[i] : n; - ssize = 128 << ssize; - fwrite(imd[drive].buffer + imd[drive].tracks[track][side].sector_data_offs[i], 1, ssize, imd[drive].f); + if (! track_gap3) + track_gap3 = dev->tracks[track][side].gap3_len; + + xdf_type = track_is_xdf(drive, side, track); + + interleave_type = track_is_interleave(drive, side, track); + + current_pos = d86f_prepare_pretrack(drive, side, 0); + + if (! xdf_type) { + for (sector = 0; sector < dev->tracks[track][side].params[3]; sector++) { + if (interleave_type == 0) { + real_sector = r_map[sector]; + actual_sector = sector; + } else { + real_sector = dmf_r[sector]; + actual_sector = dev->interleave_ordered_pos[real_sector][side]; } + id[0] = (h & 0x80) ? c_map[actual_sector] : c; + id[1] = (h & 0x40) ? h_map[actual_sector] : (h & 1); + id[2] = real_sector; + id[3] = (n == 0xFF) ? n_map[actual_sector] : n; + ssize = 128 << ((uint32_t) id[3]); + data = dev->track_buffer[side] + track_buf_pos[side]; + type = dev->buffer[dev->tracks[track][side].sector_data_offs[actual_sector]]; + type = (type >> 1) & 7; + deleted = bad_crc = 0; + if ((type == 2) || (type == 4)) deleted = 1; + if ((type == 3) || (type == 4)) bad_crc = 1; + + 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 { + xdf_type--; + xdf_spt = xdf_physical_sectors[xdf_type][is_trackx]; + for (sector = 0; sector < xdf_spt; sector++) { + xdf_sector = (side * xdf_spt) + sector; + id[0] = track; + id[1] = side; + id[2] = xdf_disk_layout[xdf_type][is_trackx][xdf_sector].id.r; + id[3] = is_trackx ? (id[2] & 7) : 2; + ssize = 128 << ((uint32_t) id[3]); + ordered_pos = dev->xdf_ordered_pos[id[2]][side]; + + data = dev->track_buffer[side] + track_buf_pos[side]; + type = dev->buffer[dev->tracks[track][side].sector_data_offs[ordered_pos]]; + type = (type >> 1) & 7; + deleted = bad_crc = 0; + if ((type == 2) || (type == 4)) deleted = 1; + if ((type == 3) || (type == 4)) bad_crc = 1; + sector_to_buffer(drive, track, side, data, ordered_pos, ssize); + + if (is_trackx) + current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[xdf_type][xdf_sector], id, data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], deleted, bad_crc); + else + current_pos = d86f_prepare_sector(drive, side, current_pos, id, data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], 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]); } } + } } -uint8_t imd_poll_read_data(int drive, int side, uint16_t pos) + +static uint16_t +disk_flags(int drive) { - int type = imd[drive].current_data[side][0]; - if (!(type & 1)) - { - return 0xf6; /* Should never happen. */ + imd_t *dev = imd[drive]; + + return(dev->disk_flags); +} + + +static uint16_t +side_flags(int drive) +{ + imd_t *dev = imd[drive]; + int side = 0; + uint16_t sflags = 0; + + side = fdd_get_head(drive); + sflags = dev->current_side_flags[side]; + + return(sflags); +} + + +static void +set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) +{ + imd_t *dev = imd[drive]; + int track = dev->track; + int i, sc, sh, sn; + char *c_map = NULL, *h_map = NULL, *r_map = NULL, *n_map = NULL; + uint8_t id[4] = { 0, 0, 0, 0 }; + sc = dev->tracks[track][side].params[1]; + sh = dev->tracks[track][side].params[2]; + sn = dev->tracks[track][side].params[4]; + + if (sh & 0x80) + c_map = dev->buffer + dev->tracks[track][side].c_map_offs; + if (sh & 0x40) + h_map = dev->buffer + dev->tracks[track][side].h_map_offs; + r_map = dev->buffer + dev->tracks[track][side].r_map_offs; + + if (sn == 0xFF) + n_map = dev->buffer + dev->tracks[track][side].n_map_offs; + + if (c != dev->track) return; + + for (i = 0; i < dev->tracks[track][side].params[3]; i++) { + id[0] = (sh & 0x80) ? c_map[i] : sc; + id[1] = (sh & 0x40) ? h_map[i] : (sh & 1); + id[2] = r_map[i]; + id[3] = (sn == 0xFF) ? n_map[i] : sn; + if ((id[0] == c) && (id[1] == h) && (id[2] == r) && (id[3] == n)) { + dev->current_data[side] = dev->buffer + dev->tracks[track][side].sector_data_offs[i]; } - return imd[drive].current_data[side][pos + 1]; + } } -void imd_poll_write_data(int drive, int side, uint16_t pos, uint8_t data) + +static void +imd_writeback(int drive) { - int type = imd[drive].current_data[side][0]; - if (writeprot[drive]) - { + imd_t *dev = imd[drive]; + int side; + int track = dev->track; + int i = 0; + char *n_map = 0; + uint8_t h, n, spt; + uint32_t ssize; + + if (writeprot[drive]) return; + + for (side = 0; side < dev->sides; side++) { + if (dev->tracks[track][side].is_present) { + fseek(dev->f, dev->tracks[track][side].file_offs, SEEK_SET); + h = dev->tracks[track][side].params[2]; + spt = dev->tracks[track][side].params[3]; + n = dev->tracks[track][side].params[4]; + fwrite(dev->tracks[track][side].params, 1, 5, dev->f); + + if (h & 0x80) + fwrite(dev->buffer + dev->tracks[track][side].c_map_offs, 1, spt, dev->f); + + if (h & 0x40) + fwrite(dev->buffer + dev->tracks[track][side].h_map_offs, 1, spt, dev->f); + + if (n == 0xFF) { + n_map = dev->buffer + dev->tracks[track][side].n_map_offs; + fwrite(n_map, 1, spt, dev->f); + } + for (i = 0; i < spt; i++) { + ssize = (n == 0xFF) ? n_map[i] : n; + ssize = 128 << ssize; + fwrite(dev->buffer + dev->tracks[track][side].sector_data_offs[i], 1, ssize, dev->f); + } + } + } +} + + +static uint8_t +poll_read_data(int drive, int side, uint16_t pos) +{ + imd_t *dev = imd[drive]; + int type = dev->current_data[side][0]; + + if (! (type & 1)) return(0xf6); /* Should never happen. */ + + return(dev->current_data[side][pos + 1]); +} + + +static void +poll_write_data(int drive, int side, uint16_t pos, uint8_t data) +{ + imd_t *dev = imd[drive]; + int type = dev->current_data[side][0]; + + if (writeprot[drive]) return; + + if (! (type & 1)) return; /* Should never happen. */ + + dev->current_data[side][pos + 1] = data; +} + + +static int +format_conditions(int drive) +{ + imd_t *dev = imd[drive]; + int track = dev->track; + int side, temp; + + side = fdd_get_head(drive); + temp = (fdc_get_format_sectors(imd_fdc) == dev->tracks[track][side].params[3]); + temp = temp && (fdc_get_format_n(imd_fdc) == dev->tracks[track][side].params[4]); + + return(temp); +} + + +void +imd_init(void) +{ + memset(imd, 0x00, sizeof(imd)); +} + + +void +imd_load(int drive, wchar_t *fn) +{ + uint32_t magic = 0; + uint32_t fsize = 0; + char *buffer; + char *buffer2; + imd_t *dev; + int i = 0; + int track_spt = 0; + int sector_size = 0; + int track = 0; + int side = 0; + int extra = 0; + uint32_t last_offset = 0; + uint32_t data_size = 512; + uint32_t mfm = 0; + uint32_t pre_sector = 0; + uint32_t track_total = 0; + uint32_t raw_tsize = 0; + uint32_t minimum_gap3 = 0; + uint32_t minimum_gap4 = 0; + + d86f_unregister(drive); + + writeprot[drive] = 0; + + /* Allocate a drive block. */ + dev = (imd_t *)malloc(sizeof(imd_t)); + memset(dev, 0x00, sizeof(imd_t)); + + dev->f = plat_fopen(fn, L"rb+"); + if (dev->f == NULL) { + dev->f = plat_fopen(fn, L"rb"); + if (dev->f == NULL) { + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); return; } - if (!(type & 1)) - { - return; /* Should never happen. */ + writeprot[drive] = 1; + } + + if (ui_writeprot[drive]) + writeprot[drive] = 1; + fwriteprot[drive] = writeprot[drive]; + + fseek(dev->f, 0, SEEK_SET); + fread(&magic, 1, 4, dev->f); + if (magic != 0x20444D49) { + pclog("IMD: Not a valid ImageDisk image\n"); + fclose(dev->f); + free(dev);; + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } else { + pclog("IMD: Valid ImageDisk image\n"); + } + + fseek(dev->f, 0, SEEK_END); + fsize = ftell(dev->f); + fseek(dev->f, 0, SEEK_SET); + dev->buffer = malloc(fsize); + fread(dev->buffer, 1, fsize, dev->f); + buffer = dev->buffer; + + buffer2 = strchr(buffer, 0x1A); + if (buffer2 == NULL) { + pclog("IMD: No ASCII EOF character\n"); + fclose(dev->f); + free(dev); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } else { + pclog("IMD: ASCII EOF character found at offset %08X\n", buffer2 - buffer); + } + + buffer2++; + if ((buffer2 - buffer) == fsize) { + pclog("IMD: File ends after ASCII EOF character\n"); + fclose(dev->f); + free(dev); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } else { + pclog("IMD: File continues after ASCII EOF character\n"); + } + + dev->start_offs = (buffer2 - buffer); + dev->disk_flags = 0x00; + dev->track_count = 0; + dev->sides = 1; + + /* Set up the drive unit. */ + imd[drive] = dev; + + while(1) { + track = buffer2[1]; + side = buffer2[2]; + if (side & 1) + dev->sides = 2; + extra = side & 0xC0; + side &= 0x3F; + + dev->tracks[track][side].side_flags = (buffer2[0] % 3); + if (! dev->tracks[track][side].side_flags) + dev->disk_flags |= (0x02); + dev->tracks[track][side].side_flags |= (!(buffer2[0] - dev->tracks[track][side].side_flags) ? 0 : 8); + mfm = dev->tracks[track][side].side_flags & 8; + track_total = mfm ? 146 : 73; + pre_sector = mfm ? 60 : 42; + + track_spt = buffer2[3]; + sector_size = buffer2[4]; + if ((track_spt == 15) && (sector_size == 2)) + dev->tracks[track][side].side_flags |= 0x20; + if ((track_spt == 16) && (sector_size == 2)) + dev->tracks[track][side].side_flags |= 0x20; + if ((track_spt == 17) && (sector_size == 2)) + dev->tracks[track][side].side_flags |= 0x20; + if ((track_spt == 8) && (sector_size == 3)) + dev->tracks[track][side].side_flags |= 0x20; + if ((dev->tracks[track][side].side_flags & 7) == 1) + dev->tracks[track][side].side_flags |= 0x20; + dev->tracks[track][side].is_present = 1; + dev->tracks[track][side].file_offs = (buffer2 - buffer); + memcpy(dev->tracks[track][side].params, buffer2, 5); + dev->tracks[track][side].r_map_offs = dev->tracks[track][side].file_offs + 5; + last_offset = dev->tracks[track][side].r_map_offs + track_spt; + + if (extra & 0x80) { + dev->tracks[track][side].c_map_offs = last_offset; + last_offset += track_spt; } - imd[drive].current_data[side][pos + 1] = data; + + if (extra & 0x40) { + dev->tracks[track][side].h_map_offs = last_offset; + last_offset += track_spt; + } + + if (sector_size == 0xFF) { + dev->tracks[track][side].n_map_offs = last_offset; + buffer2 = buffer + last_offset; + last_offset += track_spt; + + dev->tracks[track][side].data_offs = last_offset; + + for (i = 0; i < track_spt; i++) { + data_size = buffer2[i]; + data_size = 128 << data_size; + dev->tracks[track][side].sector_data_offs[i] = last_offset; + dev->tracks[track][side].sector_data_size[i] = 1; + if (buffer[dev->tracks[track][side].sector_data_offs[i]] != 0) + dev->tracks[track][side].sector_data_size[i] += (buffer[dev->tracks[track][side].sector_data_offs[i]] & 1) ? data_size : 1; + last_offset += dev->tracks[track][side].sector_data_size[i]; + if (!(buffer[dev->tracks[track][side].sector_data_offs[i]] & 1)) + fwriteprot[drive] = writeprot[drive] = 1; + track_total += (pre_sector + data_size + 2); + } + } else { + dev->tracks[track][side].data_offs = last_offset; + + for (i = 0; i < track_spt; i++) { + data_size = sector_size; + data_size = 128 << data_size; + dev->tracks[track][side].sector_data_offs[i] = last_offset; + dev->tracks[track][side].sector_data_size[i] = 1; + if (buffer[dev->tracks[track][side].sector_data_offs[i]] != 0) + dev->tracks[track][side].sector_data_size[i] += (buffer[dev->tracks[track][side].sector_data_offs[i]] & 1) ? data_size : 1; + last_offset += dev->tracks[track][side].sector_data_size[i]; + if (!(buffer[dev->tracks[track][side].sector_data_offs[i]] & 1)) + fwriteprot[drive] = writeprot[drive] = 1; + track_total += (pre_sector + data_size + 2); + } + } + buffer2 = buffer + last_offset; + + /* Leaving even GAP4: 80 : 40 */ + /* Leaving only GAP1: 96 : 47 */ + /* Not leaving even GAP1: 146 : 73 */ + raw_tsize = get_raw_tsize(dev->tracks[track][side].side_flags, 0); + minimum_gap3 = 12 * track_spt; + if ((raw_tsize - track_total + (mfm ? 146 : 73)) < (minimum_gap3 + minimum_gap4)) { + /* If we can't fit the sectors with a reasonable minimum gap at perfect RPM, let's try 2% slower. */ + raw_tsize = get_raw_tsize(dev->tracks[track][side].side_flags, 1); + /* Set disk flags so that rotation speed is 2% slower. */ + dev->disk_flags |= (3 << 5); + if ((raw_tsize - track_total + (mfm ? 146 : 73)) < (minimum_gap3 + minimum_gap4)) { + /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ + pclog("IMD: Unable to fit the %i sectors in a track\n", track_spt); + fclose(dev->f); + free(dev); + imd[drive] = NULL; + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } + } + + dev->tracks[track][side].gap3_len = (raw_tsize - track_total - minimum_gap4 + (mfm ? 146 : 73)) / track_spt; + + dev->track_count++; + + if (last_offset >= fsize) break; + } + + /* If more than 43 tracks, then the tracks are thin (96 tpi). */ + dev->track_width = 0; + if (dev->track_count > 43) + dev->track_width = 1; + + /* If 2 sides, mark it as such. */ + if (dev->sides == 2) + dev->disk_flags |= 8; + + /* Attach this format to the D86F engine. */ + d86f_handler[drive].disk_flags = disk_flags; + d86f_handler[drive].side_flags = side_flags; + d86f_handler[drive].writeback = imd_writeback; + d86f_handler[drive].set_sector = set_sector; + d86f_handler[drive].read_data = poll_read_data; + d86f_handler[drive].write_data = poll_write_data; + d86f_handler[drive].format_conditions = format_conditions; + d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; + d86f_handler[drive].encoded_data = common_encoded_data; + d86f_handler[drive].read_revolution = common_read_revolution; + 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); + + drives[drive].seek = imd_seek; + + d86f_common_handlers(drive); } -int imd_format_conditions(int drive) + +void +imd_close(int drive) { - int track = imd[drive].track; - int side = 0; - int temp = 0; - side = fdd_get_head(drive); - temp = (fdc_get_format_sectors(imd_fdc) == imd[drive].tracks[track][side].params[3]); - temp = temp && (fdc_get_format_n(imd_fdc) == imd[drive].tracks[track][side].params[4]); - return temp; + imd_t *dev = imd[drive]; + + if (dev == NULL) return; + + d86f_unregister(drive); + + if (dev->f != NULL) { + free(dev->buffer); + + fclose(dev->f); + } + + /* Release the memory. */ + free(dev); + imd[drive] = NULL; } -void imd_set_fdc(void *fdc) -{ - imd_fdc = (fdc_t *) fdc; -} -void d86f_register_imd(int drive) +void +imd_set_fdc(void *fdc) { - d86f_handler[drive].disk_flags = imd_disk_flags; - 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; - d86f_handler[drive].encoded_data = common_encoded_data; - d86f_handler[drive].read_revolution = common_read_revolution; - 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); + imd_fdc = (fdc_t *) fdc; } diff --git a/src/floppy/fdd_imd.h b/src/floppy/fdd_imd.h index 661230a..4e16bd0 100644 --- a/src/floppy/fdd_imd.h +++ b/src/floppy/fdd_imd.h @@ -8,10 +8,12 @@ * * Definitions for the IMD floppy image format. * - * Version: @(#)floppy_imd.h 1.0.1 2018/02/14 + * Version: @(#)floppy_imd.h 1.0.2 2018/03/17 * - * Author: Miran Grca, + * Authors: Fred N. van Kempen, + * Miran Grca, * + * Copyright 2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. * * This program is free software; you can redistribute it and/or modify @@ -39,7 +41,6 @@ extern void imd_init(void); extern void imd_load(int drive, wchar_t *fn); extern void imd_close(int drive); -extern void imd_seek(int drive, int track); #endif /*EMU_FLOPPY_IMD_H*/ diff --git a/src/floppy/fdd_img.c b/src/floppy/fdd_img.c index ef46b2d..741befb 100644 --- a/src/floppy/fdd_img.c +++ b/src/floppy/fdd_img.c @@ -9,11 +9,17 @@ * 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.2 2018/03/14 + * NOTE: This file is still a disaster, needs to be cleaned up and + * re-merged with the other files. Much of it is generic to + * all formats. * - * Authors: Miran Grca, + * Version: @(#)fdd_img.c 1.0.5 2018/03/17 + * + * Authors: Fred N. van Kempen, + * Miran Grca, * Sarah Walker, * + * Copyright 2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. * Copyright 2008-2018 Sarah Walker. * @@ -48,42 +54,57 @@ #include "fdc.h" -static struct -{ - FILE *f; - uint8_t track_data[2][50000]; - int sectors, tracks, sides; - uint8_t sector_size; - int xdf_type; /* 0 = not XDF, 1-5 = one of the five XDF types */ - int dmf; - int track; - int track_width; - uint32_t base; - uint8_t gap2_size; - uint8_t gap3_size; - uint16_t disk_flags; - uint16_t track_flags; - uint8_t sector_pos_side[2][256]; - uint16_t sector_pos[2][256]; - uint8_t current_sector_pos_side; - uint16_t current_sector_pos; - uint8_t *disk_data; - uint8_t is_cqm; - uint8_t disk_at_once; - uint8_t interleave; - uint8_t skew; -} img[FDD_NUM]; +typedef struct { + FILE *f; + uint8_t track_data[2][50000]; + int sectors, tracks, sides; + uint8_t sector_size; + int xdf_type; /* 0 = not XDF, 1-5 = one of the five XDF types */ + int dmf; + int track; + int track_width; + uint32_t base; + uint8_t gap2_size; + uint8_t gap3_size; + uint16_t disk_flags; + uint16_t track_flags; + uint8_t sector_pos_side[2][256]; + uint16_t sector_pos[2][256]; + uint8_t current_sector_pos_side; + uint16_t current_sector_pos; + uint8_t *disk_data; + uint8_t is_cqm; + uint8_t disk_at_once; + uint8_t interleave; + uint8_t skew; +} img_t; -static fdc_t *img_fdc; -uint8_t dmf_r[21] = { 12, 2, 13, 3, 14, 4, 15, 5, 16, 6, 17, 7, 18, 8, 19, 9, 20, 10, 21, 11, 1 }; -static uint8_t xdf_logical_sectors[2][2] = { { 38, 6 }, { 46, 8 } }; -uint8_t xdf_physical_sectors[2][2] = { { 16, 3 }, { 19, 4 } }; -uint8_t xdf_gap3_sizes[2][2] = { { 60, 69 }, { 60, 50 } }; -uint16_t xdf_trackx_spos[2][8] = { { 0xA7F, 0xF02, 0x11B7, 0xB66, 0xE1B, 0x129E }, { 0x302, 0x7E2, 0xA52, 0x12DA, 0x572, 0xDFA, 0x106A, 0x154A } }; +static img_t *img[FDD_NUM]; +static fdc_t *img_fdc; + +static double bit_rate_300; +static wchar_t *ext; +static uint8_t first_byte, + second_byte, + third_byte, + fourth_byte; +static uint8_t fdf_suppress_final_byte = 0; /* This is hard-coded to 0 - + * if you really need to read + * those NT 3.1 Beta floppy + * images, change this to 1 + * and recompile. + */ + + +const uint8_t dmf_r[21] = { 12, 2, 13, 3, 14, 4, 15, 5, 16, 6, 17, 7, 18, 8, 19, 9, 20, 10, 21, 11, 1 }; +static const uint8_t xdf_logical_sectors[2][2] = { { 38, 6 }, { 46, 8 } }; +const uint8_t xdf_physical_sectors[2][2] = { { 16, 3 }, { 19, 4 } }; +const uint8_t xdf_gap3_sizes[2][2] = { { 60, 69 }, { 60, 50 } }; +const uint16_t xdf_trackx_spos[2][8] = { { 0xA7F, 0xF02, 0x11B7, 0xB66, 0xE1B, 0x129E }, { 0x302, 0x7E2, 0xA52, 0x12DA, 0x572, 0xDFA, 0x106A, 0x154A } }; /* XDF: Layout of the sectors in the image. */ -xdf_sector_t xdf_img_layout[2][2][46] = { { { {0x8100}, {0x8200}, {0x8300}, {0x8400}, {0x8500}, {0x8600}, {0x8700}, {0x8800}, +const xdf_sector_t xdf_img_layout[2][2][46] = { { { {0x8100}, {0x8200}, {0x8300}, {0x8400}, {0x8500}, {0x8600}, {0x8700}, {0x8800}, {0x8101}, {0x8201}, {0x0100}, {0x0200}, {0x0300}, {0x0400}, {0x0500}, {0x0600}, {0x0700}, {0x0800}, { 0}, {0x8301}, {0x8401}, {0x8501}, {0x8601}, {0x8701}, {0x8801}, {0x8901}, {0x8A01}, @@ -102,7 +123,7 @@ xdf_sector_t xdf_img_layout[2][2][46] = { { { {0x8100}, {0x8200}, {0x8300}, {0x8 }; /* XDF: Layout of the sectors on the disk's track. */ -xdf_sector_t xdf_disk_layout[2][2][38] = { { { {0x0100}, {0x0200}, {0x8100}, {0x8800}, {0x8200}, {0x0300}, {0x8300}, {0x0400}, +const xdf_sector_t xdf_disk_layout[2][2][38] = { { { {0x0100}, {0x0200}, {0x8100}, {0x8800}, {0x8200}, {0x0300}, {0x8300}, {0x0400}, {0x8400}, {0x0500}, {0x8500}, {0x0600}, {0x8600}, {0x0700}, {0x8700}, {0x0800}, {0x8D01}, {0x8501}, {0x8E01}, {0x8601}, {0x8F01}, {0x8701}, {0x9001}, {0x8801}, {0x8101}, {0x8901}, {0x8201}, {0x8A01}, {0x8301}, {0x8B01}, {0x8401}, {0x8C01} }, @@ -121,40 +142,40 @@ xdf_sector_t xdf_disk_layout[2][2][38] = { { { {0x0100}, {0x0200}, {0x8100}, {0x /* First dimension is possible sector sizes (0 = 128, 7 = 16384), second is possible bit rates (250/360, 250, 300, 500/360, 500, 1000). */ /* Disks formatted at 250 kbps @ 360 RPM can be read with a 360 RPM single-RPM 5.25" drive by setting the rate to 250 kbps. Disks formatted at 300 kbps @ 300 RPM can be read with any 300 RPM single-RPM drive by setting the rate rate to 300 kbps. */ -static uint8_t maximum_sectors[8][6] = { { 26, 31, 38, 53, 64, 118 }, /* 128 */ - { 15, 19, 23, 32, 38, 73 }, /* 256 */ - { 7, 10, 12, 17, 22, 41 }, /* 512 */ - { 3, 5, 6, 9, 11, 22 }, /* 1024 */ - { 2, 2, 3, 4, 5, 11 }, /* 2048 */ - { 1, 1, 1, 2, 2, 5 }, /* 4096 */ +static const uint8_t maximum_sectors[8][6] = { { 26, 31, 38, 53, 64, 118 }, /* 128 */ + { 15, 19, 23, 32, 38, 73 }, /* 256 */ + { 7, 10, 12, 17, 22, 41 }, /* 512 */ + { 3, 5, 6, 9, 11, 22 }, /* 1024 */ + { 2, 2, 3, 4, 5, 11 }, /* 2048 */ + { 1, 1, 1, 2, 2, 5 }, /* 4096 */ { 0, 0, 0, 1, 1, 3 }, /* 8192 */ { 0, 0, 0, 0, 0, 1 } }; /* 16384 */ -static uint8_t xdf_sectors[8][6] = { { 0, 0, 0, 0, 0, 0 }, /* 128 */ - { 0, 0, 0, 0, 0, 0 }, /* 256 */ - { 0, 0, 0, 19, 23, 0 }, /* 512 */ - { 0, 0, 0, 0, 0, 0 }, /* 1024 */ - { 0, 0, 0, 0, 0, 0 }, /* 2048 */ - { 0, 0, 0, 0, 0, 0 }, /* 4096 */ +static const uint8_t xdf_sectors[8][6] = { { 0, 0, 0, 0, 0, 0 }, /* 128 */ + { 0, 0, 0, 0, 0, 0 }, /* 256 */ + { 0, 0, 0, 19, 23, 0 }, /* 512 */ + { 0, 0, 0, 0, 0, 0 }, /* 1024 */ + { 0, 0, 0, 0, 0, 0 }, /* 2048 */ + { 0, 0, 0, 0, 0, 0 }, /* 4096 */ { 0, 0, 0, 0, 0, 0 }, /* 8192 */ { 0, 0, 0, 0, 0, 0 } }; /* 16384 */ -static uint8_t xdf_types[8][6] = { { 0, 0, 0, 0, 0, 0 }, /* 128 */ - { 0, 0, 0, 0, 0, 0 }, /* 256 */ - { 0, 0, 0, 1, 2, 0 }, /* 512 */ - { 0, 0, 0, 0, 0, 0 }, /* 1024 */ - { 0, 0, 0, 0, 0, 0 }, /* 2048 */ - { 0, 0, 0, 0, 0, 0 }, /* 4096 */ +static const uint8_t xdf_types[8][6] = { { 0, 0, 0, 0, 0, 0 }, /* 128 */ + { 0, 0, 0, 0, 0, 0 }, /* 256 */ + { 0, 0, 0, 1, 2, 0 }, /* 512 */ + { 0, 0, 0, 0, 0, 0 }, /* 1024 */ + { 0, 0, 0, 0, 0, 0 }, /* 2048 */ + { 0, 0, 0, 0, 0, 0 }, /* 4096 */ { 0, 0, 0, 0, 0, 0 }, /* 8192 */ { 0, 0, 0, 0, 0, 0 } }; /* 16384 */ -static double bit_rates_300[6] = { (250.0 * 300.0) / 360.0, 250.0, 300.0, (500.0 * 300.0) / 360.0, 500.0, 1000.0 }; +static const double bit_rates_300[6] = { (250.0 * 300.0) / 360.0, 250.0, 300.0, (500.0 * 300.0) / 360.0, 500.0, 1000.0 }; -static uint8_t rates[6] = { 2, 2, 1, 4, 0, 3 }; +static const uint8_t rates[6] = { 2, 2, 1, 4, 0, 3 }; -static uint8_t holes[6] = { 0, 0, 0, 1, 1, 2 }; +static const uint8_t holes[6] = { 0, 0, 0, 1, 1, 2 }; -int gap3_sizes[5][8][48] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][0] */ +const int gap3_sizes[5][8][48] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][0] */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][1] */ @@ -275,911 +296,912 @@ int gap3_sizes[5][8][48] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }; -void img_writeback(int drive); -static int sector_size_code(int sector_size) +/* Generic */ +static int +sector_size_code(int sector_size) { - switch(sector_size) - { - case 128: - return 0; - case 256: - return 1; - default: - case 512: - return 2; - case 1024: - return 3; - case 2048: - return 4; - case 4096: - return 5; - case 8192: - return 6; - case 16384: - return 7; - } + switch(sector_size) { + case 128: + return(0); + + case 256: + return(1); + + default: + case 512: + return(2); + + case 1024: + return(3); + + case 2048: + return(4); + + case 4096: + return(5); + + case 8192: + return(6); + + case 16384: + return(7); + } } -void img_init() + +static int +bps_is_valid(uint16_t bps) { - memset(img, 0, sizeof(img)); + int i; + + for (i = 0; i <= 8; i++) { + if (bps == (128 << i)) return(1); + } + + return(0); } -void d86f_register_img(int drive); -int bps_is_valid(uint16_t bps) +static int +first_byte_is_valid(uint8_t first_byte) { - int i; - for (i = 0; i <= 8; i++) - { - if (bps == (128 << i)) - { - return 1; - } - } - return 0; + switch(first_byte) { + case 0x60: + case 0xE9: + case 0xEB: + return(1); + + default: + break; + } + + return(0); } -int first_byte_is_valid(uint8_t first_byte) -{ - switch(first_byte) - { - case 0x60: - case 0xE9: - case 0xEB: - return 1; - default: - return 0; - } -} - -double bit_rate_300; - -wchar_t *ext; - -uint8_t first_byte, second_byte, third_byte, fourth_byte; - -/* This is hard-coded to 0 - if you really need to read those NT 3.1 Beta floppy images, change this to 1 and recompile the emulator. */ -uint8_t fdf_suppress_final_byte = 0; - -void img_load(int drive, wchar_t *fn) -{ - int size; - uint16_t bpb_bps; - uint16_t bpb_total; - uint8_t bpb_mid; /* Media type ID. */ - uint8_t bpb_sectors; - uint8_t bpb_sides; - int temp_rate; - uint8_t fdi, cqm, fdf; - int i; - uint16_t comment_len = 0; - int16_t block_len = 0; - uint32_t cur_pos = 0; - uint8_t rep_byte = 0; - uint8_t run = 0; - uint8_t real_run = 0; - uint8_t *bpos; - uint16_t track_bytes = 0; - uint8_t *literal; - int guess = 0; - - ext = plat_get_extension(fn); - - d86f_unregister(drive); - - writeprot[drive] = 0; - img[drive].f = plat_fopen(fn, L"rb+"); - if (!img[drive].f) - { - img[drive].f = plat_fopen(fn, L"rb"); - if (!img[drive].f) - { - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - writeprot[drive] = 1; - } - if (ui_writeprot[drive]) - { - writeprot[drive] = 1; - } - fwriteprot[drive] = writeprot[drive]; - - fdi = cqm = 0; - - img[drive].interleave = img[drive].skew = 0; - - if (! wcscasecmp(ext, L"FDI")) - { - /* This is a Japanese FDI image, so let's read the header */ - pclog("img_load(): File is a Japanese FDI image...\n"); - fseek(img[drive].f, 0x10, SEEK_SET); - fread(&bpb_bps, 1, 2, img[drive].f); - fseek(img[drive].f, 0x0C, SEEK_SET); - fread(&size, 1, 4, img[drive].f); - bpb_total = size / bpb_bps; - fseek(img[drive].f, 0x08, SEEK_SET); - fread(&(img[drive].base), 1, 4, img[drive].f); - fseek(img[drive].f, img[drive].base + 0x15, SEEK_SET); - bpb_mid = fgetc(img[drive].f); - if (bpb_mid < 0xF0) bpb_mid = 0xF0; - fseek(img[drive].f, 0x14, SEEK_SET); - bpb_sectors = fgetc(img[drive].f); - fseek(img[drive].f, 0x18, SEEK_SET); - bpb_sides = fgetc(img[drive].f); - - fseek(img[drive].f, img[drive].base, SEEK_SET); - first_byte = fgetc(img[drive].f); - - fdi = 1; - cqm = 0; - img[drive].disk_at_once = 0; - fdf = 0; - } - else - { - /* Read the first four bytes. */ - fseek(img[drive].f, 0x00, SEEK_SET); - first_byte = fgetc(img[drive].f); - fseek(img[drive].f, 0x01, SEEK_SET); - second_byte = fgetc(img[drive].f); - fseek(img[drive].f, 0x02, SEEK_SET); - third_byte = fgetc(img[drive].f); - fseek(img[drive].f, 0x03, SEEK_SET); - fourth_byte = fgetc(img[drive].f); - - if ((first_byte == 0x1A) && (second_byte == 'F') && (third_byte == 'D') && (fourth_byte == 'F')) - { - /* This is a FDF image. */ - pclog("img_load(): File is a FDF image...\n"); - fwriteprot[drive] = writeprot[drive] = 1; - fclose(img[drive].f); - img[drive].f = plat_fopen(fn, L"rb"); - - fdf = 1; - - cqm = 0; - img[drive].disk_at_once = 1; - - fseek(img[drive].f, 0x50, SEEK_SET); - fread(&img[drive].tracks, 1, 4, img[drive].f); - - /* Decode the entire file - pass 1, no write to buffer, determine length. */ - fseek(img[drive].f, 0x80, SEEK_SET); - size = 0; - track_bytes = 0; - bpos = img[drive].disk_data; - while(!feof(img[drive].f)) - { - if (!track_bytes) - { - /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ - first_byte = fgetc(img[drive].f); - fread(&track_bytes, 1, 2, img[drive].f); - pclog("Block header: %02X %04X ", first_byte, track_bytes); - /* Read the length of encoded data block. */ - fread(&track_bytes, 1, 2, img[drive].f); - pclog("%04X\n", track_bytes); - } - - if (feof(img[drive].f)) - { - break; - } - - if (first_byte == 0xFF) - { - break; - } - - if (first_byte) - { - run = fgetc(img[drive].f); - - /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ - track_bytes--; - - if (run & 0x80) - { - /* Repeat. */ - track_bytes--; - rep_byte = fgetc(img[drive].f); - } - else - { - /* Literal. */ - track_bytes -= (run & 0x7f); - literal = (uint8_t *) malloc(run & 0x7f); - fread(literal, 1, (run & 0x7f), img[drive].f); - free(literal); - } - size += (run & 0x7f); - if (!track_bytes) - { - size -= fdf_suppress_final_byte; - } - } - else - { - /* Literal block. */ - size += (track_bytes - fdf_suppress_final_byte); - literal = (uint8_t *) malloc(track_bytes); - fread(literal, 1, track_bytes, img[drive].f); - free(literal); - track_bytes = 0; - } - - if (feof(img[drive].f)) - { - break; - } - } - - /* Allocate the buffer. */ - img[drive].disk_data = (uint8_t *) malloc(size); - - /* Decode the entire file - pass 2, write to buffer. */ - fseek(img[drive].f, 0x80, SEEK_SET); - track_bytes = 0; - bpos = img[drive].disk_data; - while(!feof(img[drive].f)) - { - if (!track_bytes) - { - /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ - first_byte = fgetc(img[drive].f); - fread(&track_bytes, 1, 2, img[drive].f); - pclog("Block header: %02X %04X ", first_byte, track_bytes); - /* Read the length of encoded data block. */ - fread(&track_bytes, 1, 2, img[drive].f); - pclog("%04X\n", track_bytes); - } - - if (feof(img[drive].f)) - { - break; - } - - if (first_byte == 0xFF) - { - break; - } - - if (first_byte) - { - run = fgetc(img[drive].f); - real_run = (run & 0x7f); - - /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ - track_bytes--; - - if (run & 0x80) - { - /* Repeat. */ - track_bytes--; - if (!track_bytes) - { - real_run -= fdf_suppress_final_byte; - } - rep_byte = fgetc(img[drive].f); - if (real_run) - { - memset(bpos, rep_byte, real_run); - } - } - else - { - /* Literal. */ - track_bytes -= real_run; - literal = (uint8_t *) malloc(real_run); - fread(literal, 1, real_run, img[drive].f); - if (!track_bytes) - { - real_run -= fdf_suppress_final_byte; - } - if (run & 0x7f) - { - memcpy(bpos, literal, real_run); - } - free(literal); - } - bpos += real_run; - } - else - { - /* Literal block. */ - literal = (uint8_t *) malloc(track_bytes); - fread(literal, 1, track_bytes, img[drive].f); - memcpy(bpos, literal, track_bytes - fdf_suppress_final_byte); - free(literal); - bpos += (track_bytes - fdf_suppress_final_byte); - track_bytes = 0; - } - - if (feof(img[drive].f)) - { - break; - } - } - - first_byte = *img[drive].disk_data; - - bpb_bps = *(uint16_t *) (img[drive].disk_data + 0x0B); - bpb_total = *(uint16_t *) (img[drive].disk_data + 0x13); - bpb_mid = *(img[drive].disk_data + 0x15); - bpb_sectors = *(img[drive].disk_data + 0x18); - bpb_sides = *(img[drive].disk_data + 0x1A); - - /* Jump ahead to determine the image's geometry and finish the loading. */ - goto jump_if_fdf; - } - - if (((first_byte == 'C') && (second_byte == 'Q')) || ((first_byte == 'c') && (second_byte == 'q'))) - { - pclog("img_load(): File is a CopyQM image...\n"); - fwriteprot[drive] = writeprot[drive] = 1; - fclose(img[drive].f); - img[drive].f = plat_fopen(fn, L"rb"); - - fseek(img[drive].f, 0x03, SEEK_SET); - fread(&bpb_bps, 1, 2, img[drive].f); - /* fseek(img[drive].f, 0x0B, SEEK_SET); - fread(&bpb_total, 1, 2, img[drive].f); */ - fseek(img[drive].f, 0x10, SEEK_SET); - bpb_sectors = fgetc(img[drive].f); - fseek(img[drive].f, 0x12, SEEK_SET); - bpb_sides = fgetc(img[drive].f); - fseek(img[drive].f, 0x5B, SEEK_SET); - img[drive].tracks = fgetc(img[drive].f); - - bpb_total = ((uint16_t) bpb_sectors) * ((uint16_t) bpb_sides) * img[drive].tracks; - - fseek(img[drive].f, 0x74, SEEK_SET); - img[drive].interleave = fgetc(img[drive].f); - fseek(img[drive].f, 0x76, SEEK_SET); - img[drive].skew = fgetc(img[drive].f); - - img[drive].disk_data = (uint8_t *) malloc(((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); - memset(img[drive].disk_data, 0xf6, ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); - - fseek(img[drive].f, 0x6F, SEEK_SET); - fread(&comment_len, 1, 2, img[drive].f); - - fseek(img[drive].f, -1, SEEK_END); - size = ftell(img[drive].f) + 1; - - fseek(img[drive].f, 133 + comment_len, SEEK_SET); - - cur_pos = 0; - - while(!feof(img[drive].f)) - { - fread(&block_len, 1, 2, img[drive].f); - - if (!feof(img[drive].f)) - { - if (block_len < 0) - { - rep_byte = fgetc(img[drive].f); - block_len = -block_len; - if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) - { - block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; - memset(img[drive].disk_data + cur_pos, rep_byte, block_len); - break; - } - else - { - memset(img[drive].disk_data + cur_pos, rep_byte, block_len); - cur_pos += block_len; - } - } - else if (block_len > 0) - { - if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) - { - block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; - fread(img[drive].disk_data + cur_pos, 1, block_len, img[drive].f); - break; - } - else - { - fread(img[drive].disk_data + cur_pos, 1, block_len, img[drive].f); - cur_pos += block_len; - } - } - } - } - pclog("Finished reading CopyQM image data\n"); - - cqm = 1; - img[drive].disk_at_once = 1; - fdf = 0; - first_byte = *img[drive].disk_data; - } - else - { - img[drive].disk_at_once = 0; - /* Read the BPB */ - pclog("img_load(): File is a raw image...\n"); - fseek(img[drive].f, 0x0B, SEEK_SET); - fread(&bpb_bps, 1, 2, img[drive].f); - fseek(img[drive].f, 0x13, SEEK_SET); - fread(&bpb_total, 1, 2, img[drive].f); - fseek(img[drive].f, 0x15, SEEK_SET); - bpb_mid = fgetc(img[drive].f); - fseek(img[drive].f, 0x18, SEEK_SET); - bpb_sectors = fgetc(img[drive].f); - fseek(img[drive].f, 0x1A, SEEK_SET); - bpb_sides = fgetc(img[drive].f); - - cqm = 0; - } - - fseek(img[drive].f, -1, SEEK_END); - size = ftell(img[drive].f) + 1; - -jump_if_fdf: - img[drive].base = 0; - fdi = 0; - } - - img[drive].sides = 2; - img[drive].sector_size = 2; - - pclog("BPB reports %i sides and %i bytes per sector (%i sectors total)\n", bpb_sides, bpb_bps, bpb_total); - - guess = (bpb_sides < 1); - guess = guess || (bpb_sides > 2); - guess = guess || !bps_is_valid(bpb_bps); - guess = guess || !first_byte_is_valid(first_byte); - guess = guess || !fdd_get_check_bpb(drive); - guess = guess && !fdi; - guess = guess && !cqm; - - if (guess) - { - /* The BPB is giving us a wacky number of sides and/or bytes per sector, therefore it is most probably - not a BPB at all, so we have to guess the parameters from file size. */ - - if (size <= (160*1024)) { img[drive].sectors = 8; img[drive].tracks = 40; img[drive].sides = 1; } - else if (size <= (180*1024)) { img[drive].sectors = 9; img[drive].tracks = 40; img[drive].sides = 1; } - else if (size <= (315*1024)) { img[drive].sectors = 9; img[drive].tracks = 70; img[drive].sides = 1; } - else if (size <= (320*1024)) { img[drive].sectors = 8; img[drive].tracks = 40; } - else if (size <= (320*1024)) { img[drive].sectors = 8; img[drive].tracks = 40; } - else if (size <= (360*1024)) { img[drive].sectors = 9; img[drive].tracks = 40; } /*Double density*/ - else if (size <= (400*1024)) { img[drive].sectors = 10; img[drive].tracks = 80; img[drive].sides = 1; } /*DEC RX50*/ - else if (size <= (640*1024)) { img[drive].sectors = 8; img[drive].tracks = 80; } /*Double density 640k*/ - else if (size <= (720*1024)) { img[drive].sectors = 9; img[drive].tracks = 80; } /*Double density*/ - else if (size <= (800*1024)) { img[drive].sectors = 10; img[drive].tracks = 80; } /*Double density*/ - else if (size <= (880*1024)) { img[drive].sectors = 11; img[drive].tracks = 80; } /*Double density*/ - else if (size <= (960*1024)) { img[drive].sectors = 12; img[drive].tracks = 80; } /*Double density*/ - else if (size <= (1040*1024)) { img[drive].sectors = 13; img[drive].tracks = 80; } /*Double density*/ - else if (size <= (1120*1024)) { img[drive].sectors = 14; img[drive].tracks = 80; } /*Double density*/ - else if (size <= 1228800) { img[drive].sectors = 15; img[drive].tracks = 80; } /*High density 1.2MB*/ - else if (size <= 1261568) { img[drive].sectors = 8; img[drive].tracks = 77; img[drive].sector_size = 3; } /*High density 1.25MB Japanese format*/ - else if (size <= 1474560) { img[drive].sectors = 18; img[drive].tracks = 80; } /*High density (not supported by Tandy 1000)*/ - else if (size <= 1556480) { img[drive].sectors = 19; img[drive].tracks = 80; } /*High density (not supported by Tandy 1000)*/ - else if (size <= 1638400) { img[drive].sectors = 10; img[drive].tracks = 80; img[drive].sector_size = 3; } /*High density (not supported by Tandy 1000)*/ - else if (size <= 1720320) { img[drive].sectors = 21; img[drive].tracks = 80; } /*DMF format - used by Windows 95 */ - else if (size <= 1741824) { img[drive].sectors = 21; img[drive].tracks = 81; } - else if (size <= 1763328) { img[drive].sectors = 21; img[drive].tracks = 82; } - else if (size <= 1802240) { img[drive].sectors = 22; img[drive].tracks = 80; img[drive].sector_size = 3; } /*High density (not supported by Tandy 1000)*/ - else if (size == 1884160) { img[drive].sectors = 23; img[drive].tracks = 80; } /*XDF format - used by OS/2 Warp*/ - else if (size <= 2949120) { img[drive].sectors = 36; img[drive].tracks = 80; } /*E density*/ - else if (size <= 3194880) { img[drive].sectors = 39; img[drive].tracks = 80; } /*E density*/ - else if (size <= 3276800) { img[drive].sectors = 40; img[drive].tracks = 80; } /*E density*/ - else if (size <= 3358720) { img[drive].sectors = 41; img[drive].tracks = 80; } /*E density, maximum possible size*/ - else if (size <= 3440640) { img[drive].sectors = 42; img[drive].tracks = 80; } /*E density, maximum possible size*/ - /* else if (size <= 3440640) { img[drive].sectors = 21; img[drive].tracks = 80; img[drive].sector_size = 3; } */ /*High density (not supported by Tandy 1000)*/ - else if (size <= 3604480) { img[drive].sectors = 22; img[drive].tracks = 80; img[drive].sector_size = 3; } /*High density (not supported by Tandy 1000)*/ - else if (size <= 3610624) { img[drive].sectors = 41; img[drive].tracks = 86; } /*E density, maximum possible size*/ - else if (size <= 3698688) { img[drive].sectors = 42; img[drive].tracks = 86; } /*E density, maximum possible size*/ - else - { - pclog("Image is bigger than can fit on an ED floppy, ejecting...\n"); - fclose(img[drive].f); - img[drive].f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - - bpb_sides = img[drive].sides; - bpb_sectors = img[drive].sectors; - bpb_total = size >> (img[drive].sector_size + 7); - } - else - { - /* The BPB readings appear to be valid, so let's set the values. */ - if (fdi) - { - /* The image is a Japanese FDI, therefore we read the number of tracks from the header. */ - fseek(img[drive].f, 0x1C, SEEK_SET); - fread(&(img[drive].tracks), 1, 4, img[drive].f); - } - else - { - if (!cqm && !fdf) - { - /* Number of tracks = number of total sectors divided by sides times sectors per track. */ - img[drive].tracks = ((uint32_t) bpb_total) / (((uint32_t) bpb_sides) * ((uint32_t) bpb_sectors)); - } - } - /* The rest we just set directly from the BPB. */ - img[drive].sectors = bpb_sectors; - img[drive].sides = bpb_sides; - /* The sector size. */ - img[drive].sector_size = sector_size_code(bpb_bps); - - temp_rate = 0xFF; - } - - for (i = 0; i < 6; i++) - { - if ((img[drive].sectors <= maximum_sectors[img[drive].sector_size][i]) || (img[drive].sectors == xdf_sectors[img[drive].sector_size][i])) - { - bit_rate_300 = bit_rates_300[i]; - temp_rate = rates[i]; - img[drive].disk_flags = holes[i] << 1; - img[drive].xdf_type = (img[drive].sectors == xdf_sectors[img[drive].sector_size][i]) ? xdf_types[img[drive].sector_size][i] : 0; - if ((bit_rate_300 == 500.0) && (img[drive].sectors == 21) && (img[drive].sector_size == 2) && (img[drive].tracks >= 80) && (img[drive].tracks <= 82) && (img[drive].sides == 2)) - { - /* This is a DMF floppy, set the flag so we know to interleave the sectors. */ - img[drive].dmf = 1; - } - else - { - if ((bit_rate_300 == 500.0) && (img[drive].sectors == 22) && (img[drive].sector_size == 2) && (img[drive].tracks >= 80) && (img[drive].tracks <= 82) && (img[drive].sides == 2)) - { - /* This is marked specially because of the track flag (a RPM slow down is needed). */ - img[drive].interleave = 2; - } - img[drive].dmf = 0; - } - - pclog("Image parameters: bit rate 300: %f, temporary rate: %i, hole: %i, DMF: %i, XDF type: %i\n", bit_rate_300, temp_rate, img[drive].disk_flags >> 1, img[drive].dmf, img[drive].xdf_type); - break; - } - } - - if (temp_rate == 0xFF) - { - pclog("Image is bigger than can fit on an ED floppy, ejecting...\n"); - fclose(img[drive].f); - img[drive].f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - - img[drive].gap2_size = (temp_rate == 3) ? 41 : 22; - if (img[drive].dmf) - { - img[drive].gap3_size = 8; - } - else - { - img[drive].gap3_size = gap3_sizes[temp_rate][img[drive].sector_size][img[drive].sectors]; - } - if (!img[drive].gap3_size) - { - pclog("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41); - fclose(img[drive].f); - img[drive].f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - - img[drive].track_width = 0; - if (img[drive].tracks > 43) img[drive].track_width = 1; /* If the image has more than 43 tracks, then the tracks are thin (96 tpi). */ - if (img[drive].sides == 2) img[drive].disk_flags |= 8; /* If the has 2 sides, mark it as such. */ - if (img[drive].interleave == 2) - { - img[drive].interleave = 1; - img[drive].disk_flags |= 0x60; - } - - img[drive].track_flags = 0x08; /* IMG files are always assumed to be MFM-encoded. */ - img[drive].track_flags |= temp_rate & 3; /* Data rate. */ - if (temp_rate & 4) img[drive].track_flags |= 0x20; /* RPM. */ - - img[drive].is_cqm = cqm; - - pclog("Disk flags: %i, track flags: %i\n", img[drive].disk_flags, img[drive].track_flags); - - d86f_register_img(drive); - - drives[drive].seek = img_seek; - - d86f_common_handlers(drive); -} - -void img_close(int drive) -{ - d86f_unregister(drive); - if (img[drive].f) - { - fclose(img[drive].f); - img[drive].f = NULL; - } - if (img[drive].disk_data) - free(img[drive].disk_data); -} #define xdf_img_sector xdf_img_layout[current_xdft][!is_t0][sector] #define xdf_disk_sector xdf_disk_layout[current_xdft][!is_t0][array_sector] -int interleave(int sector, int skew, int track_spt) + +static int +interleave(int sector, int skew, int track_spt) { - uint32_t skewed_i = 0; - uint32_t adjusted_r = 0; + uint32_t skewed_i; + uint32_t adjusted_r; + uint32_t add = (track_spt & 1); + uint32_t adjust = (track_spt >> 1); - uint32_t add = (track_spt & 1); - uint32_t adjust = (track_spt >> 1); + skewed_i = (sector + skew) % track_spt; + adjusted_r = (skewed_i >> 1) + 1; + if (skewed_i & 1) + adjusted_r += (adjust + add); - skewed_i = (sector + skew) % track_spt; - adjusted_r = (skewed_i >> 1) + 1; - if (skewed_i & 1) - { - adjusted_r += (adjust + add); - } - - return adjusted_r; + return(adjusted_r); } -void img_seek(int drive, int track) + +static void +write_back(int drive) { - int side; - int current_xdft = img[drive].xdf_type - 1; + img_t *dev = img[drive]; + int ssize = 128 << ((int) dev->sector_size); + int side; - int read_bytes = 0; + if (dev->f == NULL) return; - uint8_t id[4] = { 0, 0, 0, 0 }; - - int is_t0, sector, current_pos, img_pos, sr, sside, total, array_sector, buf_side, buf_pos; - - int ssize = 128 << ((int) img[drive].sector_size); - uint32_t cur_pos = 0; - - if (!img[drive].f) - return; - - if (!img[drive].track_width && fdd_doublestep_40(drive)) - track /= 2; - - img[drive].track = track; - d86f_set_cur_track(drive, track); - - is_t0 = (track == 0) ? 1 : 0; - - if (!img[drive].disk_at_once) - { - fseek(img[drive].f, img[drive].base + (track * img[drive].sectors * ssize * img[drive].sides), SEEK_SET); - } - - for (side = 0; side < img[drive].sides; side++) - { - if (img[drive].disk_at_once) - { - cur_pos = (track * img[drive].sectors * ssize * img[drive].sides) + (side * img[drive].sectors * ssize); - memcpy(img[drive].track_data[side], img[drive].disk_data + cur_pos, img[drive].sectors * ssize); - } - else - { - read_bytes = fread(img[drive].track_data[side], 1, img[drive].sectors * ssize, img[drive].f); - if (read_bytes < (img[drive].sectors * ssize)) - { - memset(img[drive].track_data[side] + read_bytes, 0xf6, (img[drive].sectors * ssize) - read_bytes); - } - } - } - - d86f_reset_index_hole_pos(drive, 0); - d86f_reset_index_hole_pos(drive, 1); - - d86f_destroy_linked_lists(drive, 0); - d86f_destroy_linked_lists(drive, 1); - - if (track > img[drive].tracks) - { - d86f_zero_track(drive); - return; - } - - if (!img[drive].xdf_type || img[drive].is_cqm) - { - for (side = 0; side < img[drive].sides; side++) - { - current_pos = d86f_prepare_pretrack(drive, side, 0); - - for (sector = 0; sector < img[drive].sectors; sector++) - { - if (img[drive].is_cqm) - { - if (img[drive].interleave) - { - sr = interleave(sector, img[drive].skew, img[drive].sectors); - } - else - { - sr = sector + 1; - sr += img[drive].skew; - if (sr > img[drive].sectors) - { - sr -= img[drive].sectors; - } - } - } - else - { - if (img[drive].gap3_size < 68) - { - sr = interleave(sector, 1, img[drive].sectors); - } - else - { - sr = img[drive].dmf ? (dmf_r[sector]) : (sector + 1); - } - } - id[0] = track; - id[1] = side; - id[2] = sr; - id[3] = img[drive].sector_size; - 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]); - } - } - } - } - else - { - total = img[drive].sectors; - img_pos = 0; - sside = 0; - - /* Pass 1, get sector positions in the image. */ - for (sector = 0; sector < xdf_logical_sectors[current_xdft][!is_t0]; sector++) - { - if (is_t0) - { - img_pos = (sector % total) << 9; - sside = (sector >= total) ? 1 : 0; - } - - if (xdf_img_sector.word) - { - img[drive].sector_pos_side[xdf_img_sector.id.h][xdf_img_sector.id.r] = sside; - img[drive].sector_pos[xdf_img_sector.id.h][xdf_img_sector.id.r] = img_pos; - } - - if (!is_t0) - { - img_pos += (128 << (xdf_img_sector.id.r & 7)); - if (img_pos >= (total << 9)) sside = 1; - img_pos %= (total << 9); - } - } - - /* Pass 2, prepare the actual track. */ - for (side = 0; side < img[drive].sides; side++) - { - current_pos = d86f_prepare_pretrack(drive, side, 0); - - for (sector = 0; sector < xdf_physical_sectors[current_xdft][!is_t0]; sector++) - { - array_sector = (side * xdf_physical_sectors[current_xdft][!is_t0]) + sector; - - buf_side = img[drive].sector_pos_side[xdf_disk_sector.id.h][xdf_disk_sector.id.r]; - buf_pos = img[drive].sector_pos[xdf_disk_sector.id.h][xdf_disk_sector.id.r]; - - id[0] = track; - id[1] = xdf_disk_sector.id.h; - id[2] = xdf_disk_sector.id.r; - - if (is_t0) - { - id[3] = 2; - current_pos = d86f_prepare_sector(drive, side, current_pos, id, &img[drive].track_data[buf_side][buf_pos], ssize, img[drive].gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0, 0); - } - else - { - id[3] = id[2] & 7; - 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]); - } - } - } - } + if (dev->disk_at_once) return; + + fseek(dev->f, dev->base + (dev->track * dev->sectors * ssize * dev->sides), SEEK_SET); + for (side = 0; side < dev->sides; side++) + fwrite(dev->track_data[side], dev->sectors * ssize, 1, dev->f); } -void img_writeback(int drive) + +static uint16_t +disk_flags(int drive) { - int side; - int ssize = 128 << ((int) img[drive].sector_size); + img_t *dev = img[drive]; - if (!img[drive].f) - return; + return(dev->disk_flags); +} - if (img[drive].disk_at_once) - return; - - fseek(img[drive].f, img[drive].base + (img[drive].track * img[drive].sectors * ssize * img[drive].sides), SEEK_SET); - for (side = 0; side < img[drive].sides; side++) - { - fwrite(img[drive].track_data[side], img[drive].sectors * ssize, 1, img[drive].f); + +static uint16_t +side_flags(int drive) +{ + img_t *dev = img[drive]; + + return(dev->track_flags); +} + + +static void +set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) +{ + img_t *dev = img[drive]; + + dev->current_sector_pos_side = dev->sector_pos_side[h][r]; + dev->current_sector_pos = dev->sector_pos[h][r]; +} + + +static uint8_t +poll_read_data(int drive, int side, uint16_t pos) +{ + img_t *dev = img[drive]; + + return(dev->track_data[dev->current_sector_pos_side][dev->current_sector_pos + pos]); +} + + +static void +poll_write_data(int drive, int side, uint16_t pos, uint8_t data) +{ + img_t *dev = img[drive]; + + dev->track_data[dev->current_sector_pos_side][dev->current_sector_pos + pos] = data; +} + + +static int +format_conditions(int drive) +{ + img_t *dev = img[drive]; + int temp = (fdc_get_format_sectors(img_fdc) == dev->sectors); + + temp = temp && (fdc_get_format_n(img_fdc) == dev->sector_size); + temp = temp && (dev->xdf_type == 0); + + return(temp); +} + + +static void +img_seek(int drive, int track) +{ + img_t *dev = img[drive]; + int side; + int current_xdft = dev->xdf_type - 1; + int read_bytes = 0; + uint8_t id[4] = { 0, 0, 0, 0 }; + int is_t0, sector, current_pos, img_pos, sr, sside, total, array_sector, buf_side, buf_pos; + int ssize = 128 << ((int) dev->sector_size); + uint32_t cur_pos = 0; + + if (dev->f == NULL) return; + + if (!dev->track_width && fdd_doublestep_40(drive)) + track /= 2; + + dev->track = track; + d86f_set_cur_track(drive, track); + + is_t0 = (track == 0) ? 1 : 0; + + if (! dev->disk_at_once) + fseek(dev->f, dev->base + (track * dev->sectors * ssize * dev->sides), SEEK_SET); + + for (side = 0; side < dev->sides; side++) { + if (dev->disk_at_once) { + cur_pos = (track * dev->sectors * ssize * dev->sides) + (side * dev->sectors * ssize); + memcpy(dev->track_data[side], dev->disk_data + cur_pos, dev->sectors * ssize); + } else { + read_bytes = fread(dev->track_data[side], 1, dev->sectors * ssize, dev->f); + if (read_bytes < (dev->sectors * ssize)) + memset(dev->track_data[side] + read_bytes, 0xf6, (dev->sectors * ssize) - read_bytes); } -} + } -int img_xdf_type(int drive) -{ - return img[drive].xdf_type; -} + d86f_reset_index_hole_pos(drive, 0); + d86f_reset_index_hole_pos(drive, 1); -uint16_t img_disk_flags(int drive) -{ - return img[drive].disk_flags; -} + d86f_destroy_linked_lists(drive, 0); + d86f_destroy_linked_lists(drive, 1); -uint16_t img_side_flags(int drive) -{ - return img[drive].track_flags; -} - -void img_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) -{ - img[drive].current_sector_pos_side = img[drive].sector_pos_side[h][r]; - img[drive].current_sector_pos = img[drive].sector_pos[h][r]; + if (track > dev->tracks) { + d86f_zero_track(drive); return; + } + + if (!dev->xdf_type || dev->is_cqm) { + for (side = 0; side < dev->sides; side++) { + current_pos = d86f_prepare_pretrack(drive, side, 0); + + for (sector = 0; sector < dev->sectors; sector++) { + if (dev->is_cqm) { + if (dev->interleave) + sr = interleave(sector, dev->skew, dev->sectors); + else { + sr = sector + 1; + sr += dev->skew; + if (sr > dev->sectors) + sr -= dev->sectors; + } + } else { + if (dev->gap3_size < 68) + sr = interleave(sector, 1, dev->sectors); + else + sr = dev->dmf ? (dmf_r[sector]) : (sector + 1); + } + id[0] = track; + id[1] = side; + id[2] = sr; + id[3] = dev->sector_size; + dev->sector_pos_side[side][sr] = side; + dev->sector_pos[side][sr] = (sr - 1) * ssize; + current_pos = d86f_prepare_sector(drive, side, current_pos, id, &dev->track_data[side][(sr - 1) * ssize], ssize, dev->gap2_size, dev->gap3_size, 0, 0); + + if (sector == 0) + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + } + } + } else { + total = dev->sectors; + img_pos = 0; + sside = 0; + + /* Pass 1, get sector positions in the image. */ + for (sector = 0; sector < xdf_logical_sectors[current_xdft][!is_t0]; sector++) { + if (is_t0) { + img_pos = (sector % total) << 9; + sside = (sector >= total) ? 1 : 0; + } + + if (xdf_img_sector.word) { + dev->sector_pos_side[xdf_img_sector.id.h][xdf_img_sector.id.r] = sside; + dev->sector_pos[xdf_img_sector.id.h][xdf_img_sector.id.r] = img_pos; + } + + if (! is_t0) { + img_pos += (128 << (xdf_img_sector.id.r & 7)); + if (img_pos >= (total << 9)) sside = 1; + img_pos %= (total << 9); + } + } + + /* Pass 2, prepare the actual track. */ + for (side = 0; side < dev->sides; side++) { + current_pos = d86f_prepare_pretrack(drive, side, 0); + + for (sector = 0; sector < xdf_physical_sectors[current_xdft][!is_t0]; sector++) { + array_sector = (side * xdf_physical_sectors[current_xdft][!is_t0]) + sector; + buf_side = dev->sector_pos_side[xdf_disk_sector.id.h][xdf_disk_sector.id.r]; + buf_pos = dev->sector_pos[xdf_disk_sector.id.h][xdf_disk_sector.id.r]; + + id[0] = track; + id[1] = xdf_disk_sector.id.h; + id[2] = xdf_disk_sector.id.r; + + if (is_t0) { + id[3] = 2; + current_pos = d86f_prepare_sector(drive, side, current_pos, id, &dev->track_data[buf_side][buf_pos], ssize, dev->gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0, 0); + } else { + id[3] = id[2] & 7; + ssize = (128 << id[3]); + current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[current_xdft][array_sector], id, &dev->track_data[buf_side][buf_pos], ssize, dev->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]); + } + } + } } -uint8_t img_poll_read_data(int drive, int side, uint16_t pos) + +void +img_init(void) { - return img[drive].track_data[img[drive].current_sector_pos_side][img[drive].current_sector_pos + pos]; + memset(img, 0x00, sizeof(img)); } -void img_poll_write_data(int drive, int side, uint16_t pos, uint8_t data) + +void +img_load(int drive, wchar_t *fn) { - img[drive].track_data[img[drive].current_sector_pos_side][img[drive].current_sector_pos + pos] = data; + uint16_t bpb_bps; + uint16_t bpb_total; + uint8_t bpb_mid; /* Media type ID. */ + uint8_t bpb_sectors; + uint8_t bpb_sides; + uint8_t fdi, cqm, fdf; + uint16_t comment_len = 0; + int16_t block_len = 0; + uint32_t cur_pos = 0; + uint8_t rep_byte = 0; + uint8_t run = 0; + uint8_t real_run = 0; + uint8_t *bpos; + uint16_t track_bytes = 0; + uint8_t *literal; + img_t *dev; + int temp_rate; + int guess = 0; + int size; + int i; + + ext = plat_get_extension(fn); + + d86f_unregister(drive); + + writeprot[drive] = 0; + + /* Allocate a drive block. */ + dev = (img_t *)malloc(sizeof(img_t)); + memset(dev, 0x00, sizeof(img_t)); + + dev->f = plat_fopen(fn, L"rb+"); + if (dev->f == NULL) { + dev->f = plat_fopen(fn, L"rb"); + if (dev->f == NULL) { + free(dev); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } + writeprot[drive] = 1; + } + + if (ui_writeprot[drive]) + writeprot[drive] = 1; + fwriteprot[drive] = writeprot[drive]; + + fdi = cqm = 0; + + dev->interleave = dev->skew = 0; + + if (! wcscasecmp(ext, L"FDI")) { + /* This is a Japanese FDI image, so let's read the header */ + pclog("img_load(): File is a Japanese FDI image...\n"); + fseek(dev->f, 0x10, SEEK_SET); + (void)fread(&bpb_bps, 1, 2, dev->f); + fseek(dev->f, 0x0C, SEEK_SET); + (void)fread(&size, 1, 4, dev->f); + bpb_total = size / bpb_bps; + fseek(dev->f, 0x08, SEEK_SET); + (void)fread(&(dev->base), 1, 4, dev->f); + fseek(dev->f, dev->base + 0x15, SEEK_SET); + bpb_mid = fgetc(dev->f); + if (bpb_mid < 0xF0) + bpb_mid = 0xF0; + fseek(dev->f, 0x14, SEEK_SET); + bpb_sectors = fgetc(dev->f); + fseek(dev->f, 0x18, SEEK_SET); + bpb_sides = fgetc(dev->f); + fseek(dev->f, dev->base, SEEK_SET); + first_byte = fgetc(dev->f); + + fdi = 1; + cqm = 0; + dev->disk_at_once = 0; + fdf = 0; + } else { + /* Read the first four bytes. */ + fseek(dev->f, 0x00, SEEK_SET); + first_byte = fgetc(dev->f); + fseek(dev->f, 0x01, SEEK_SET); + second_byte = fgetc(dev->f); + fseek(dev->f, 0x02, SEEK_SET); + third_byte = fgetc(dev->f); + fseek(dev->f, 0x03, SEEK_SET); + fourth_byte = fgetc(dev->f); + + if ((first_byte == 0x1A) && (second_byte == 'F') && + (third_byte == 'D') && (fourth_byte == 'F')) { + /* This is a FDF image. */ + pclog("img_load(): File is a FDF image...\n"); + fwriteprot[drive] = writeprot[drive] = 1; + fclose(dev->f); + dev->f = plat_fopen(fn, L"rb"); + + fdf = 1; + cqm = 0; + dev->disk_at_once = 1; + + fseek(dev->f, 0x50, SEEK_SET); + (void)fread(&dev->tracks, 1, 4, dev->f); + + /* Decode the entire file - pass 1, no write to buffer, determine length. */ + fseek(dev->f, 0x80, SEEK_SET); + size = 0; + track_bytes = 0; + bpos = dev->disk_data; + while (! feof(dev->f)) { + if (! track_bytes) { + /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ + first_byte = fgetc(dev->f); + fread(&track_bytes, 1, 2, dev->f); + pclog("Block header: %02X %04X ", first_byte, track_bytes); + /* Read the length of encoded data block. */ + fread(&track_bytes, 1, 2, dev->f); + pclog("%04X\n", track_bytes); + } + + if (feof(dev->f)) break; + + if (first_byte == 0xFF) break; + + if (first_byte) { + run = fgetc(dev->f); + + /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ + track_bytes--; + + if (run & 0x80) { + /* Repeat. */ + track_bytes--; + rep_byte = fgetc(dev->f); + } else { + /* Literal. */ + track_bytes -= (run & 0x7f); + literal = (uint8_t *)malloc(run & 0x7f); + fread(literal, 1, (run & 0x7f), dev->f); + free(literal); + } + size += (run & 0x7f); + if (!track_bytes) + size -= fdf_suppress_final_byte; + } else { + /* Literal block. */ + size += (track_bytes - fdf_suppress_final_byte); + literal = (uint8_t *)malloc(track_bytes); + fread(literal, 1, track_bytes, dev->f); + free(literal); + track_bytes = 0; + } + + if (feof(dev->f)) break; + } + + /* Allocate the buffer. */ + dev->disk_data = (uint8_t *)malloc(size); + + /* Decode the entire file - pass 2, write to buffer. */ + fseek(dev->f, 0x80, SEEK_SET); + track_bytes = 0; + bpos = dev->disk_data; + while(! feof(dev->f)) { + if (! track_bytes) { + /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ + first_byte = fgetc(dev->f); + fread(&track_bytes, 1, 2, dev->f); + pclog("Block header: %02X %04X ", first_byte, track_bytes); + /* Read the length of encoded data block. */ + fread(&track_bytes, 1, 2, dev->f); + pclog("%04X\n", track_bytes); + } + + if (feof(dev->f)) break; + + if (first_byte == 0xFF) break; + + if (first_byte) { + run = fgetc(dev->f); + real_run = (run & 0x7f); + + /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ + track_bytes--; + + if (run & 0x80) { + /* Repeat. */ + track_bytes--; + if (! track_bytes) + real_run -= fdf_suppress_final_byte; + rep_byte = fgetc(dev->f); + if (real_run) + memset(bpos, rep_byte, real_run); + } else { + /* Literal. */ + track_bytes -= real_run; + literal = (uint8_t *) malloc(real_run); + fread(literal, 1, real_run, dev->f); + if (! track_bytes) + real_run -= fdf_suppress_final_byte; + if (run & 0x7f) + memcpy(bpos, literal, real_run); + free(literal); + } + bpos += real_run; + } else { + /* Literal block. */ + literal = (uint8_t *) malloc(track_bytes); + fread(literal, 1, track_bytes, dev->f); + memcpy(bpos, literal, track_bytes - fdf_suppress_final_byte); + free(literal); + bpos += (track_bytes - fdf_suppress_final_byte); + track_bytes = 0; + } + + if (feof(dev->f)) break; + } + + first_byte = *dev->disk_data; + + bpb_bps = *(uint16_t *)(dev->disk_data + 0x0B); + bpb_total = *(uint16_t *)(dev->disk_data + 0x13); + bpb_mid = *(dev->disk_data + 0x15); + bpb_sectors = *(dev->disk_data + 0x18); + bpb_sides = *(dev->disk_data + 0x1A); + + /* Jump ahead to determine the image's geometry. */ + goto jump_if_fdf; + } + + if (((first_byte == 'C') && (second_byte == 'Q')) || + ((first_byte == 'c') && (second_byte == 'q'))) { + pclog("img_load(): File is a CopyQM image...\n"); + fwriteprot[drive] = writeprot[drive] = 1; + fclose(dev->f); + dev->f = plat_fopen(fn, L"rb"); + + fseek(dev->f, 0x03, SEEK_SET); + fread(&bpb_bps, 1, 2, dev->f); +#if 0 + fseek(dev->f, 0x0B, SEEK_SET); + fread(&bpb_total, 1, 2, dev->f); +#endif + fseek(dev->f, 0x10, SEEK_SET); + bpb_sectors = fgetc(dev->f); + fseek(dev->f, 0x12, SEEK_SET); + bpb_sides = fgetc(dev->f); + fseek(dev->f, 0x5B, SEEK_SET); + dev->tracks = fgetc(dev->f); + + bpb_total = ((uint16_t)bpb_sectors) * ((uint16_t) bpb_sides) * dev->tracks; + + fseek(dev->f, 0x74, SEEK_SET); + dev->interleave = fgetc(dev->f); + fseek(dev->f, 0x76, SEEK_SET); + dev->skew = fgetc(dev->f); + + dev->disk_data = (uint8_t *) malloc(((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); + memset(dev->disk_data, 0xf6, ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); + + fseek(dev->f, 0x6F, SEEK_SET); + fread(&comment_len, 1, 2, dev->f); + + fseek(dev->f, -1, SEEK_END); + size = ftell(dev->f) + 1; + + fseek(dev->f, 133 + comment_len, SEEK_SET); + + cur_pos = 0; + + while(! feof(dev->f)) { + fread(&block_len, 1, 2, dev->f); + + if (! feof(dev->f)) { + if (block_len < 0) { + rep_byte = fgetc(dev->f); + block_len = -block_len; + if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) { + block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; + memset(dev->disk_data + cur_pos, rep_byte, block_len); + break; + } else { + memset(dev->disk_data + cur_pos, rep_byte, block_len); + cur_pos += block_len; + } + } else if (block_len > 0) { + if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) { + block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; + fread(dev->disk_data + cur_pos, 1, block_len, dev->f); + break; + } else { + fread(dev->disk_data + cur_pos, 1, block_len, dev->f); + cur_pos += block_len; + } + } + } + } + pclog("Finished reading CopyQM image data\n"); + + cqm = 1; + dev->disk_at_once = 1; + fdf = 0; + first_byte = *dev->disk_data; + } else { + dev->disk_at_once = 0; + /* Read the BPB */ + pclog("img_load(): File is a raw image...\n"); + fseek(dev->f, 0x0B, SEEK_SET); + fread(&bpb_bps, 1, 2, dev->f); + fseek(dev->f, 0x13, SEEK_SET); + fread(&bpb_total, 1, 2, dev->f); + fseek(dev->f, 0x15, SEEK_SET); + bpb_mid = fgetc(dev->f); + fseek(dev->f, 0x18, SEEK_SET); + bpb_sectors = fgetc(dev->f); + fseek(dev->f, 0x1A, SEEK_SET); + bpb_sides = fgetc(dev->f); + + cqm = 0; + } + + fseek(dev->f, -1, SEEK_END); + size = ftell(dev->f) + 1; + +jump_if_fdf: + dev->base = 0; + fdi = 0; + } + + dev->sides = 2; + dev->sector_size = 2; + + pclog("BPB reports %i sides and %i bytes per sector (%i sectors total)\n", + bpb_sides, bpb_bps, bpb_total); + + guess = (bpb_sides < 1); + guess = guess || (bpb_sides > 2); + guess = guess || !bps_is_valid(bpb_bps); + guess = guess || !first_byte_is_valid(first_byte); + guess = guess || !fdd_get_check_bpb(drive); + guess = guess && !fdi; + guess = guess && !cqm; + if (guess) { + /* + * The BPB is giving us a wacky number of sides and/or bytes + * per sector, therefore it is most probably not a BPB at all, + * so we have to guess the parameters from file size. + */ + if (size <= (160*1024)) { + dev->sectors = 8; + dev->tracks = 40; + dev->sides = 1; + } else if (size <= (180*1024)) { + dev->sectors = 9; + dev->tracks = 40; + dev->sides = 1; + } else if (size <= (315*1024)) { + dev->sectors = 9; + dev->tracks = 70; + dev->sides = 1; + } else if (size <= (320*1024)) { + dev->sectors = 8; + dev->tracks = 40; + } else if (size <= (320*1024)) { + dev->sectors = 8; + dev->tracks = 40; + } else if (size <= (360*1024)) { /*DD 360K*/ + dev->sectors = 9; + dev->tracks = 40; + } else if (size <= (400*1024)) { /*DEC RX50*/ + dev->sectors = 10; + dev->tracks = 80; + dev->sides = 1; + } else if (size <= (640*1024)) { /*DD 640K*/ + dev->sectors = 8; + dev->tracks = 80; + } else if (size <= (720*1024)) { /*DD 720K*/ + dev->sectors = 9; + dev->tracks = 80; + } else if (size <= (800*1024)) { /*DD*/ + dev->sectors = 10; + dev->tracks = 80; + } else if (size <= (880*1024)) { /*DD*/ + dev->sectors = 11; + dev->tracks = 80; + } else if (size <= (960*1024)) { /*DD*/ + dev->sectors = 12; + dev->tracks = 80; + } else if (size <= (1040*1024)) { /*DD*/ + dev->sectors = 13; + dev->tracks = 80; + } else if (size <= (1120*1024)) { /*DD*/ + dev->sectors = 14; + dev->tracks = 80; + } else if (size <= 1228800) { /*HD 1.2MB*/ + dev->sectors = 15; + dev->tracks = 80; + } else if (size <= 1261568) { /*HD 1.25MB Japanese*/ + dev->sectors = 8; + dev->tracks = 77; + dev->sector_size = 3; + } else if (size <= 1474560) { /*HD 1.44MB*/ + dev->sectors = 18; + dev->tracks = 80; + } else if (size <= 1556480) { /*HD*/ + dev->sectors = 19; + dev->tracks = 80; + } else if (size <= 1638400) { /*HD 1024 sector*/ + dev->sectors = 10; + dev->tracks = 80; + dev->sector_size = 3; + } else if (size <= 1720320) { /*DMF (Windows 95) */ + dev->sectors = 21; + dev->tracks = 80; + } else if (size <= 1741824) { + dev->sectors = 21; + dev->tracks = 81; + } else if (size <= 1763328) { + dev->sectors = 21; + dev->tracks = 82; + } else if (size <= 1802240) { /*HD 1024 sector*/ + dev->sectors = 22; + dev->tracks = 80; + dev->sector_size = 3; + } else if (size == 1884160) { /*XDF (OS/2 Warp)*/ + dev->sectors = 23; + dev->tracks = 80; + } else if (size <= 2949120) { /*ED*/ + dev->sectors = 36; + dev->tracks = 80; + } else if (size <= 3194880) { /*ED*/ + dev->sectors = 39; + dev->tracks = 80; + } else if (size <= 3276800) { /*ED*/ + dev->sectors = 40; + dev->tracks = 80; + } else if (size <= 3358720) { /*ED, maximum possible size*/ + dev->sectors = 41; + dev->tracks = 80; + } else if (size <= 3440640) { /*ED, maximum possible size*/ + dev->sectors = 42; + dev->tracks = 80; +#if 0 + } else if (size <= 3440640) { /*HD 1024 sector*/ + dev->sectors = 21; + dev->tracks = 80; + dev->sector_size = 3; +#endif + } else if (size <= 3604480) { /*HD 1024 sector*/ + dev->sectors = 22; + dev->tracks = 80; + dev->sector_size = 3; + } else if (size <= 3610624) { /*ED, maximum possible size*/ + dev->sectors = 41; + dev->tracks = 86; + } else if (size <= 3698688) { /*ED, maximum possible size*/ + dev->sectors = 42; + dev->tracks = 86; + } else { + pclog("Image is bigger than can fit on an ED floppy, ejecting...\n"); + fclose(dev->f); + free(dev); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } + + bpb_sides = dev->sides; + bpb_sectors = dev->sectors; + bpb_total = size >> (dev->sector_size + 7); + } else { + /* The BPB readings appear to be valid, so let's set the values. */ + if (fdi) { + /* The image is a Japanese FDI, therefore we read the number of tracks from the header. */ + fseek(dev->f, 0x1C, SEEK_SET); + fread(&(dev->tracks), 1, 4, dev->f); + } else { + if (!cqm && !fdf) { + /* Number of tracks = number of total sectors divided by sides times sectors per track. */ + dev->tracks = ((uint32_t) bpb_total) / (((uint32_t) bpb_sides) * ((uint32_t) bpb_sectors)); + } + } + + /* The rest we just set directly from the BPB. */ + dev->sectors = bpb_sectors; + dev->sides = bpb_sides; + + /* The sector size. */ + dev->sector_size = sector_size_code(bpb_bps); + + temp_rate = 0xFF; + } + + for (i = 0; i < 6; i++) { + if ((dev->sectors <= maximum_sectors[dev->sector_size][i]) || (dev->sectors == xdf_sectors[dev->sector_size][i])) { + bit_rate_300 = bit_rates_300[i]; + temp_rate = rates[i]; + dev->disk_flags = holes[i] << 1; + dev->xdf_type = (dev->sectors == xdf_sectors[dev->sector_size][i]) ? xdf_types[dev->sector_size][i] : 0; + if ((bit_rate_300 == 500.0) && (dev->sectors == 21) && (dev->sector_size == 2) && (dev->tracks >= 80) && (dev->tracks <= 82) && (dev->sides == 2)) { + /* This is a DMF floppy, set the flag so we know to interleave the sectors. */ + dev->dmf = 1; + } else { + if ((bit_rate_300 == 500.0) && (dev->sectors == 22) && (dev->sector_size == 2) && (dev->tracks >= 80) && (dev->tracks <= 82) && (dev->sides == 2)) { + /* This is marked specially because of the track flag (a RPM slow down is needed). */ + dev->interleave = 2; + } + dev->dmf = 0; + } + + pclog("Image parameters: bit rate 300: %f, temporary rate: %i, hole: %i, DMF: %i, XDF type: %i\n", bit_rate_300, temp_rate, dev->disk_flags >> 1, dev->dmf, dev->xdf_type); + break; + } + } + + if (temp_rate == 0xFF) { + pclog("Image is bigger than can fit on an ED floppy, ejecting...\n"); + fclose(dev->f); + free(dev); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } + + dev->gap2_size = (temp_rate == 3) ? 41 : 22; + if (dev->dmf) + dev->gap3_size = 8; + else + dev->gap3_size = gap3_sizes[temp_rate][dev->sector_size][dev->sectors]; + if (! dev->gap3_size) { + pclog("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41); + fclose(dev->f); + free(dev); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } + + dev->track_width = 0; + if (dev->tracks > 43) + dev->track_width = 1; /* If the image has more than 43 tracks, then the tracks are thin (96 tpi). */ + if (dev->sides == 2) + dev->disk_flags |= 8; /* If the has 2 sides, mark it as such. */ + if (dev->interleave == 2) { + dev->interleave = 1; + dev->disk_flags |= 0x60; + } + + dev->track_flags = 0x08; /* IMG files are always assumed to be MFM-encoded. */ + dev->track_flags |= temp_rate & 3; /* Data rate. */ + if (temp_rate & 4) + dev->track_flags |= 0x20; /* RPM. */ + + dev->is_cqm = cqm; + + pclog("Disk flags: %i, track flags: %i\n", + dev->disk_flags, dev->track_flags); + + /* Set up the drive unit. */ + img[drive] = dev; + + /* Attach this format to the D86F engine. */ + d86f_handler[drive].disk_flags = disk_flags; + d86f_handler[drive].side_flags = side_flags; + d86f_handler[drive].writeback = write_back; + d86f_handler[drive].set_sector = set_sector; + d86f_handler[drive].read_data = poll_read_data; + d86f_handler[drive].write_data = poll_write_data; + d86f_handler[drive].format_conditions = format_conditions; + d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; + d86f_handler[drive].encoded_data = common_encoded_data; + d86f_handler[drive].read_revolution = common_read_revolution; + 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); + + drives[drive].seek = img_seek; + + d86f_common_handlers(drive); } -int img_format_conditions(int drive) + +void +img_close(int drive) { - int temp = (fdc_get_format_sectors(img_fdc) == img[drive].sectors); - temp = temp && (fdc_get_format_n(img_fdc) == img[drive].sector_size); - temp = temp && (img[drive].xdf_type == 0); - return temp; + img_t *dev = img[drive]; + + if (dev == NULL) return; + + d86f_unregister(drive); + + if (dev->f != NULL) { + fclose(dev->f); + dev->f = NULL; + } + + if (dev->disk_data != NULL) + free(dev->disk_data); + + /* Release the memory. */ + free(dev); + img[drive] = NULL; } -void img_set_fdc(void *fdc) -{ - img_fdc = (fdc_t *) fdc; -} -void d86f_register_img(int drive) +void +img_set_fdc(void *fdc) { - d86f_handler[drive].disk_flags = img_disk_flags; - 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; - d86f_handler[drive].encoded_data = common_encoded_data; - d86f_handler[drive].read_revolution = common_read_revolution; - 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); + img_fdc = (fdc_t *) fdc; } diff --git a/src/floppy/fdd_img.h b/src/floppy/fdd_img.h index 1eba453..b5bddb4 100644 --- a/src/floppy/fdd_img.h +++ b/src/floppy/fdd_img.h @@ -9,11 +9,13 @@ * Implementation of the raw sector-based floppy image format, * as well as the Japanese FDI, CopyQM, and FDF formats. * - * Version: @(#)floppy_img.h 1.0.1 2018/02/14 + * Version: @(#)floppy_img.h 1.0.2 2018/03/17 * - * Authors: Miran Grca, + * Authors: Fred N. van Kempen, + * Miran Grca, * Sarah Walker, * + * Copyright 2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. * Copyright 2008-2018 Sarah Walker. * @@ -39,10 +41,9 @@ # define EMU_FLOPPY_IMG_H -extern void img_init(void); -extern void img_load(int drive, wchar_t *fn); -extern void img_close(int drive); -extern void img_seek(int drive, int track); +extern void img_init(void); +extern void img_load(int drive, wchar_t *fn); +extern void img_close(int drive); #endif /*EMU_FLOPPY_IMG_H*/ diff --git a/src/floppy/fdd_json.c b/src/floppy/fdd_json.c index c9758a8..550aed9 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.3 2018/03/14 + * Version: @(#)fdd_json.c 1.0.4 2018/03/17 * * Author: Fred N. van Kempen, * @@ -101,11 +101,11 @@ typedef struct { } json_t; -static json_t images[FDD_NUM]; +static json_t *images[FDD_NUM]; static void -handle(json_t *img, char *name, char *str) +handle(json_t *dev, char *name, char *str) { sector_t *sec = NULL; uint32_t l, pat; @@ -114,7 +114,7 @@ handle(json_t *img, char *name, char *str) int i, s; /* Point to the currently selected sector. */ - sec = &img->sects[img->track][img->side][img->dmf-1]; + sec = &dev->sects[dev->track][dev->side][dev->dmf-1]; /* If no name given, assume sector is done. */ if (name == NULL) { @@ -128,8 +128,8 @@ handle(json_t *img, char *name, char *str) sec->size = fdd_sector_size_code(sec->size); /* Set up the rest of the Sector ID. */ - sec->track = img->track; - sec->side = img->side; + sec->track = dev->track; + sec->side = dev->side; return; } @@ -189,13 +189,13 @@ unexpect(int c, int state, int level) static int -load_image(json_t *img) +load_image(json_t *dev) { char buff[4096], name[32]; int c, i, j, state, level; char *ptr; - if (img->f == NULL) { + if (dev->f == NULL) { pclog("JSON: no file loaded!\n"); return(0); } @@ -203,17 +203,17 @@ load_image(json_t *img) /* Initialize. */ for (i=0; isects[i][j], 0x00, sizeof(sector_t)); + memset(dev->sects[i][j], 0x00, sizeof(sector_t)); } - img->track = img->side = img->dmf = 0; /* "dmf" is "sector#" */ + dev->track = dev->side = dev->dmf = 0; /* "dmf" is "sector#" */ /* Now run the state machine. */ ptr = NULL; level = state = 0; while (state >= 0) { /* Get a character from the input. */ - c = fgetc(img->f); - if ((c == EOF) || ferror(img->f)) { + c = fgetc(dev->f); + if ((c == EOF) || ferror(dev->f)) { state = -1; break; } @@ -221,7 +221,7 @@ load_image(json_t *img) /* Process it. */ switch(state) { case 0: /* read level header */ - img->dmf = 1; + dev->dmf = 1; if (c != '[') { state = unexpect(c, state, level); } else { @@ -269,7 +269,7 @@ load_image(json_t *img) case ',': case '}': *ptr = '\0'; - handle(img, name, buff); + handle(dev, name, buff); if (c == '}') state = 7; /* done */ @@ -294,10 +294,10 @@ load_image(json_t *img) break; case 7: /* sector done */ - handle(img, NULL, NULL); + handle(dev, NULL, NULL); switch(c) { case ',': /* next sector */ - img->dmf++; + dev->dmf++; state = 1; break; @@ -327,14 +327,14 @@ load_image(json_t *img) default: state = unexpect(c, state, level); } - img->spt[img->track][img->side] = img->dmf; - img->side++; + dev->spt[dev->track][dev->side] = dev->dmf; + dev->side++; break; case 9: /* track done */ switch(c) { case ',': /* next track */ - img->side = 0; + dev->side = 0; state = 0; break; @@ -347,15 +347,15 @@ load_image(json_t *img) default: state = unexpect(c, state, level); } - img->track++; + dev->track++; break; } } /* Save derived values. */ - img->tracks = img->track; - img->sides = img->side; + dev->tracks = dev->track; + dev->sides = dev->side; return(1); } @@ -366,22 +366,22 @@ static void json_seek(int drive, int track) { uint8_t id[4] = { 0,0,0,0 }; - json_t *img = &images[drive]; + json_t *dev = images[drive]; int side, sector; int rate, gap2, gap3, pos; int ssize, rsec, asec; int interleave_type; - if (img->f == NULL) { + if (dev->f == NULL) { pclog("JSON: seek: no file loaded!\n"); return; } /* Allow for doublestepping tracks. */ - if (! img->track_width && fdd_doublestep_40(drive)) track /= 2; + if (! dev->track_width && fdd_doublestep_40(drive)) track /= 2; /* Set the new track. */ - img->track = track; + dev->track = track; d86f_set_cur_track(drive, track); /* Reset the 86F state machine. */ @@ -392,45 +392,45 @@ json_seek(int drive, int track) interleave_type = 0; - if (track > img->tracks) { + if (track > dev->tracks) { d86f_zero_track(drive); return; } - for (side=0; sidesides; side++) { + for (side=0; sidesides; side++) { /* Get transfer rate for this side. */ - rate = img->track_flags & 0x07; - if (!rate && (img->track_flags & 0x20)) rate = 4; + rate = dev->track_flags & 0x07; + if (!rate && (dev->track_flags & 0x20)) rate = 4; /* Get correct GAP3 value for this side. */ gap3 = fdd_get_gap3_size(rate, - img->sects[track][side][0].size, - img->spt[track][side]); + dev->sects[track][side][0].size, + dev->spt[track][side]); /* Get correct GAP2 value for this side. */ - gap2 = ((img->track_flags & 0x07) >= 3) ? 41 : 22; + gap2 = ((dev->track_flags & 0x07) >= 3) ? 41 : 22; pos = d86f_prepare_pretrack(drive, side, 0); - for (sector=0; sectorspt[track][side]; sector++) { + for (sector=0; sectorspt[track][side]; sector++) { if (interleave_type == 0) { - rsec = img->sects[track][side][sector].sector; + rsec = dev->sects[track][side][sector].sector; asec = sector; } else { rsec = fdd_dmf_r[sector]; - asec = img->interleave_ordered[rsec][side]; + asec = dev->interleave_ordered[rsec][side]; } id[0] = track; id[1] = side; id[2] = rsec; - if (img->sects[track][side][asec].size > 255) + if (dev->sects[track][side][asec].size > 255) perror("fdd_json.c: json_seek: sector size too big."); - id[3] = img->sects[track][side][asec].size & 0xff; - ssize = fdd_sector_code_size(img->sects[track][side][asec].size & 0xff); + id[3] = dev->sects[track][side][asec].size & 0xff; + ssize = fdd_sector_code_size(dev->sects[track][side][asec].size & 0xff); pos = d86f_prepare_sector( drive, side, pos, id, - img->sects[track][side][asec].data, + dev->sects[track][side][asec].data, ssize, gap2, gap3, 0, /*deleted flag*/ 0 /*bad_crc flag*/ @@ -446,38 +446,42 @@ json_seek(int drive, int track) static uint16_t disk_flags(int drive) { - return(images[drive].disk_flags); + json_t *dev = images[drive]; + + return(dev->disk_flags); } static uint16_t track_flags(int drive) { - return(images[drive].track_flags); + json_t *dev = images[drive]; + + return(dev->track_flags); } static void set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) { - json_t *img = &images[drive]; + json_t *dev = images[drive]; int i; - img->sector[side] = 0; + dev->sector[side] = 0; /* Make sure we are on the desired track. */ - if (c != img->track) return; + if (c != dev->track) return; /* Set the desired side. */ - img->side = side; + dev->side = side; /* Now loop over all sector ID's on this side to find our sector. */ - for (i=0; ispt[c][side]; i++) { - if ((img->sects[img->track][side][i].track == c) && - (img->sects[img->track][side][i].side == h) && - (img->sects[img->track][side][i].sector == r) && - (img->sects[img->track][side][i].size == n)) { - img->sector[side] = i; + for (i=0; ispt[c][side]; i++) { + if ((dev->sects[dev->track][side][i].track == c) && + (dev->sects[dev->track][side][i].side == h) && + (dev->sects[dev->track][side][i].sector == r) && + (dev->sects[dev->track][side][i].size == n)) { + dev->sector[side] = i; } } } @@ -486,10 +490,10 @@ set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) static uint8_t poll_read_data(int drive, int side, uint16_t pos) { - json_t *img = &images[drive]; - uint8_t sec = img->sector[side]; + json_t *dev = images[drive]; + uint8_t sec = dev->sector[side]; - return(img->sects[img->track][side][sec].data[pos]); + return(dev->sects[dev->track][side][sec].data[pos]); } @@ -503,21 +507,23 @@ json_init(void) void json_load(int drive, wchar_t *fn) { - json_t *img = &images[drive]; - sector_t *sec; double bit_rate; int temp_rate; + sector_t *sec; + json_t *dev; int i; /* Just in case- remove ourselves from 86F. */ d86f_unregister(drive); - /* Zap any old data. */ - memset(img, 0x00, sizeof(json_t)); + /* Allocate a drive block. */ + dev = (json_t *)malloc(sizeof(json_t)); + memset(dev, 0x00, sizeof(json_t)); /* Open the image file. */ - img->f = plat_fopen(fn, L"rb"); - if (img->f == NULL) { + dev->f = plat_fopen(fn, L"rb"); + if (dev->f == NULL) { + free(dev); memset(fn, 0x00, sizeof(wchar_t)); return; } @@ -525,66 +531,70 @@ json_load(int drive, wchar_t *fn) /* Our images are always RO. */ writeprot[drive] = 1; + /* Set up the drive unit. */ + images[drive] = dev; + /* Load all sectors from the image file. */ - if (! load_image(img)) { + if (! load_image(dev)) { pclog("JSON: failed to initialize\n"); - (void)fclose(img->f); - img->f = NULL; + (void)fclose(dev->f); + free(dev); + images[drive] = NULL; memset(fn, 0x00, sizeof(wchar_t)); return; } pclog("JSON(%d): %ls (%i tracks, %i sides, %i sectors)\n", - drive, fn, img->tracks, img->sides, img->spt[0][0]); + drive, fn, dev->tracks, dev->sides, dev->spt[0][0]); /* * If the image has more than 43 tracks, then * the tracks are thin (96 tpi). */ - img->track_width = (img->tracks > 43) ? 1 : 0; + dev->track_width = (dev->tracks > 43) ? 1 : 0; /* If the image has 2 sides, mark it as such. */ - img->disk_flags = 0x00; - if (img->sides == 2) - img->disk_flags |= 0x08; + dev->disk_flags = 0x00; + if (dev->sides == 2) + dev->disk_flags |= 0x08; /* JSON files are always assumed to be MFM-encoded. */ - img->track_flags = 0x08; + dev->track_flags = 0x08; - img->interleave = 0; + dev->interleave = 0; #if 0 - img->skew = 0; + dev->skew = 0; #endif temp_rate = 0xff; - sec = &img->sects[0][0][0]; + sec = &dev->sects[0][0][0]; for (i=0; i<6; i++) { - if (img->spt[0][0] > fdd_max_sectors[sec->size][i]) continue; + if (dev->spt[0][0] > fdd_max_sectors[sec->size][i]) continue; bit_rate = fdd_bit_rates_300[i]; temp_rate = fdd_rates[i]; - img->disk_flags |= (fdd_holes[i] << 1); + dev->disk_flags |= (fdd_holes[i] << 1); - if ((bit_rate == 500.0) && (img->spt[0][0] == 21) && - (sec->size == 2) && (img->tracks >= 80) && - (img->tracks <= 82) && (img->sides == 2)) { + if ((bit_rate == 500.0) && (dev->spt[0][0] == 21) && + (sec->size == 2) && (dev->tracks >= 80) && + (dev->tracks <= 82) && (dev->sides == 2)) { /* * This is a DMF floppy, set the flag so * we know to interleave the sectors. */ - img->dmf = 1; + dev->dmf = 1; } else { - if ((bit_rate == 500.0) && (img->spt[0][0] == 22) && - (sec->size == 2) && (img->tracks >= 80) && - (img->tracks <= 82) && (img->sides == 2)) { + if ((bit_rate == 500.0) && (dev->spt[0][0] == 22) && + (sec->size == 2) && (dev->tracks >= 80) && + (dev->tracks <= 82) && (dev->sides == 2)) { /* * This is marked specially because of the * track flag (a RPM slow down is needed). */ - img->interleave = 2; + dev->interleave = 2; } - img->dmf = 0; + dev->dmf = 0; } break; @@ -592,41 +602,44 @@ json_load(int drive, wchar_t *fn) if (temp_rate == 0xff) { pclog("JSON: invalid image (temp_rate=0xff)\n"); - (void)fclose(img->f); - img->f = NULL; + (void)fclose(dev->f); + dev->f = NULL; + free(dev); + images[drive] = NULL; memset(fn, 0x00, sizeof(wchar_t)); return; } - if (img->interleave == 2) { - img->interleave = 1; - img->disk_flags |= 0x60; + if (dev->interleave == 2) { + dev->interleave = 1; + dev->disk_flags |= 0x60; } - img->gap2_len = (temp_rate == 3) ? 41 : 22; - if (img->dmf) { - img->gap3_len = 8; - } else { - img->gap3_len = fdd_get_gap3_size(temp_rate,sec->size,img->spt[0][0]); - } + dev->gap2_len = (temp_rate == 3) ? 41 : 22; + if (dev->dmf) + dev->gap3_len = 8; + else + dev->gap3_len = fdd_get_gap3_size(temp_rate,sec->size,dev->spt[0][0]); - if (! img->gap3_len) { + if (! dev->gap3_len) { pclog("JSON: image of unknown format was inserted into drive %c:!\n", 'C'+drive); - (void)fclose(img->f); - img->f = NULL; + (void)fclose(dev->f); + dev->f = NULL; + free(dev); + images[drive] = NULL; memset(fn, 0x00, sizeof(wchar_t)); return; } - img->track_flags |= (temp_rate & 0x03); /* data rate */ + dev->track_flags |= (temp_rate & 0x03); /* data rate */ if (temp_rate & 0x04) - img->track_flags |= 0x20; /* RPM */ + dev->track_flags |= 0x20; /* RPM */ pclog(" disk_flags: 0x%02x, track_flags: 0x%02x, GAP3 length: %i\n", - img->disk_flags, img->track_flags, img->gap3_len); + dev->disk_flags, dev->track_flags, dev->gap3_len); pclog(" bit rate 300: %.2f, temporary rate: %i, hole: %i, DMF: %i\n", - bit_rate, temp_rate, (img->disk_flags >> 1), img->dmf); + bit_rate, temp_rate, (dev->disk_flags >> 1), dev->dmf); /* Set up handlers for 86F layer. */ d86f_handler[drive].disk_flags = disk_flags; @@ -654,26 +667,30 @@ json_load(int drive, wchar_t *fn) void json_close(int drive) { - json_t *img = &images[drive]; + json_t *dev = images[drive]; int t, h, s; + if (dev == NULL) return; + /* Unlink image from the system. */ d86f_unregister(drive); /* Release all the sector buffers. */ for (t=0; t<256; t++) { for (h=0; h<2; h++) { - memset(img->sects[t][h], 0x00, sizeof(sector_t)); + memset(dev->sects[t][h], 0x00, sizeof(sector_t)); for (s=0; s<256; s++) { - if (img->sects[t][h][s].data != NULL) - free(img->sects[t][h][s].data); - img->sects[t][h][s].data = NULL; + if (dev->sects[t][h][s].data != NULL) + free(dev->sects[t][h][s].data); + dev->sects[t][h][s].data = NULL; } } } - if (img->f != NULL) { - (void)fclose(img->f); - img->f = NULL; - } + if (dev->f != NULL) + (void)fclose(dev->f); + + /* Release the memory. */ + free(dev); + images[drive] = NULL; } diff --git a/src/floppy/fdd_json.h b/src/floppy/fdd_json.h index 58e5812..0df9dab 100644 --- a/src/floppy/fdd_json.h +++ b/src/floppy/fdd_json.h @@ -8,7 +8,7 @@ * * Definitions for the PCjs JSON floppy image format. * - * Version: @(#)floppy_json.h 1.0.1 2018/02/14 + * Version: @(#)floppy_json.h 1.0.2 2018/03/17 * * Author: Fred N. van Kempen, * @@ -48,10 +48,9 @@ # define EMU_FLOPPY_JSON_H -//extern void json_init(void); +extern void json_init(void); extern void json_load(int drive, wchar_t *fn); extern void json_close(int drive); -//extern void json_seek(int drive, int track); #endif /*EMU_FLOPPY_JSON_H*/ diff --git a/src/floppy/fdd_td0.c b/src/floppy/fdd_td0.c index 46d72ef..2693ecd 100644 --- a/src/floppy/fdd_td0.c +++ b/src/floppy/fdd_td0.c @@ -8,14 +8,20 @@ * * Implementation of the Teledisk floppy image format. * - * Version: @(#)fdd_td0.c 1.0.3 2018/03/14 + * Version: @(#)fdd_td0.c 1.0.4 2018/03/17 * - * Authors: Miran Grca, + * Authors: Fred N. van Kempen, + * Miran Grca, * Milodrag Milanovic, * Haruhiko OKUMURA, * Haruyasu YOSHIZAKI, * Kenji RIKITAKE, * + * Based on Japanese version 29-NOV-1988 + * LZSS coded by Haruhiko OKUMURA + * Adaptive Huffman Coding coded by Haruyasu YOSHIZAKI + * Edited and translated to English by Kenji RIKITAKE + * * Copyright 2016-2018 Miran Grca. * Copyright 2013-2018 Milodrag Milanovic. * Copyright 1988-2018 Haruhiko OKUMURA. @@ -40,19 +46,6 @@ * Boston, MA 02111-1307 * USA. */ -/********************************************************************* - - formats/td0_dsk.c - - TD0 disk images - -*********************************************************************/ -/* - * Based on Japanese version 29-NOV-1988 - * LZSS coded by Haruhiko OKUMURA - * Adaptive Huffman Coding coded by Haruyasu YOSHIZAKI - * Edited and translated to English by Kenji RIKITAKE - */ #include #include #include @@ -65,1204 +58,1164 @@ #include "fdc.h" -#define BUFSZ 512 /* new input buffer */ +#define BUFSZ 512 /* new input buffer */ +#define TD0_MAX_BUFSZ (1024UL*1024UL*4UL) /* LZSS Parameters */ - -#define N 4096 /* Size of string buffer */ -#define F 60 /* Size of look-ahead buffer */ -#define THRESHOLD 2 -#define NIL N /* End of tree's node */ - +#define N 4096 /* Size of string buffer */ +#define F 60 /* Size of look-ahead buffer */ +#define THRESHOLD 2 +#define NIL N /* End of tree's node */ /* Huffman coding parameters */ - -#define N_CHAR (256 - THRESHOLD + F) - /* character code (= 0..N_CHAR-1) */ -#define T (N_CHAR * 2 - 1) /* Size of table */ -#define R (T - 1) /* root position */ -#define MAX_FREQ 0x8000 +#define N_CHAR (256-THRESHOLD+F) /* code (= 0..N_CHAR-1) */ +#define T (N_CHAR*2-1) /* Size of table */ +#define R (T-1) /* root position */ +#define MAX_FREQ 0x8000 /* update when cumulative frequency */ /* reaches to this value */ typedef struct { - uint16_t r, - bufcnt,bufndx,bufpos, /* string buffer */ - /* the following to allow block reads from input in next_word() */ - ibufcnt,ibufndx; /* input buffer counters */ - uint8_t inbuf[BUFSZ]; /* input buffer */ + uint16_t r, + bufcnt,bufndx,bufpos, /* string buffer */ + /* the following to allow block reads + from input in next_word() */ + ibufcnt,ibufndx; /* input buffer counters */ + uint8_t inbuf[BUFSZ]; /* input buffer */ } tdlzhuf; -typedef struct -{ - FILE *fdd_file; - off_t fdd_file_offset; +typedef struct { + FILE *fdd_file; + off_t fdd_file_offset; - tdlzhuf tdctl; - uint8_t text_buf[N + F - 1]; - uint16_t freq[T + 1]; /* cumulative freq table */ + tdlzhuf tdctl; + uint8_t text_buf[N + F - 1]; + uint16_t freq[T + 1]; /* cumulative freq table */ -/* - * pointing parent nodes. - * area [T..(T + N_CHAR - 1)] are pointers for leaves - */ - int16_t prnt[T + N_CHAR]; + /* + * pointing parent nodes. + * area [T..(T + N_CHAR - 1)] are pointers for leaves + */ + int16_t prnt[T + N_CHAR]; - /* pointing children nodes (son[], son[] + 1)*/ - int16_t son[T]; + /* pointing children nodes (son[], son[] + 1)*/ + int16_t son[T]; - uint16_t getbuf; - uint8_t getlen; + uint16_t getbuf; + uint8_t getlen; } td0dsk_t; -typedef struct -{ - uint8_t track; - uint8_t head; - uint8_t sector; - uint8_t size; - uint8_t deleted; - uint8_t bad_crc; - uint8_t *data; +typedef struct { + uint8_t track; + uint8_t head; + uint8_t sector; + uint8_t size; + uint8_t deleted; + uint8_t bad_crc; + uint8_t *data; } td0_sector_t; -typedef struct -{ - FILE *f; +typedef struct { + FILE *f; - int tracks; - int track_width; - int sides; - uint16_t disk_flags; - uint16_t default_track_flags; - uint16_t side_flags[256][2]; - uint8_t track_in_file[256][2]; - td0_sector_t sects[256][2][256]; - uint8_t track_spt[256][2]; - uint8_t gap3_len; - uint16_t current_side_flags[2]; - int track; - int current_sector_index[2]; - uint8_t calculated_gap3_lengths[256][2]; - uint8_t xdf_ordered_pos[256][2]; - uint8_t interleave_ordered_pos[256][2]; + int tracks; + int track_width; + int sides; + uint16_t disk_flags; + uint16_t default_track_flags; + uint16_t side_flags[256][2]; + uint8_t track_in_file[256][2]; + td0_sector_t sects[256][2][256]; + uint8_t track_spt[256][2]; + uint8_t gap3_len; + uint16_t current_side_flags[2]; + int track; + int current_sector_index[2]; + uint8_t calculated_gap3_lengths[256][2]; + uint8_t xdf_ordered_pos[256][2]; + uint8_t interleave_ordered_pos[256][2]; + + uint8_t *imagebuf; + uint8_t *processed_buf; } td0_t; -td0_t td0[FDD_NUM]; - - -void fdd_image_read(int drive, char *buffer, uint32_t offset, uint32_t len) -{ - fseek(td0[drive].f, offset, SEEK_SET); - fread(buffer, 1, len, td0[drive].f); -} - -int td0_dsk_identify(int drive) -{ - char header[2]; - - fdd_image_read(drive, header, 0, 2); - if (header[0]=='T' && header[1]=='D') { - return 1; - } else if (header[0]=='t' && header[1]=='d') { - return 1; - } else { - return 0; - } -} - -int td0_state_data_read(td0dsk_t *state, uint8_t *buf, uint16_t size) -{ - uint32_t image_size = 0; - fseek(state->fdd_file, 0, SEEK_END); - image_size = ftell(state->fdd_file); - if (size > image_size - state->fdd_file_offset) { - size = (image_size - state->fdd_file_offset) & 0xffff; - } - fseek(state->fdd_file, state->fdd_file_offset, SEEK_SET); - fread(buf, 1, size, state->fdd_file); - state->fdd_file_offset += size; - return size; -} - /* * Tables for encoding/decoding upper 6 bits of * sliding dictionary pointer */ - -/* decoder table */ static const uint8_t d_code[256] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, - 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, - 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, - 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, - 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, - 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, - 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B, - 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F, - 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, - 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, - 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, - 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, + 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, + 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, + 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, + 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, + 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, + 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B, + 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F, + 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, + 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, + 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, + 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, }; static const uint8_t d_len[256] = { - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, }; -int td0_state_next_word(td0dsk_t *state) + +static td0_t *td0[FDD_NUM]; + + +static void +fdd_image_read(int drive, char *buffer, uint32_t offset, uint32_t len) { - if(state->tdctl.ibufndx >= state->tdctl.ibufcnt) - { - state->tdctl.ibufndx = 0; - state->tdctl.ibufcnt = td0_state_data_read(state, state->tdctl.inbuf,BUFSZ); - if(state->tdctl.ibufcnt == 0) - return(-1); - } - while (state->getlen <= 8) { /* typically reads a word at a time */ - state->getbuf |= state->tdctl.inbuf[state->tdctl.ibufndx++] << (8 - state->getlen); - state->getlen += 8; - } - return(0); + td0_t *dev = td0[drive]; + + fseek(dev->f, offset, SEEK_SET); + fread(buffer, 1, len, dev->f); } -int td0_state_GetBit(td0dsk_t *state) /* get one bit */ +static int +dsk_identify(int drive) { - int16_t i; - if(td0_state_next_word(state) < 0) + char header[2]; + + fdd_image_read(drive, header, 0, 2); + if (header[0]=='T' && header[1]=='D') + return(1); + else if (header[0]=='t' && header[1]=='d') + return(1); + + return(0); +} + + +static int +state_data_read(td0dsk_t *state, uint8_t *buf, uint16_t size) +{ + uint32_t image_size = 0; + + fseek(state->fdd_file, 0, SEEK_END); + image_size = ftell(state->fdd_file); + if (size > image_size - state->fdd_file_offset) + size = (image_size - state->fdd_file_offset) & 0xffff; + fseek(state->fdd_file, state->fdd_file_offset, SEEK_SET); + fread(buf, 1, size, state->fdd_file); + state->fdd_file_offset += size; + + return(size); +} + + +static int +state_next_word(td0dsk_t *state) +{ + if (state->tdctl.ibufndx >= state->tdctl.ibufcnt) { + state->tdctl.ibufndx = 0; + state->tdctl.ibufcnt = state_data_read(state, state->tdctl.inbuf,BUFSZ); + if (state->tdctl.ibufcnt == 0) return(-1); - i = state->getbuf; - state->getbuf <<= 1; - state->getlen--; - if(i < 0) - return(1); - else - return(0); + } + + while (state->getlen <= 8) { /* typically reads a word at a time */ + state->getbuf |= state->tdctl.inbuf[state->tdctl.ibufndx++] << (8 - state->getlen); + state->getlen += 8; + } + + return(0); } -int td0_state_GetByte(td0dsk_t *state) /* get a byte */ + +/* get one bit */ +static int +state_GetBit(td0dsk_t *state) { - uint16_t i; - if(td0_state_next_word(state) != 0) - return(-1); - i = state->getbuf; - state->getbuf <<= 8; - state->getlen -= 8; - i = i >> 8; - return((int) i); + int16_t i; + + if (state_next_word(state) < 0) + return(-1); + + i = state->getbuf; + state->getbuf <<= 1; + state->getlen--; + if (i < 0) + return(1); + + return(0); } +/* get a byte */ +static int +state_GetByte(td0dsk_t *state) +{ + uint16_t i; + + if (state_next_word(state) != 0) + return(-1); + + i = state->getbuf; + state->getbuf <<= 8; + state->getlen -= 8; + i = i >> 8; + + return((int) i); +} + /* initialize freq tree */ - -void td0_state_StartHuff(td0dsk_t *state) +static void +state_StartHuff(td0dsk_t *state) { - int i, j; + int i, j; - for (i = 0; i < N_CHAR; i++) { - state->freq[i] = 1; - state->son[i] = i + T; - state->prnt[i + T] = i; - } - i = 0; j = N_CHAR; - while (j <= R) { - state->freq[j] = state->freq[i] + state->freq[i + 1]; - state->son[j] = i; - state->prnt[i] = state->prnt[i + 1] = j; - i += 2; j++; - } - state->freq[T] = 0xffff; - state->prnt[R] = 0; + for (i = 0; i < N_CHAR; i++) { + state->freq[i] = 1; + state->son[i] = i + T; + state->prnt[i + T] = i; + } + i = 0; j = N_CHAR; + while (j <= R) { + state->freq[j] = state->freq[i] + state->freq[i + 1]; + state->son[j] = i; + state->prnt[i] = state->prnt[i + 1] = j; + i += 2; j++; + } + state->freq[T] = 0xffff; + state->prnt[R] = 0; } /* reconstruct freq tree */ - -void td0_state_reconst(td0dsk_t *state) +static void +state_reconst(td0dsk_t *state) { - int16_t i, j, k; - uint16_t f, l; + int16_t i, j, k; + uint16_t f, l; - /* halven cumulative freq for leaf nodes */ - j = 0; - for (i = 0; i < T; i++) { - if (state->son[i] >= T) { - state->freq[j] = (state->freq[i] + 1) / 2; - state->son[j] = state->son[i]; - j++; - } + /* halven cumulative freq for leaf nodes */ + j = 0; + for (i = 0; i < T; i++) { + if (state->son[i] >= T) { + state->freq[j] = (state->freq[i] + 1) / 2; + state->son[j] = state->son[i]; + j++; } - /* make a tree : first, connect children nodes */ - for (i = 0, j = N_CHAR; j < T; i += 2, j++) { - k = i + 1; - f = state->freq[j] = state->freq[i] + state->freq[k]; - for (k = j - 1; f < state->freq[k]; k--) {}; - k++; - l = (j - k) * 2; + } - /* movmem() is Turbo-C dependent - rewritten to memmove() by Kenji */ + /* make a tree : first, connect children nodes */ + for (i = 0, j = N_CHAR; j < T; i += 2, j++) { + k = i + 1; + f = state->freq[j] = state->freq[i] + state->freq[k]; + for (k = j - 1; f < state->freq[k]; k--) {}; + k++; + l = (j - k) * 2; - /* movmem(&freq[k], &freq[k + 1], l); */ - (void)memmove(&state->freq[k + 1], &state->freq[k], l); - state->freq[k] = f; - /* movmem(&son[k], &son[k + 1], l); */ - (void)memmove(&state->son[k + 1], &state->son[k], l); - state->son[k] = i; - } - /* connect parent nodes */ - for (i = 0; i < T; i++) { - if ((k = state->son[i]) >= T) { - state->prnt[k] = i; - } else { - state->prnt[k] = state->prnt[k + 1] = i; - } - } + memcpy(&state->freq[k + 1], &state->freq[k], l); + state->freq[k] = f; + memcpy(&state->son[k + 1], &state->son[k], l); + state->son[k] = i; + } + + /* connect parent nodes */ + for (i = 0; i < T; i++) { + if ((k = state->son[i]) >= T) + state->prnt[k] = i; + else + state->prnt[k] = state->prnt[k + 1] = i; + } } /* update freq tree */ - -void td0_state_update(td0dsk_t *state, int c) +static void +state_update(td0dsk_t *state, int c) { - int i, j, k, l; + int i, j, k, l; - if (state->freq[R] == MAX_FREQ) { - td0_state_reconst(state); + if (state->freq[R] == MAX_FREQ) + state_reconst(state); + + c = state->prnt[c + T]; + + /* do it until reaching the root */ + do { + k = ++state->freq[c]; + + /* swap nodes to keep the tree freq-ordered */ + if (k > state->freq[l = c + 1]) { + while (k > state->freq[++l]) {}; + l--; + state->freq[c] = state->freq[l]; + state->freq[l] = k; + + i = state->son[c]; + state->prnt[i] = l; + if (i < T) state->prnt[i + 1] = l; + + j = state->son[l]; + state->son[l] = i; + + state->prnt[j] = c; + if (j < T) state->prnt[j + 1] = c; + state->son[c] = j; + + c = l; } - c = state->prnt[c + T]; - do { - k = ++state->freq[c]; - - /* swap nodes to keep the tree freq-ordered */ - if (k > state->freq[l = c + 1]) { - while (k > state->freq[++l]) {}; - l--; - state->freq[c] = state->freq[l]; - state->freq[l] = k; - - i = state->son[c]; - state->prnt[i] = l; - if (i < T) state->prnt[i + 1] = l; - - j = state->son[l]; - state->son[l] = i; - - state->prnt[j] = c; - if (j < T) state->prnt[j + 1] = c; - state->son[c] = j; - - c = l; - } - } while ((c = state->prnt[c]) != 0); /* do it until reaching the root */ + } while ((c = state->prnt[c]) != 0); } -int16_t td0_state_DecodeChar(td0dsk_t *state) +static int16_t +state_DecodeChar(td0dsk_t *state) { - int ret; - uint16_t c; + int ret; + uint16_t c; - c = state->son[R]; + c = state->son[R]; - /* - * start searching tree from the root to leaves. - * choose node #(son[]) if input bit == 0 - * else choose #(son[]+1) (input bit == 1) - */ - while (c < T) { - if((ret = td0_state_GetBit(state)) < 0) - return(-1); - c += (unsigned) ret; - c = state->son[c]; - } - c -= T; - td0_state_update(state, c); - return c; -} - -int16_t td0_state_DecodePosition(td0dsk_t *state) -{ - int16_t bit; - uint16_t i, j, c; - - /* decode upper 6 bits from given table */ - if((bit=td0_state_GetByte(state)) < 0) + /* + * start searching tree from the root to leaves. + * choose node #(son[]) if input bit == 0 + * else choose #(son[]+1) (input bit == 1) + */ + while (c < T) { + if ((ret = state_GetBit(state)) < 0) return(-1); - i = (uint16_t) bit; - c = (uint16_t)d_code[i] << 6; - j = d_len[i]; + c += (unsigned) ret; + c = state->son[c]; + } + c -= T; - /* input lower 6 bits directly */ - j -= 2; - while (j--) { - if((bit = td0_state_GetBit(state)) < 0) - return(-1); - i = (i << 1) + bit; - } - return(c | (i & 0x3f)); -} + state_update(state, c); -/* DeCompression - -split out initialization code to init_Decode() - -*/ - -void td0_state_init_Decode(td0dsk_t *state) -{ - int i; - state->getbuf = 0; - state->getlen = 0; - state->tdctl.ibufcnt= state->tdctl.ibufndx = 0; /* input buffer is empty */ - state->tdctl.bufcnt = 0; - td0_state_StartHuff(state); - for (i = 0; i < N - F; i++) - state->text_buf[i] = ' '; - state->tdctl.r = N - F; + return(c); } -int td0_state_Decode(td0dsk_t *state, uint8_t *buf, int len) /* Decoding/Uncompressing */ +static int16_t +state_DecodePosition(td0dsk_t *state) { - int16_t c,pos; - int count; /* was an unsigned long, seems unnecessary */ - for (count = 0; count < len; ) { - if(state->tdctl.bufcnt == 0) { - if((c = td0_state_DecodeChar(state)) < 0) - return(count); /* fatal error */ - if (c < 256) { - *(buf++) = c & 0xff; - state->text_buf[state->tdctl.r++] = c & 0xff; - state->tdctl.r &= (N - 1); - count++; - } - else { - if((pos = td0_state_DecodePosition(state)) < 0) - return(count); /* fatal error */ - state->tdctl.bufpos = (state->tdctl.r - pos - 1) & (N - 1); - state->tdctl.bufcnt = c - 255 + THRESHOLD; - state->tdctl.bufndx = 0; - } - } - else { /* still chars from last string */ - while( state->tdctl.bufndx < state->tdctl.bufcnt && count < len ) { - c = state->text_buf[(state->tdctl.bufpos + state->tdctl.bufndx) & (N - 1)]; - *(buf++) = c & 0xff; - state->tdctl.bufndx++; - state->text_buf[state->tdctl.r++] = c & 0xff; - state->tdctl.r &= (N - 1); - count++; - } - /* reset bufcnt after copy string from text_buf[] */ - if(state->tdctl.bufndx >= state->tdctl.bufcnt) - state->tdctl.bufndx = state->tdctl.bufcnt = 0; - } - } - return(count); /* count == len, success */ + int16_t bit; + uint16_t i, j, c; + + /* decode upper 6 bits from given table */ + if ((bit = state_GetByte(state)) < 0) + return(-1); + + i = (uint16_t) bit; + c = (uint16_t)d_code[i] << 6; + j = d_len[i]; + + /* input lower 6 bits directly */ + j -= 2; + while (j--) { + if ((bit = state_GetBit(state)) < 0) + return(-1); + i = (i << 1) + bit; + } + + return(c | (i & 0x3f)); } -/********************************************************************* - - formats/td0_dsk.h - - Teledisk disk images - -*********************************************************************/ - -int td0_initialize(int drive); - -void td0_seek(int drive, int track); - -void td0_init() +/* DeCompression - split out initialization code to init_Decode() */ +static void +state_init_Decode(td0dsk_t *state) { - memset(td0, 0, sizeof(td0)); + int i; + + state->getbuf = 0; + state->getlen = 0; + state->tdctl.ibufcnt= state->tdctl.ibufndx = 0; /* input buffer is empty */ + state->tdctl.bufcnt = 0; + + state_StartHuff(state); + for (i = 0; i < N - F; i++) + state->text_buf[i] = ' '; + + state->tdctl.r = N - F; } -void d86f_register_td0(int drive); -const size_t max_size = 4*1024*1024; /* 4MB ought to be large enough for any floppy */ -const size_t max_processed_size = 5*1024*1024; -uint8_t imagebuf[4*1024*1024]; -uint8_t processed_buf[5*1024*1024]; -uint8_t header[12]; - -void td0_load(int drive, wchar_t *fn) +/* Decoding/Uncompressing */ +static int +state_Decode(td0dsk_t *state, uint8_t *buf, int len) { - int ret = 0; + int16_t c, pos; + int count; /* was an unsigned long, seems unnecessary */ - d86f_unregister(drive); + for (count = 0; count < len; ) { + if (state->tdctl.bufcnt == 0) { + if ((c = state_DecodeChar(state)) < 0) + return(count); /* fatal error */ + if (c < 256) { + *(buf++) = c & 0xff; + state->text_buf[state->tdctl.r++] = c & 0xff; + state->tdctl.r &= (N - 1); + count++; + } else { + if ((pos = state_DecodePosition(state)) < 0) + return(count); /* fatal error */ + state->tdctl.bufpos = (state->tdctl.r - pos - 1) & (N - 1); + state->tdctl.bufcnt = c - 255 + THRESHOLD; + state->tdctl.bufndx = 0; + } + } else { + /* still chars from last string */ + while (state->tdctl.bufndx < state->tdctl.bufcnt && count < len) { + c = state->text_buf[(state->tdctl.bufpos + state->tdctl.bufndx) & (N - 1)]; + *(buf++) = c & 0xff; + state->tdctl.bufndx++; + state->text_buf[state->tdctl.r++] = c & 0xff; + state->tdctl.r &= (N - 1); + count++; + } - writeprot[drive] = 1; - td0[drive].f = plat_fopen(fn, L"rb"); - if (!td0[drive].f) - { - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - fwriteprot[drive] = writeprot[drive]; - - ret = td0_dsk_identify(drive); - if (!ret) - { - pclog("TD0: Not a valid Teledisk image\n"); - fclose(td0[drive].f); - td0[drive].f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - else - { - pclog("TD0: Valid Teledisk image\n"); + /* reset bufcnt after copy string from text_buf[] */ + if (state->tdctl.bufndx >= state->tdctl.bufcnt) + state->tdctl.bufndx = state->tdctl.bufcnt = 0; } + } - memset(imagebuf, 0, 4*1024*1024); - memset(processed_buf, 0, 4*1024*1024); - ret = td0_initialize(drive); - if (!ret) - { - pclog("TD0: Failed to initialize\n"); - fclose(td0[drive].f); - td0[drive].f = NULL; - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - else - { - pclog("TD0: Initialized successfully\n"); - } - - d86f_register_td0(drive); - - drives[drive].seek = td0_seek; - - d86f_common_handlers(drive); + return(count); /* count == len, success */ } -void td0_close(int drive) -{ - int i = 0; - int j = 0; - int k = 0; - d86f_unregister(drive); - memset(imagebuf, 0, 4*1024*1024); - memset(processed_buf, 0, 4*1024*1024); - for (i = 0; i < 256; i++) - { - for (j = 0; j < 2; j++) - { - for (k = 0; k < 256; k++) - { - td0[drive].sects[i][j][k].data = NULL; +static uint32_t +get_raw_tsize(int side_flags, int slower_rpm) +{ + uint32_t size; + + switch(side_flags & 0x27) { + case 0x22: + size = slower_rpm ? 5314 : 5208; + break; + + default: + case 0x02: + case 0x21: + size = slower_rpm ? 6375 : 6250; + break; + + case 0x01: + size = slower_rpm ? 7650 : 7500; + break; + + case 0x20: + size = slower_rpm ? 10629 : 10416; + break; + + case 0x00: + size = slower_rpm ? 12750 : 12500; + break; + + case 0x23: + size = slower_rpm ? 21258 : 20833; + break; + + case 0x03: + size = slower_rpm ? 25500 : 25000; + break; + + case 0x25: + size = slower_rpm ? 42517 : 41666; + break; + + case 0x05: + size = slower_rpm ? 51000 : 50000; + break; + } + + return(size); +} + + +static int +td0_initialize(int drive) +{ + td0_t *dev = td0[drive]; + uint8_t header[12]; + int fm, head, track; + int track_count = 0; + int head_count = 0; + int track_spt; + int offset = 0; + int density = 0; + int temp_rate = 0; + uint32_t file_size; + uint16_t len, rep; + td0dsk_t disk_decode; + uint8_t *hs; + uint16_t size; + uint8_t *dbuf = dev->processed_buf; + uint32_t total_size = 0; + uint32_t pre_sector = 0; + uint32_t track_size = 0; + uint32_t raw_tsize = 0; + uint32_t minimum_gap3 = 0; + uint32_t minimum_gap4 = 0; + int i, j, k; + + if (dev->f == NULL) { + pclog("TD0: Attempted to initialize without loading a file first\n"); + return(0); + } + + fseek(dev->f, 0, SEEK_END); + file_size = ftell(dev->f); + + if (file_size < 12) { + pclog("TD0: File is too small to even contain the header\n"); + return(0); + } + + if (file_size > TD0_MAX_BUFSZ) { + pclog("TD0: File exceeds the maximum size\n"); + return(0); + } + + fseek(dev->f, 0, SEEK_SET); + fread(header, 1, 12, dev->f); + head_count = header[9]; + + if (header[0] == 't') { + pclog("TD0: File is compressed\n"); + disk_decode.fdd_file = dev->f; + state_init_Decode(&disk_decode); + disk_decode.fdd_file_offset = 12; + state_Decode(&disk_decode, dev->imagebuf, TD0_MAX_BUFSZ); + } else { + pclog("TD0: File is uncompressed\n"); + fseek(dev->f, 12, SEEK_SET); + fread(dev->imagebuf, 1, file_size - 12, dev->f); + } + + if (header[7] & 0x80) + offset = 10 + dev->imagebuf[2] + (dev->imagebuf[3] << 8); + + track_spt = dev->imagebuf[offset]; + if (track_spt == 255) { + /* Empty file? */ + pclog("TD0: File has no tracks\n"); + return(0); + } + + density = (header[5] >> 1) & 3; + + if (density == 3) { + pclog("TD0: Unknown density\n"); + return(0); + } + + /* + * We determine RPM from the drive type as well as we possibly can. + * This byte is actually the BIOS floppy drive type read by Teledisk + * from the CMOS. + */ + switch (header[6]) { + case 0: /* 5.25" 360k in 1.2M drive: 360 rpm + CMOS Drive type: None, value probably + reused by Teledisk */ + case 2: /* 5.25" 1.2M 360 rpm */ + case 5: /* 8"/5.25"/3.5" 1.25M 360 rpm */ + dev->default_track_flags = (density == 1) ? 0x20 : 0x21; + break; + + case 1: /* 5.25" 360k: 300 rpm */ + case 3: /* 3.5" 720k: 300 rpm */ + dev->default_track_flags = 0x02; + break; + + case 4: /* 3.5" 1.44M: 300 rpm */ + dev->default_track_flags = (density == 1) ? 0x00 : 0x02; + break; + + case 6: /* 3.5" 2.88M: 300 rpm */ + dev->default_track_flags = (density == 1) ? 0x00 : ((density == 2) ? 0x03 : 0x02); + break; + } + + dev->disk_flags = header[5] & 0x06; + + dev->track_width = (header[7] & 1) ^ 1; + + for (i = 0; i < 256; i++) { + memset(dev->side_flags[i], 0, 4); + memset(dev->track_in_file[i], 0, 2); + memset(dev->calculated_gap3_lengths[i], 0, 2); + for (j = 0; j < 2; j++) + memset(dev->sects[i][j], 0, sizeof(td0_sector_t)); + } + + while (track_spt != 255) { + track = dev->imagebuf[offset + 1]; + head = dev->imagebuf[offset + 2] & 1; + fm = (header[5] & 0x80) || (dev->imagebuf[offset + 2] & 0x80); /* ? */ + dev->side_flags[track][head] = dev->default_track_flags | (fm ? 0 : 8); + dev->track_in_file[track][head] = 1; + offset += 4; + track_size = fm ? 73 : 146; + pre_sector = fm ? 42 : 60; + + for (i = 0; i < track_spt; i++) { + hs = &dev->imagebuf[offset]; + offset += 6; + + dev->sects[track][head][i].track = hs[0]; + dev->sects[track][head][i].head = hs[1]; + dev->sects[track][head][i].sector = hs[2]; + dev->sects[track][head][i].size = hs[3]; + dev->sects[track][head][i].deleted = (hs[4] & 4) == 4; + dev->sects[track][head][i].bad_crc = (hs[4] & 2) == 2; + dev->sects[track][head][i].data = dbuf; + + size = 128 << hs[3]; + if ((total_size + size) >= TD0_MAX_BUFSZ) { + pclog("TD0: Processed buffer overflow\n"); + return(0); + } + + if (hs[4] & 0x30) { + memset(dbuf, 0, size); + } else { + offset += 3; + switch (hs[8]) { + default: + pclog("TD0: Image uses an unsupported sector data encoding\n"); + return(0); + + case 0: + memcpy(dbuf, &dev->imagebuf[offset], size); + offset += size; + break; + + case 1: + offset += 4; + k = (hs[9] + (hs[10] << 8)) * 2; + k = (k <= size) ? k : size; + for(j = 0; j < k; j += 2) { + dbuf[j] = hs[11]; + dbuf[j + 1] = hs[12]; + } + if (k < size) + memset(&(dbuf[k]), 0, size - k); + break; + + case 2: + k = 0; + while (k < size) { + len = dev->imagebuf[offset]; + rep = dev->imagebuf[offset + 1]; + offset += 2; + if (! len) { + memcpy(&(dbuf[k]), &dev->imagebuf[offset], rep); + offset += rep; + k += rep; + } else { + len = (1 << len); + rep = len * rep; + rep = ((rep + k) <= size) ? rep : (size - k); + for(j = 0; j < rep; j += len) + memcpy(&(dbuf[j + k]), &dev->imagebuf[offset], len); + k += rep; + offset += len; + } + } + break; } } + + dbuf += size; + total_size += size; + track_size += (pre_sector + size + 2); } - for (i = 0; i < 256; i++) - { - memset(td0[drive].side_flags[i], 0, 4); - memset(td0[drive].track_in_file[i], 0, 2); - memset(td0[drive].calculated_gap3_lengths[i], 0, 2); - for (j = 0; j < 2; j++) - { - memset(td0[drive].sects[i][j], 0, sizeof(td0_sector_t)); + track_count = track; + + if (track_spt != 255) { + dev->track_spt[track][head] = track_spt; + + if ((dev->track_spt[track][head] == 8) && (dev->sects[track][head][0].size == 3)) { + dev->side_flags[track][head] |= 0x20; } - } - if (td0[drive].f) - { - fclose(td0[drive].f); - td0[drive].f = NULL; - } -} - -uint32_t td0_get_raw_tsize(int side_flags, int slower_rpm) -{ - uint32_t size; - switch(side_flags & 0x27) - { - case 0x22: - size = slower_rpm ? 5314 : 5208; - break; - default: - case 0x02: - case 0x21: - size = slower_rpm ? 6375 : 6250; - break; - case 0x01: - size = slower_rpm ? 7650 : 7500; - break; - case 0x20: - size = slower_rpm ? 10629 : 10416; - break; - case 0x00: - size = slower_rpm ? 12750 : 12500; - break; - case 0x23: - size = slower_rpm ? 21258 : 20833; - break; - case 0x03: - size = slower_rpm ? 25500 : 25000; - break; - case 0x25: - size = slower_rpm ? 42517 : 41666; - break; - case 0x05: - size = slower_rpm ? 51000 : 50000; - break; - } - return size; -} - -int td0_initialize(int drive) -{ - int track; - int head; - int fm; - int track_count = 0; - int head_count = 0; - int track_spt; - int offset = 0; - int density = 0; - int i = 0; - int j = 0; - int k = 0; - int temp_rate = 0; - uint32_t file_size; - uint16_t len; - uint16_t rep; - td0dsk_t disk_decode; - uint8_t *hs; - uint16_t size; - uint8_t *dbuf = processed_buf; - uint32_t total_size = 0; - uint32_t pre_sector = 0; - uint32_t track_size = 0; - uint32_t raw_tsize = 0; - uint32_t minimum_gap3 = 0; - uint32_t minimum_gap4 = 0; - - if (!td0[drive].f) - { - pclog("TD0: Attempted to initialize without loading a file first\n"); - return 0; - } - - fseek(td0[drive].f, 0, SEEK_END); - file_size = ftell(td0[drive].f); - - if (file_size < 12) - { - pclog("TD0: File is too small to even contain the header\n"); - return 0; - } - - if (file_size > max_size) - { - pclog("TD0: File exceeds the maximum size\n"); - return 0; - } - - fseek(td0[drive].f, 0, SEEK_SET); - fread(header, 1, 12, td0[drive].f); - head_count = header[9]; - - if(header[0] == 't') - { - pclog("TD0: File is compressed\n"); - disk_decode.fdd_file = td0[drive].f; - td0_state_init_Decode(&disk_decode); - disk_decode.fdd_file_offset = 12; - td0_state_Decode(&disk_decode, imagebuf, max_size); - } - else - { - pclog("TD0: File is uncompressed\n"); - fseek(td0[drive].f, 12, SEEK_SET); - fread(imagebuf, 1, file_size - 12, td0[drive].f); - } - - if(header[7] & 0x80) - offset = 10 + imagebuf[2] + (imagebuf[3] << 8); - - track_spt = imagebuf[offset]; - if(track_spt == 255) /* Empty file? */ - { - pclog("TD0: File has no tracks\n"); - return 0; - } - - density = (header[5] >> 1) & 3; - - if (density == 3) - { - pclog("TD0: Unknown density\n"); - return 0; - } - - /* We determine RPM from the drive type as well as we possibly can. */ - /* This byte is actually the BIOS floppy drive type read by Teledisk from the CMOS. */ - switch(header[6]) - { - case 0: /* 5.25" 360k in 1.2M drive: 360 rpm - CMOS Drive type: None, value probably reused by Teledisk */ - case 2: /* 5.25" 1.2M 360 rpm */ - case 5: /* 8"/5.25"/3.5" 1.25M 360 rpm */ - td0[drive].default_track_flags = (density == 1) ? 0x20 : 0x21; - break; - case 1: /* 5.25" 360k: 300 rpm */ - case 3: /* 3.5" 720k: 300 rpm */ - td0[drive].default_track_flags = 0x02; - break; - case 4: /* 3.5" 1.44M: 300 rpm */ - td0[drive].default_track_flags = (density == 1) ? 0x00 : 0x02; - break; - case 6: /* 3.5" 2.88M: 300 rpm */ - td0[drive].default_track_flags = (density == 1) ? 0x00 : ((density == 2) ? 0x03 : 0x02); - break; - } - - td0[drive].disk_flags = header[5] & 0x06; - - td0[drive].track_width = (header[7] & 1) ^ 1; - - for (i = 0; i < 256; i++) - { - memset(td0[drive].side_flags[i], 0, 4); - memset(td0[drive].track_in_file[i], 0, 2); - memset(td0[drive].calculated_gap3_lengths[i], 0, 2); - for (j = 0; j < 2; j++) - { - memset(td0[drive].sects[i][j], 0, sizeof(td0_sector_t)); - } - } - - while(track_spt != 255) - { - track = imagebuf[offset + 1]; - head = imagebuf[offset + 2] & 1; - fm = (header[5] & 0x80) || (imagebuf[offset + 2] & 0x80); /* ? */ - td0[drive].side_flags[track][head] = td0[drive].default_track_flags | (fm ? 0 : 8); - td0[drive].track_in_file[track][head] = 1; - offset += 4; - track_size = fm ? 73 : 146; - pre_sector = fm ? 42 : 60; - - for(i = 0; i < track_spt; i++) - { - hs = &imagebuf[offset]; - offset += 6; - - td0[drive].sects[track][head][i].track = hs[0]; - td0[drive].sects[track][head][i].head = hs[1]; - td0[drive].sects[track][head][i].sector = hs[2]; - td0[drive].sects[track][head][i].size = hs[3]; - td0[drive].sects[track][head][i].deleted = (hs[4] & 4) == 4; - td0[drive].sects[track][head][i].bad_crc = (hs[4] & 2) == 2; - td0[drive].sects[track][head][i].data = dbuf; - - size = 128 << hs[3]; - if ((total_size + size) >= max_processed_size) - { - pclog("TD0: Processed buffer overflow\n"); - fclose(td0[drive].f); + raw_tsize = get_raw_tsize(dev->side_flags[track][head], 0); + minimum_gap3 = 12 * track_spt; + if ((raw_tsize - track_size + (fm ? 73 : 146)) < (minimum_gap3 + minimum_gap4)) { + /* If we can't fit the sectors with a reasonable minimum gap at perfect RPM, let's try 2% slower. */ + raw_tsize = get_raw_tsize(dev->side_flags[track][head], 1); + /* Set disk flags so that rotation speed is 2% slower. */ + dev->disk_flags |= (3 << 5); + if ((raw_tsize - track_size + (fm ? 73 : 146)) < (minimum_gap3 + minimum_gap4)) { + /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ + pclog("TD0: Unable to fit the %i sectors in a track\n", track_spt); return 0; } - - if(hs[4] & 0x30) - { - memset(dbuf, 0, size); - } - else - { - offset += 3; - switch(hs[8]) - { - default: - pclog("TD0: Image uses an unsupported sector data encoding\n"); - fclose(td0[drive].f); - return 0; - case 0: - memcpy(dbuf, &imagebuf[offset], size); - offset += size; - break; - case 1: - offset += 4; - k = (hs[9] + (hs[10] << 8)) * 2; - k = (k <= size) ? k : size; - for(j = 0; j < k; j += 2) - { - dbuf[j] = hs[11]; - dbuf[j + 1] = hs[12]; - } - if(k < size) - memset(&(dbuf[k]), 0, size - k); - break; - case 2: - k = 0; - while(k < size) - { - len = imagebuf[offset]; - rep = imagebuf[offset + 1]; - offset += 2; - if(!len) - { - memcpy(&(dbuf[k]), &imagebuf[offset], rep); - offset += rep; - k += rep; - } - else - { - len = (1 << len); - rep = len * rep; - rep = ((rep + k) <= size) ? rep : (size - k); - for(j = 0; j < rep; j += len) - memcpy(&(dbuf[j + k]), &imagebuf[offset], len); - k += rep; - offset += len; - } - } - break; - } - } - - dbuf += size; - total_size += size; - track_size += (pre_sector + size + 2); } + dev->calculated_gap3_lengths[track][head] = (raw_tsize - track_size - minimum_gap4 + (fm ? 73 : 146)) / track_spt; - track_count = track; - - if (track_spt != 255) - { - td0[drive].track_spt[track][head] = track_spt; - - if ((td0[drive].track_spt[track][head] == 8) && (td0[drive].sects[track][head][0].size == 3)) - { - td0[drive].side_flags[track][head] |= 0x20; - } - - raw_tsize = td0_get_raw_tsize(td0[drive].side_flags[track][head], 0); - minimum_gap3 = 12 * track_spt; - if ((raw_tsize - track_size + (fm ? 73 : 146)) < (minimum_gap3 + minimum_gap4)) - { - /* If we can't fit the sectors with a reasonable minimum gap at perfect RPM, let's try 2% slower. */ - raw_tsize = td0_get_raw_tsize(td0[drive].side_flags[track][head], 1); - /* Set disk flags so that rotation speed is 2% slower. */ - td0[drive].disk_flags |= (3 << 5); - if ((raw_tsize - track_size + (fm ? 73 : 146)) < (minimum_gap3 + minimum_gap4)) - { - /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ - pclog("TD0: Unable to fit the %i sectors in a track\n", track_spt); - return 0; - } - } - td0[drive].calculated_gap3_lengths[track][head] = (raw_tsize - track_size - minimum_gap4 + (fm ? 73 : 146)) / track_spt; - - track_spt = imagebuf[offset]; - } + track_spt = dev->imagebuf[offset]; } + } - if ((td0[drive].disk_flags & 0x60) == 0x60) - { - pclog("TD0: Disk will rotate 2% below perfect RPM\n"); - } + if ((dev->disk_flags & 0x60) == 0x60) + pclog("TD0: Disk will rotate 2% below perfect RPM\n"); - td0[drive].tracks = track_count + 1; + dev->tracks = track_count + 1; - temp_rate = td0[drive].default_track_flags & 7; - if ((td0[drive].default_track_flags & 0x27) == 0x20) temp_rate = 4; - td0[drive].gap3_len = gap3_sizes[temp_rate][td0[drive].sects[0][0][0].size][td0[drive].track_spt[0][0]]; - if (!td0[drive].gap3_len) - { - td0[drive].gap3_len = td0[drive].calculated_gap3_lengths[0][0]; /* If we can't determine the GAP3 length, assume the smallest one we possibly know of. */ - } + temp_rate = dev->default_track_flags & 7; + if ((dev->default_track_flags & 0x27) == 0x20) + temp_rate = 4; + dev->gap3_len = gap3_sizes[temp_rate][dev->sects[0][0][0].size][dev->track_spt[0][0]]; + if (! dev->gap3_len) + dev->gap3_len = dev->calculated_gap3_lengths[0][0]; /* If we can't determine the GAP3 length, assume the smallest one we possibly know of. */ - if(head_count == 2) - { - td0[drive].disk_flags |= 8; /* 2 sides */ - } + if (head_count == 2) + dev->disk_flags |= 8; /* 2 sides */ - if (td0[drive].tracks <= 43) - { - td0[drive].track_width &= ~1; - } + if (dev->tracks <= 43) + dev->track_width &= ~1; - td0[drive].sides = head_count; + dev->sides = head_count; - td0[drive].current_side_flags[0] = td0[drive].side_flags[0][0]; - td0[drive].current_side_flags[1] = td0[drive].side_flags[0][1]; + dev->current_side_flags[0] = dev->side_flags[0][0]; + dev->current_side_flags[1] = dev->side_flags[0][1]; - pclog("TD0: File loaded: %i tracks, %i sides, disk flags: %02X, side flags: %02X, %02X, GAP3 length: %02X\n", td0[drive].tracks, td0[drive].sides, td0[drive].disk_flags, td0[drive].current_side_flags[0], td0[drive].current_side_flags[1], td0[drive].gap3_len); + pclog("TD0: File loaded: %i tracks, %i sides, disk flags: %02X, side flags: %02X, %02X, GAP3 length: %02X\n", dev->tracks, dev->sides, dev->disk_flags, dev->current_side_flags[0], dev->current_side_flags[1], dev->gap3_len); - return 1; + return(1); } -int td0_track_is_xdf(int drive, int side, int track) + +static uint16_t +disk_flags(int drive) { - uint8_t id[4] = { 0, 0, 0, 0 }; - int i, effective_sectors, xdf_sectors; - int high_sectors, low_sectors; - int max_high_id, expected_high_count, expected_low_count; + td0_t *dev = td0[drive]; - effective_sectors = xdf_sectors = high_sectors = low_sectors = 0; - - memset(td0[drive].xdf_ordered_pos[side], 0, 256); - - if (!track) - { - if ((td0[drive].track_spt[track][side] == 16) || (td0[drive].track_spt[track][side] == 19)) - { - if (!side) - { - max_high_id = (td0[drive].track_spt[track][side] == 19) ? 0x8B : 0x88; - expected_high_count = (td0[drive].track_spt[track][side] == 19) ? 0x0B : 0x08; - expected_low_count = 8; - } - else - { - max_high_id = (td0[drive].track_spt[track][side] == 19) ? 0x93 : 0x90; - expected_high_count = (td0[drive].track_spt[track][side] == 19) ? 0x13 : 0x10; - expected_low_count = 0; - } - for (i = 0; i < td0[drive].track_spt[track][side]; i++) - { - id[0] = td0[drive].sects[track][side][i].track; - id[1] = td0[drive].sects[track][side][i].head; - id[2] = td0[drive].sects[track][side][i].sector; - id[3] = td0[drive].sects[track][side][i].size; - if (!(id[0]) && (id[1] == side) && (id[3] == 2)) - { - if ((id[2] >= 0x81) && (id[2] <= max_high_id)) - { - high_sectors++; - td0[drive].xdf_ordered_pos[id[2]][side] = i; - } - if ((id[2] >= 0x01) && (id[2] <= 0x08)) - { - low_sectors++; - td0[drive].xdf_ordered_pos[id[2]][side] = i; - } - } - } - if ((high_sectors == expected_high_count) && (low_sectors == expected_low_count)) - { - td0[drive].current_side_flags[side] = (td0[drive].track_spt[track][side] == 19) ? 0x08 : 0x28; - return (td0[drive].track_spt[track][side] == 19) ? 2 : 1; - } - return 0; - } - else - { - return 0; - } - } - else - { - for (i = 0; i < td0[drive].track_spt[track][side]; i++) - { - id[0] = td0[drive].sects[track][side][i].track; - id[1] = td0[drive].sects[track][side][i].head; - id[2] = td0[drive].sects[track][side][i].sector; - id[3] = td0[drive].sects[track][side][i].size; - effective_sectors++; - if ((id[0] == track) && (id[1] == side) && !(id[2]) && !(id[3])) - { - effective_sectors--; - } - if ((id[0] == track) && (id[1] == side) && (id[2] == (id[3] | 0x80))) - { - xdf_sectors++; - td0[drive].xdf_ordered_pos[id[2]][side] = i; - } - } - if ((effective_sectors == 3) && (xdf_sectors == 3)) - { - td0[drive].current_side_flags[side] = 0x28; - return 1; /* 5.25" 2HD XDF */ - } - if ((effective_sectors == 4) && (xdf_sectors == 4)) - { - td0[drive].current_side_flags[side] = 0x08; - return 2; /* 3.5" 2HD XDF */ - } - return 0; - } + return(dev->disk_flags); } -int td0_track_is_interleave(int drive, int side, int track) + +static uint16_t +side_flags(int drive) { - int i, effective_sectors; - int track_spt; + td0_t *dev = td0[drive]; + int side = 0; + uint16_t sflags = 0; - effective_sectors = 0; + side = fdd_get_head(drive); + sflags = dev->current_side_flags[side]; - for (i = 0; i < 256; i++) - { - td0[drive].interleave_ordered_pos[i][side] = 0; - } - - track_spt = td0[drive].track_spt[track][side]; - - if (track_spt != 21) - { - return 0; - } - - for (i = 0; i < track_spt; i++) - { - if ((td0[drive].sects[track][side][i].track == track) && (td0[drive].sects[track][side][i].head == side) && (td0[drive].sects[track][side][i].sector >= 1) && (td0[drive].sects[track][side][i].sector <= track_spt) && (td0[drive].sects[track][side][i].size == 2)) - { - effective_sectors++; - td0[drive].interleave_ordered_pos[td0[drive].sects[track][side][i].sector][side] = i; - } - } - - if (effective_sectors == track_spt) - { - return 1; - } - return 0; + return(sflags); } -void td0_seek(int drive, int track) + +static void +set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) { - int side; + td0_t *dev = td0[drive]; + int i = 0; - uint8_t id[4] = { 0, 0, 0, 0 }; - - int sector, current_pos; - - int ssize = 512; - - int track_rate = 0; - - int track_gap2 = 22; - int track_gap3 = 12; - - int xdf_type = 0; - int interleave_type = 0; - - int is_trackx = 0; - - int xdf_spt = 0; - int xdf_sector = 0; - - int ordered_pos = 0; - - int real_sector = 0; - int actual_sector = 0; - - if (!td0[drive].f) - return; - - if (!td0[drive].track_width && fdd_doublestep_40(drive)) - track /= 2; - - d86f_set_cur_track(drive, track); - - is_trackx = (track == 0) ? 0 : 1; - - td0[drive].track = track; - - td0[drive].current_side_flags[0] = td0[drive].side_flags[track][0]; - td0[drive].current_side_flags[1] = td0[drive].side_flags[track][1]; - - d86f_reset_index_hole_pos(drive, 0); - d86f_reset_index_hole_pos(drive, 1); - - d86f_destroy_linked_lists(drive, 0); - d86f_destroy_linked_lists(drive, 1); - - if (track > td0[drive].tracks) - { - d86f_zero_track(drive); - return; + dev->current_sector_index[side] = 0; + if (c != dev->track) return; + for (i = 0; i < dev->track_spt[c][side]; i++) { + if ((dev->sects[c][side][i].track == c) && + (dev->sects[c][side][i].head == h) && + (dev->sects[c][side][i].sector == r) && + (dev->sects[c][side][i].size == n)) { + dev->current_sector_index[side] = i; } + } +} - for (side = 0; side < td0[drive].sides; side++) - { - track_rate = td0[drive].current_side_flags[side] & 7; - if (!track_rate && (td0[drive].current_side_flags[side] & 0x20)) track_rate = 4; - track_gap3 = gap3_sizes[track_rate][td0[drive].sects[track][side][0].size][td0[drive].track_spt[track][side]]; - if (!track_gap3) - { - track_gap3 = td0[drive].calculated_gap3_lengths[track][side]; + +static uint8_t +poll_read_data(int drive, int side, uint16_t pos) +{ + td0_t *dev = td0[drive]; + + return(dev->sects[dev->track][side][dev->current_sector_index[side]].data[pos]); +} + + +static int +track_is_xdf(int drive, int side, int track) +{ + td0_t *dev = td0[drive]; + uint8_t id[4] = { 0, 0, 0, 0 }; + int i, effective_sectors, xdf_sectors; + int high_sectors, low_sectors; + int max_high_id, expected_high_count, expected_low_count; + + effective_sectors = xdf_sectors = high_sectors = low_sectors = 0; + + memset(dev->xdf_ordered_pos[side], 0, 256); + + if (! track) { + if ((dev->track_spt[track][side] == 16) || (dev->track_spt[track][side] == 19)) { + if (! side) { + max_high_id = (dev->track_spt[track][side] == 19) ? 0x8B : 0x88; + expected_high_count = (dev->track_spt[track][side] == 19) ? 0x0B : 0x08; + expected_low_count = 8; + } else { + max_high_id = (dev->track_spt[track][side] == 19) ? 0x93 : 0x90; + expected_high_count = (dev->track_spt[track][side] == 19) ? 0x13 : 0x10; + expected_low_count = 0; } - track_gap2 = ((td0[drive].current_side_flags[side] & 7) >= 3) ? 41 : 22; - - xdf_type = td0_track_is_xdf(drive, side, track); - - interleave_type = td0_track_is_interleave(drive, side, track); - - current_pos = d86f_prepare_pretrack(drive, side, 0); - - if (!xdf_type) - { - for (sector = 0; sector < td0[drive].track_spt[track][side]; sector++) - { - if (interleave_type == 0) - { - real_sector = td0[drive].sects[track][side][sector].sector; - actual_sector = sector; + for (i = 0; i < dev->track_spt[track][side]; i++) { + id[0] = dev->sects[track][side][i].track; + id[1] = dev->sects[track][side][i].head; + id[2] = dev->sects[track][side][i].sector; + id[3] = dev->sects[track][side][i].size; + if (!(id[0]) && (id[1] == side) && (id[3] == 2)) { + if ((id[2] >= 0x81) && (id[2] <= max_high_id)) { + high_sectors++; + dev->xdf_ordered_pos[id[2]][side] = i; } - else - { - real_sector = dmf_r[sector]; - actual_sector = td0[drive].interleave_ordered_pos[real_sector][side]; - } - id[0] = td0[drive].sects[track][side][actual_sector].track; - id[1] = td0[drive].sects[track][side][actual_sector].head; - id[2] = real_sector; - 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]); + if ((id[2] >= 0x01) && (id[2] <= 0x08)) { + low_sectors++; + dev->xdf_ordered_pos[id[2]][side] = i; } } } - else - { - xdf_type--; - xdf_spt = xdf_physical_sectors[xdf_type][is_trackx]; - for (sector = 0; sector < xdf_spt; sector++) - { - xdf_sector = (side * xdf_spt) + sector; - id[0] = track; - id[1] = side; - id[2] = xdf_disk_layout[xdf_type][is_trackx][xdf_sector].id.r; - id[3] = is_trackx ? (id[2] & 7) : 2; - ssize = 128 << ((uint32_t) id[3]); - ordered_pos = td0[drive].xdf_ordered_pos[id[2]][side]; - if (is_trackx) - { - current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[xdf_type][xdf_sector], 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); - } - else - { - 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]); - } - } + if ((high_sectors == expected_high_count) && (low_sectors == expected_low_count)) { + dev->current_side_flags[side] = (dev->track_spt[track][side] == 19) ? 0x08 : 0x28; + return((dev->track_spt[track][side] == 19) ? 2 : 1); } } -} - -uint16_t td0_disk_flags(int drive) -{ - return td0[drive].disk_flags; -} - -uint16_t td0_side_flags(int drive) -{ - int side = 0; - uint16_t sflags = 0; - side = fdd_get_head(drive); - sflags = td0[drive].current_side_flags[side]; - return sflags; -} - -void td0_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) -{ - int i = 0; - td0[drive].current_sector_index[side] = 0; - if (c != td0[drive].track) return; - for (i = 0; i < td0[drive].track_spt[c][side]; i++) - { - if ((td0[drive].sects[c][side][i].track == c) && - (td0[drive].sects[c][side][i].head == h) && - (td0[drive].sects[c][side][i].sector == r) && - (td0[drive].sects[c][side][i].size == n)) - { - td0[drive].current_sector_index[side] = i; + } else { + for (i = 0; i < dev->track_spt[track][side]; i++) { + id[0] = dev->sects[track][side][i].track; + id[1] = dev->sects[track][side][i].head; + id[2] = dev->sects[track][side][i].sector; + id[3] = dev->sects[track][side][i].size; + effective_sectors++; + if ((id[0] == track) && (id[1] == side) && !(id[2]) && !(id[3])) { + effective_sectors--; + } + if ((id[0] == track) && (id[1] == side) && (id[2] == (id[3] | 0x80))) { + xdf_sectors++; + dev->xdf_ordered_pos[id[2]][side] = i; } } + + if ((effective_sectors == 3) && (xdf_sectors == 3)) { + dev->current_side_flags[side] = 0x28; + return(1); /* 5.25" 2HD XDF */ + } + + if ((effective_sectors == 4) && (xdf_sectors == 4)) { + dev->current_side_flags[side] = 0x08; + return(2); /* 3.5" 2HD XDF */ + } + } + + return(0); +} + + +static int +track_is_interleave(int drive, int side, int track) +{ + td0_t *dev = td0[drive]; + int i, effective_sectors; + int track_spt; + + effective_sectors = 0; + + for (i = 0; i < 256; i++) + dev->interleave_ordered_pos[i][side] = 0; + + track_spt = dev->track_spt[track][side]; + + if (track_spt != 21) return(0); + + for (i = 0; i < track_spt; i++) { + if ((dev->sects[track][side][i].track == track) && (dev->sects[track][side][i].head == side) && (dev->sects[track][side][i].sector >= 1) && (dev->sects[track][side][i].sector <= track_spt) && (dev->sects[track][side][i].size == 2)) { + effective_sectors++; + dev->interleave_ordered_pos[dev->sects[track][side][i].sector][side] = i; + } + } + + if (effective_sectors == track_spt) return(1); + + return(0); +} + + +static void +td0_seek(int drive, int track) +{ + td0_t *dev = td0[drive]; + int side; + uint8_t id[4] = { 0, 0, 0, 0 }; + int sector, current_pos; + int ssize = 512; + int track_rate = 0; + int track_gap2 = 22; + int track_gap3 = 12; + int xdf_type = 0; + int interleave_type = 0; + int is_trackx = 0; + int xdf_spt = 0; + int xdf_sector = 0; + int ordered_pos = 0; + int real_sector = 0; + int actual_sector = 0; + + if (dev->f == NULL) return; + + if (!dev->track_width && fdd_doublestep_40(drive)) + track /= 2; + + d86f_set_cur_track(drive, track); + + is_trackx = (track == 0) ? 0 : 1; + dev->track = track; + + dev->current_side_flags[0] = dev->side_flags[track][0]; + dev->current_side_flags[1] = dev->side_flags[track][1]; + + d86f_reset_index_hole_pos(drive, 0); + d86f_reset_index_hole_pos(drive, 1); + + d86f_destroy_linked_lists(drive, 0); + d86f_destroy_linked_lists(drive, 1); + + if (track > dev->tracks) { + d86f_zero_track(drive); return; + } + + for (side = 0; side < dev->sides; side++) { + track_rate = dev->current_side_flags[side] & 7; + if (!track_rate && (dev->current_side_flags[side] & 0x20)) + track_rate = 4; + track_gap3 = gap3_sizes[track_rate][dev->sects[track][side][0].size][dev->track_spt[track][side]]; + if (! track_gap3) + track_gap3 = dev->calculated_gap3_lengths[track][side]; + + track_gap2 = ((dev->current_side_flags[side] & 7) >= 3) ? 41 : 22; + + xdf_type = track_is_xdf(drive, side, track); + + interleave_type = track_is_interleave(drive, side, track); + + current_pos = d86f_prepare_pretrack(drive, side, 0); + + if (! xdf_type) { + for (sector = 0; sector < dev->track_spt[track][side]; sector++) { + if (interleave_type == 0) { + real_sector = dev->sects[track][side][sector].sector; + actual_sector = sector; + } else { + real_sector = dmf_r[sector]; + actual_sector = dev->interleave_ordered_pos[real_sector][side]; + } + + id[0] = dev->sects[track][side][actual_sector].track; + id[1] = dev->sects[track][side][actual_sector].head; + id[2] = real_sector; + id[3] = dev->sects[track][side][actual_sector].size; + ssize = 128 << ((uint32_t) dev->sects[track][side][actual_sector].size); + current_pos = d86f_prepare_sector(drive, side, current_pos, id, dev->sects[track][side][actual_sector].data, ssize, track_gap2, track_gap3, dev->sects[track][side][actual_sector].deleted, dev->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 { + xdf_type--; + xdf_spt = xdf_physical_sectors[xdf_type][is_trackx]; + for (sector = 0; sector < xdf_spt; sector++) { + xdf_sector = (side * xdf_spt) + sector; + id[0] = track; + id[1] = side; + id[2] = xdf_disk_layout[xdf_type][is_trackx][xdf_sector].id.r; + id[3] = is_trackx ? (id[2] & 7) : 2; + ssize = 128 << ((uint32_t) id[3]); + ordered_pos = dev->xdf_ordered_pos[id[2]][side]; + if (is_trackx) { + current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[xdf_type][xdf_sector], id, dev->sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], dev->sects[track][side][ordered_pos].deleted, dev->sects[track][side][ordered_pos].bad_crc); + } else { + current_pos = d86f_prepare_sector(drive, side, current_pos, id, dev->sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], dev->sects[track][side][ordered_pos].deleted, dev->sects[track][side][ordered_pos].bad_crc); + } + + if (sector == 0) + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + } + } + } } -uint8_t td0_poll_read_data(int drive, int side, uint16_t pos) + +void +td0_init(void) { - return td0[drive].sects[td0[drive].track][side][td0[drive].current_sector_index[side]].data[pos]; + memset(td0, 0x00, sizeof(td0)); } -void d86f_register_td0(int drive) + +void +td0_load(int drive, wchar_t *fn) { - 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; - d86f_handler[drive].encoded_data = common_encoded_data; - d86f_handler[drive].read_revolution = common_read_revolution; - 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); + td0_t *dev; + uint32_t i; + + d86f_unregister(drive); + + writeprot[drive] = 1; + + dev = (td0_t *)malloc(sizeof(td0_t)); + memset(dev, 0x00, sizeof(td0_t)); + td0[drive] = dev; + + dev->f = plat_fopen(fn, L"rb"); + if (dev->f == NULL) { + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } + + fwriteprot[drive] = writeprot[drive]; + + if (! dsk_identify(drive)) { + pclog("TD0: Not a valid Teledisk image\n"); + fclose(dev->f); + dev->f = NULL; + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } else { + pclog("TD0: Valid Teledisk image\n"); + } + + /* Allocate the processing buffers. */ + i = 1024UL * 1024UL * 4UL; + dev->imagebuf = (uint8_t *)malloc(i); + memset(dev->imagebuf, 0x00, i); + dev->processed_buf = (uint8_t *)malloc(i); + memset(dev->processed_buf, 0x00, i); + + if (! td0_initialize(drive)) { + pclog("TD0: Failed to initialize\n"); + fclose(dev->f); + free(dev->imagebuf); + free(dev->processed_buf); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } else { + pclog("TD0: Initialized successfully\n"); + } + + /* Attach this format to the D86F engine. */ + d86f_handler[drive].disk_flags = disk_flags; + d86f_handler[drive].side_flags = side_flags; + d86f_handler[drive].writeback = null_writeback; + d86f_handler[drive].set_sector = set_sector; + d86f_handler[drive].read_data = 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; + d86f_handler[drive].encoded_data = common_encoded_data; + d86f_handler[drive].read_revolution = common_read_revolution; + 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); + + drives[drive].seek = td0_seek; + + d86f_common_handlers(drive); +} + + +void +td0_close(int drive) +{ + td0_t *dev = td0[drive]; + int i, j, k; + + if (dev == NULL) return; + + d86f_unregister(drive); + + free(dev->imagebuf); + free(dev->processed_buf); + + for (i = 0; i < 256; i++) { + for (j = 0; j < 2; j++) { + for (k = 0; k < 256; k++) + dev->sects[i][j][k].data = NULL; + } + } + + for (i = 0; i < 256; i++) { + memset(dev->side_flags[i], 0, 4); + memset(dev->track_in_file[i], 0, 2); + memset(dev->calculated_gap3_lengths[i], 0, 2); + for (j = 0; j < 2; j++) + memset(dev->sects[i][j], 0, sizeof(td0_sector_t)); + } + + if (dev->f != NULL) + fclose(dev->f); + + /* Release resources. */ + free(dev); + td0[drive] = NULL; } diff --git a/src/floppy/fdd_td0.h b/src/floppy/fdd_td0.h index 9a4623d..8c35932 100644 --- a/src/floppy/fdd_td0.h +++ b/src/floppy/fdd_td0.h @@ -8,7 +8,7 @@ * * Definitions for the Teledisk floppy image format. * - * Version: @(#)floppy_td0.h 1.0.1 2018/02/14 + * Version: @(#)floppy_td0.h 1.0.2 2018/03/17 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -41,7 +41,6 @@ extern void td0_init(void); extern void td0_load(int drive, wchar_t *fn); extern void td0_close(int drive); -extern void td0_seek(int drive, int track); #endif /*EMU_FLOPPY_TD0_H*/ diff --git a/src/game/gameport.c b/src/game/gameport.c index abbc58c..f99dc22 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -8,7 +8,7 @@ * * Implementation of a generic Game Port. * - * Version: @(#)gameport.c 1.0.2 2018/03/10 + * Version: @(#)gameport.c 1.0.3 2018/03/15 * * Authors: Miran Grca, * Sarah Walker, @@ -52,258 +52,284 @@ #include "joystick_tm_fcs.h" -int joystick_type; +typedef struct { + int64_t count; + int axis_nr; + struct _gameport_ *gameport; +} g_axis_t; +typedef struct _gameport_ { + uint8_t state; -joystick_if_t joystick_none = -{ - "No joystick", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - 0, - 0, - 0 -}; + g_axis_t axis[4]; -static joystick_if_t *joystick_list[] = -{ - &joystick_standard, - &joystick_standard_4button, - &joystick_standard_6button, - &joystick_standard_8button, - &joystick_ch_flightstick_pro, - &joystick_sw_pad, - &joystick_tm_fcs, - &joystick_none, - NULL -}; - -char *joystick_get_name(int64_t joystick) -{ - if (!joystick_list[joystick]) - return NULL; - return (char *)joystick_list[joystick]->name; -} - -int64_t joystick_get_max_joysticks(int64_t joystick) -{ - return joystick_list[joystick]->max_joysticks; -} - -int64_t joystick_get_axis_count(int64_t joystick) -{ - return joystick_list[joystick]->axis_count; -} - -int64_t joystick_get_button_count(int64_t joystick) -{ - return joystick_list[joystick]->button_count; -} - -int64_t joystick_get_pov_count(int64_t joystick) -{ - return joystick_list[joystick]->pov_count; -} - - char *joystick_get_axis_name(int64_t joystick, int64_t id) -{ - return (char *)joystick_list[joystick]->axis_names[id]; -} - -char *joystick_get_button_name(int64_t joystick, int64_t id) -{ - return (char *)joystick_list[joystick]->button_names[id]; -} - -char *joystick_get_pov_name(int64_t joystick, int64_t id) -{ - return (char *)joystick_list[joystick]->pov_names[id]; -} - -typedef struct gameport_axis_t -{ - int64_t count; - int64_t axis_nr; - struct gameport_t *gameport; -} gameport_axis_t; - -typedef struct gameport_t -{ - uint8_t state; - - gameport_axis_t axis[4]; - - joystick_if_t *joystick; - void *joystick_dat; + const joystick_if_t *joystick; + void *joystick_dat; } gameport_t; + +int joystick_type; + + +static const joystick_if_t joystick_none = { + "No joystick", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + 0 +}; + + +static const joystick_if_t *joystick_list[] = { + &joystick_standard, + &joystick_standard_4button, + &joystick_standard_6button, + &joystick_standard_8button, + &joystick_ch_flightstick_pro, + &joystick_sw_pad, + &joystick_tm_fcs, + &joystick_none, + NULL +}; static gameport_t *gameport_global = NULL; -static int64_t gameport_time(int64_t axis) -{ - if (axis == AXIS_NOT_PRESENT) - return 0; - axis += 32768; - axis = (axis * 100) / 65; /*Axis now in ohms*/ - axis = (axis * 11) / 1000; - return TIMER_USEC * (axis + 24); /*max = 11.115 ms*/ +char * +joystick_get_name(int js) +{ + if (! joystick_list[js]) + return(NULL); + return((char *)joystick_list[js]->name); } -void gameport_write(uint16_t addr, uint8_t val, void *p) + +int +joystick_get_max_joysticks(int js) { - gameport_t *gameport = (gameport_t *)p; - - timer_clock(); - gameport->state |= 0x0f; - pclog("gameport_write : joysticks_present=%i\n", joysticks_present); - - gameport->axis[0].count = gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 0)); - gameport->axis[1].count = gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 1)); - gameport->axis[2].count = gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 2)); - gameport->axis[3].count = gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 3)); - - gameport->joystick->write(gameport->joystick_dat); - - cycles -= ISA_CYCLES(8); + return(joystick_list[js]->max_joysticks); } -uint8_t gameport_read(uint16_t addr, void *p) + +int +joystick_get_axis_count(int js) { - gameport_t *gameport = (gameport_t *)p; - uint8_t ret; - - timer_clock(); - ret = gameport->state | gameport->joystick->read(gameport->joystick_dat); - - cycles -= ISA_CYCLES(8); - - return ret; + return(joystick_list[js]->axis_count); } -void gameport_timer_over(void *p) + +int +joystick_get_button_count(int js) { - gameport_axis_t *axis = (gameport_axis_t *)p; - gameport_t *gameport = axis->gameport; - - gameport->state &= ~(1 << axis->axis_nr); - axis->count = 0; - - if (axis == &gameport->axis[0]) - gameport->joystick->a0_over(gameport->joystick_dat); + return(joystick_list[js]->button_count); } -void *gameport_init_common(void) -{ - gameport_t *gameport = malloc(sizeof(gameport_t)); - - memset(gameport, 0, sizeof(gameport_t)); - - gameport->axis[0].gameport = gameport; - gameport->axis[1].gameport = gameport; - gameport->axis[2].gameport = gameport; - gameport->axis[3].gameport = gameport; - gameport->axis[0].axis_nr = 0; - gameport->axis[1].axis_nr = 1; - gameport->axis[2].axis_nr = 2; - gameport->axis[3].axis_nr = 3; - - timer_add(gameport_timer_over, &gameport->axis[0].count, &gameport->axis[0].count, &gameport->axis[0]); - timer_add(gameport_timer_over, &gameport->axis[1].count, &gameport->axis[1].count, &gameport->axis[1]); - timer_add(gameport_timer_over, &gameport->axis[2].count, &gameport->axis[2].count, &gameport->axis[2]); - timer_add(gameport_timer_over, &gameport->axis[3].count, &gameport->axis[3].count, &gameport->axis[3]); - - gameport->joystick = joystick_list[joystick_type]; - gameport->joystick_dat = gameport->joystick->init(); - - gameport_global = gameport; - - return gameport; +int +joystick_get_pov_count(int js) +{ + return(joystick_list[js]->pov_count); } -void gameport_update_joystick_type(void) + +char * +joystick_get_axis_name(int js, int id) { - gameport_t *gameport = gameport_global; - - if (gameport) - { - gameport->joystick->close(gameport->joystick_dat); - gameport->joystick = joystick_list[joystick_type]; - gameport->joystick_dat = gameport->joystick->init(); - } + return((char *)joystick_list[js]->axis_names[id]); } -void *gameport_init(device_t *info) + +char * +joystick_get_button_name(int js, int id) { - gameport_t *gameport = NULL; - - if (joystick_type == 7) - { - gameport = NULL; - return gameport; - } - - gameport = gameport_init_common(); - - io_sethandler(0x0200, 0x0008, gameport_read, NULL, NULL, gameport_write, NULL, NULL, gameport); - - return gameport; + return((char *)joystick_list[js]->button_names[id]); } -void *gameport_201_init(device_t *info) + +char * +joystick_get_pov_name(int js, int id) { - gameport_t *gameport; - - if (joystick_type == 7) - { - gameport = NULL; - return gameport; - } - - gameport = gameport_init_common(); - - io_sethandler(0x0201, 0x0001, gameport_read, NULL, NULL, gameport_write, NULL, NULL, gameport); - - return gameport; + return (char *)joystick_list[js]->pov_names[id]; } -void gameport_close(void *p) + +static int +gameport_time(int axis) { - gameport_t *gameport = (gameport_t *)p; + if (axis == AXIS_NOT_PRESENT) return(0); - if (!p) - { - return; - } - - gameport->joystick->close(gameport->joystick_dat); + axis += 32768; + axis = (axis * 100) / 65; /*Axis now in ohms*/ + axis = (axis * 11) / 1000; - gameport_global = NULL; - - free(gameport); + return(TIMER_USEC * (axis + 24)); /*max = 11.115 ms*/ } -device_t gameport_device = + +static void +gameport_write(uint16_t addr, uint8_t val, void *priv) { - "Game port", - 0, 0, - gameport_init, - gameport_close, - NULL, NULL, NULL, NULL, - NULL + gameport_t *p = (gameport_t *)priv; + + timer_clock(); + p->state |= 0x0f; + pclog("gameport_write : joysticks_present=%i\n", joysticks_present); + + p->axis[0].count = gameport_time(p->joystick->read_axis(p->joystick_dat, 0)); + p->axis[1].count = gameport_time(p->joystick->read_axis(p->joystick_dat, 1)); + p->axis[2].count = gameport_time(p->joystick->read_axis(p->joystick_dat, 2)); + p->axis[3].count = gameport_time(p->joystick->read_axis(p->joystick_dat, 3)); + + p->joystick->write(p->joystick_dat); + + cycles -= ISA_CYCLES(8); +} + + +static uint8_t +gameport_read(uint16_t addr, void *priv) +{ + gameport_t *p = (gameport_t *)p; + uint8_t ret; + + timer_clock(); + ret = p->state | p->joystick->read(p->joystick_dat); + + cycles -= ISA_CYCLES(8); + + return(ret); +} + + +static void +timer_over(void *priv) +{ + g_axis_t *axis = (g_axis_t *)priv; + gameport_t *p = axis->gameport; + + p->state &= ~(1 << axis->axis_nr); + axis->count = 0; + + if (axis == &p->axis[0]) + p->joystick->a0_over(p->joystick_dat); +} + + +static void * +init_common(void) +{ + gameport_t *p = malloc(sizeof(gameport_t)); + + memset(p, 0x00, sizeof(gameport_t)); + + p->axis[0].gameport = p; + p->axis[1].gameport = p; + p->axis[2].gameport = p; + p->axis[3].gameport = p; + + p->axis[0].axis_nr = 0; + p->axis[1].axis_nr = 1; + p->axis[2].axis_nr = 2; + p->axis[3].axis_nr = 3; + + timer_add(timer_over, &p->axis[0].count, &p->axis[0].count, &p->axis[0]); + timer_add(timer_over, &p->axis[1].count, &p->axis[1].count, &p->axis[1]); + timer_add(timer_over, &p->axis[2].count, &p->axis[2].count, &p->axis[2]); + timer_add(timer_over, &p->axis[3].count, &p->axis[3].count, &p->axis[3]); + + p->joystick = joystick_list[joystick_type]; + p->joystick_dat = p->joystick->init(); + + gameport_global = p; + + return(p); +} + + +void +gameport_update_joystick_type(void) +{ + gameport_t *p = gameport_global; + + if (p != NULL) { + p->joystick->close(p->joystick_dat); + p->joystick = joystick_list[joystick_type]; + p->joystick_dat = p->joystick->init(); + } +} + + +static void * +gameport_init(const device_t *info) +{ + gameport_t *p = NULL; + + if (joystick_type == 7) { + p = NULL; + return(p); + } + + p = init_common(); + + io_sethandler(0x0200, 8, + gameport_read,NULL,NULL, gameport_write,NULL,NULL, p); + + return(p); +} + + +static void * +gameport_201_init(const device_t *info) +{ + gameport_t *p; + + if (joystick_type == 7) { + p = NULL; + return(p); + } + + p = init_common(); + + io_sethandler(0x0201, 1, + gameport_read,NULL,NULL, gameport_write,NULL,NULL, p); + + return(p); +} + + +static void +gameport_close(void *priv) +{ + gameport_t *p = (gameport_t *)priv; + + if (p == NULL) return; + + p->joystick->close(p->joystick_dat); + + gameport_global = NULL; + + free(p); +} + + +const device_t gameport_device = { + "Game port", + 0, 0, + gameport_init, + gameport_close, + NULL, NULL, NULL, NULL, + NULL }; -device_t gameport_201_device = -{ - "Game port (port 201h only)", - 0, 0, - gameport_201_init, - gameport_close, - NULL, NULL, NULL, NULL, - NULL +const device_t gameport_201_device = { + "Game port (port 201h only)", + 0, 0, + gameport_201_init, + gameport_close, + NULL, NULL, NULL, NULL, + NULL }; diff --git a/src/game/gameport.h b/src/game/gameport.h index 1b1be36..3db9996 100644 --- a/src/game/gameport.h +++ b/src/game/gameport.h @@ -10,7 +10,7 @@ * * NOTE: This module needs a good cleanup someday. * - * Version: @(#)gameport.h 1.0.2 2018/02/10 + * Version: @(#)gameport.h 1.0.3 2018/03/15 * * Authors: Miran Grca, * Sarah Walker, @@ -114,8 +114,8 @@ extern "C" { #endif #ifdef EMU_DEVICE_H -extern device_t gameport_device; -extern device_t gameport_201_device; +extern const device_t gameport_device; +extern const device_t gameport_201_device; #endif extern plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; @@ -129,14 +129,14 @@ extern void joystick_init(void); extern void joystick_close(void); extern void joystick_process(void); -extern char *joystick_get_name(int64_t joystick); -extern int64_t joystick_get_max_joysticks(int64_t joystick); -extern int64_t joystick_get_axis_count(int64_t joystick); -extern int64_t joystick_get_button_count(int64_t joystick); -extern int64_t joystick_get_pov_count(int64_t joystick); -extern char *joystick_get_axis_name(int64_t joystick, int64_t id); -extern char *joystick_get_button_name(int64_t joystick, int64_t id); -extern char *joystick_get_pov_name(int64_t joystick, int64_t id); +extern char *joystick_get_name(int js); +extern int joystick_get_max_joysticks(int js); +extern int joystick_get_axis_count(int js); +extern int joystick_get_button_count(int js); +extern int joystick_get_pov_count(int js); +extern char *joystick_get_axis_name(int js, int id); +extern char *joystick_get_button_name(int js, int id); +extern char *joystick_get_pov_name(int js, int id); extern void gameport_update_joystick_type(void); diff --git a/src/game/joystick_ch_flightstick_pro.c b/src/game/joystick_ch_flightstick_pro.c index 948e40c..460872c 100644 --- a/src/game/joystick_ch_flightstick_pro.c +++ b/src/game/joystick_ch_flightstick_pro.c @@ -8,7 +8,7 @@ * * Implementation of the Flight Stick Pro. * - * Version: @(#)flightstick_pro.c 1.0.3 2018/03/10 + * Version: @(#)flightstick_pro.c 1.0.4 2018/03/15 * * Authors: Miran Grca, * Sarah Walker, @@ -113,7 +113,7 @@ static void ch_flightstick_pro_a0_over(void *p) { } -joystick_if_t joystick_ch_flightstick_pro = +const joystick_if_t joystick_ch_flightstick_pro = { "CH Flightstick Pro", ch_flightstick_pro_init, diff --git a/src/game/joystick_ch_flightstick_pro.h b/src/game/joystick_ch_flightstick_pro.h index 3852696..7cbb717 100644 --- a/src/game/joystick_ch_flightstick_pro.h +++ b/src/game/joystick_ch_flightstick_pro.h @@ -8,7 +8,7 @@ * * Definitions for the Flight Stick Pro driver. * - * Version: @(#)joystick_ch_flightstickpro.h 1.0.1 2018/02/14 + * Version: @(#)joystick_ch_flightstickpro.h 1.0.2 2018/03/15 * * Authors: Miran Grca, * Sarah Walker, @@ -35,4 +35,4 @@ * USA. */ -extern joystick_if_t joystick_ch_flightstick_pro; +extern const joystick_if_t joystick_ch_flightstick_pro; diff --git a/src/game/joystick_standard.c b/src/game/joystick_standard.c index e2934c5..616225a 100644 --- a/src/game/joystick_standard.c +++ b/src/game/joystick_standard.c @@ -8,7 +8,7 @@ * * Implementation of a standard joystick. * - * Version: @(#)joystick_standard.c 1.0.3 2018/03/10 + * Version: @(#)joystick_standard.c 1.0.4 2018/03/15 * * Authors: Miran Grca, * Sarah Walker, @@ -195,7 +195,7 @@ static void joystick_standard_a0_over(void *p) { } -joystick_if_t joystick_standard = +const joystick_if_t joystick_standard = { "Standard 2-button joystick(s)", joystick_standard_init, @@ -211,7 +211,7 @@ joystick_if_t joystick_standard = {"X axis", "Y axis"}, {"Button 1", "Button 2"} }; -joystick_if_t joystick_standard_4button = +const joystick_if_t joystick_standard_4button = { "Standard 4-button joystick", joystick_standard_init, @@ -227,7 +227,7 @@ joystick_if_t joystick_standard_4button = {"X axis", "Y axis"}, {"Button 1", "Button 2", "Button 3", "Button 4"} }; -joystick_if_t joystick_standard_6button = +const joystick_if_t joystick_standard_6button = { "Standard 6-button joystick", joystick_standard_init, @@ -243,7 +243,7 @@ joystick_if_t joystick_standard_6button = {"X axis", "Y axis"}, {"Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6"} }; -joystick_if_t joystick_standard_8button = +const joystick_if_t joystick_standard_8button = { "Standard 8-button joystick", joystick_standard_init, diff --git a/src/game/joystick_standard.h b/src/game/joystick_standard.h index 5b1a5e5..26b1699 100644 --- a/src/game/joystick_standard.h +++ b/src/game/joystick_standard.h @@ -8,7 +8,7 @@ * * Definitions for the joystick driver. * - * Version: @(#)joystick_standard.h 1.0.1 2018/02/14 + * Version: @(#)joystick_standard.h 1.0.2 2018/03/15 * * Authors: Miran Grca, * Sarah Walker, @@ -35,7 +35,7 @@ * USA. */ -extern joystick_if_t joystick_standard; -extern joystick_if_t joystick_standard_4button; -extern joystick_if_t joystick_standard_6button; -extern joystick_if_t joystick_standard_8button; +extern const joystick_if_t joystick_standard; +extern const joystick_if_t joystick_standard_4button; +extern const joystick_if_t joystick_standard_6button; +extern const joystick_if_t joystick_standard_8button; diff --git a/src/game/joystick_sw_pad.c b/src/game/joystick_sw_pad.c index f225c37..257a4ab 100644 --- a/src/game/joystick_sw_pad.c +++ b/src/game/joystick_sw_pad.c @@ -29,7 +29,7 @@ * - Some DOS stuff will write to 0x201 while a packet is * being transferred. This seems to be ignored. * - * Version: @(#)sw_pad.c 1.0.4 2018/03/12 + * Version: @(#)sw_pad.c 1.0.5 2018/03/15 * * Authors: Miran Grca, * Sarah Walker, @@ -270,7 +270,7 @@ static void sw_a0_over(void *p) sw->trigger_time = TIMER_USEC * 10000; } -joystick_if_t joystick_sw_pad = +const joystick_if_t joystick_sw_pad = { "Microsoft SideWinder Pad", sw_init, diff --git a/src/game/joystick_sw_pad.h b/src/game/joystick_sw_pad.h index 8e52207..0cd4132 100644 --- a/src/game/joystick_sw_pad.h +++ b/src/game/joystick_sw_pad.h @@ -8,7 +8,7 @@ * * Definitions for the Sidewinder Pro driver. * - * Version: @(#)joystick_sw_pad.h 1.0.1 2018/02/14 + * Version: @(#)joystick_sw_pad.h 1.0.2 2018/03/15 * * Authors: Miran Grca, * Sarah Walker, @@ -35,4 +35,4 @@ * USA. */ -extern joystick_if_t joystick_sw_pad; +extern const joystick_if_t joystick_sw_pad; diff --git a/src/game/joystick_tm_fcs.c b/src/game/joystick_tm_fcs.c index 5d42576..01bf9dd 100644 --- a/src/game/joystick_tm_fcs.c +++ b/src/game/joystick_tm_fcs.c @@ -8,7 +8,7 @@ * * Implementation of Thrust Master Flight Control System. * - * Version: @(#)tm_fcs.c 1.0.2 2018/03/10 + * Version: @(#)tm_fcs.c 1.0.3 2018/03/15 * * Authors: Miran Grca, * Sarah Walker, @@ -112,7 +112,7 @@ static void tm_fcs_a0_over(void *p) { } -joystick_if_t joystick_tm_fcs = +const joystick_if_t joystick_tm_fcs = { "Thrustmaster Flight Control System", tm_fcs_init, diff --git a/src/game/joystick_tm_fcs.h b/src/game/joystick_tm_fcs.h index b7a2d3c..7ada355 100644 --- a/src/game/joystick_tm_fcs.h +++ b/src/game/joystick_tm_fcs.h @@ -8,7 +8,7 @@ * * Definitions for the Flight Control System driver. * - * Version: @(#)joystick_tm_fcs.h 1.0.1 2018/02/14 + * Version: @(#)joystick_tm_fcs.h 1.0.2 2018/03/15 * * Authors: Miran Grca, * Sarah Walker, @@ -35,4 +35,4 @@ * USA. */ -extern joystick_if_t joystick_tm_fcs; +extern const joystick_if_t joystick_tm_fcs; diff --git a/src/intel_flash.c b/src/intel_flash.c index 73dc20d..1adc41c 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -8,7 +8,7 @@ * * Implementation of the Intel 2 Mbit 8-bit flash devices. * - * Version: @(#)intel_flash.c 1.0.3 2018/02/22 + * Version: @(#)intel_flash.c 1.0.4 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -270,25 +270,25 @@ void *intel_flash_init(uint8_t type) return flash; } -void *intel_flash_bxb_ami_init(device_t *info) +void *intel_flash_bxb_ami_init(const device_t *info) { return intel_flash_init(info->local); } /* For AMI BIOS'es - Intel 28F001BXT with high address pin inverted. */ -void *intel_flash_bxt_ami_init(device_t *info) +void *intel_flash_bxt_ami_init(const device_t *info) { return intel_flash_init(info->local); } /* For Award BIOS'es - Intel 28F001BXT with high address pin not inverted. */ -void *intel_flash_bxt_init(device_t *info) +void *intel_flash_bxt_init(const device_t *info) { return intel_flash_init(info->local); } /* For Acer BIOS'es - Intel 28F001BXB. */ -void *intel_flash_bxb_init(device_t *info) +void *intel_flash_bxb_init(const device_t *info) { return intel_flash_init(info->local); } @@ -308,7 +308,7 @@ void intel_flash_close(void *p) } -device_t intel_flash_bxt_ami_device = +const device_t intel_flash_bxt_ami_device = { "Intel 28F001BXT Flash BIOS", 0, FLASH_INVERT, @@ -318,7 +318,7 @@ device_t intel_flash_bxt_ami_device = NULL, NULL, NULL, NULL, NULL }; -device_t intel_flash_bxb_ami_device = +const device_t intel_flash_bxb_ami_device = { "Intel 28F001BXB Flash BIOS", 0, FLASH_IS_BXB | FLASH_INVERT, @@ -328,7 +328,7 @@ device_t intel_flash_bxb_ami_device = NULL, NULL, NULL, NULL, NULL }; -device_t intel_flash_bxt_device = +const device_t intel_flash_bxt_device = { "Intel 28F001BXT Flash BIOS", 0, 0, @@ -338,7 +338,7 @@ device_t intel_flash_bxt_device = NULL, NULL, NULL, NULL, NULL }; -device_t intel_flash_bxb_device = +const device_t intel_flash_bxb_device = { "Intel 28F001BXB Flash BIOS", 0, FLASH_IS_BXB, diff --git a/src/keyboard.c b/src/keyboard.c index 31fa2f0..1e11b8a 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -8,7 +8,7 @@ * * General keyboard driver interface. * - * Version: @(#)keyboard.c 1.0.2 2018/02/28 + * Version: @(#)keyboard.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -55,7 +55,7 @@ static int oldkey[512]; #if 0 static int keydelay[512]; #endif -static scancode *scan_table; /* scancode table for keyboard */ +static const scancode *scan_table; /* scancode table for keyboard */ static uint8_t caps_lock = 0; static uint8_t num_lock = 0; @@ -79,7 +79,7 @@ keyboard_init(void) void -keyboard_set_table(scancode *ptr) +keyboard_set_table(const scancode *ptr) { scan_table = ptr; } @@ -110,7 +110,7 @@ fake_shift_needed(uint16_t scan) void key_process(uint16_t scan, int down) { - scancode *codes = scan_table; + const scancode *codes = scan_table; int c; if (! keyboard_scan) return; @@ -250,7 +250,7 @@ keyboard_input(int down, uint16_t scan) static uint8_t keyboard_do_break(uint16_t scan) { - scancode *codes = scan_table; + const scancode *codes = scan_table; if (AT && ((keyboard_mode & 3) == 3)) { if (!keyboard_set3_all_break && !recv_key[scan] && @@ -304,7 +304,7 @@ keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl) void keyboard_set_states(uint8_t cl, uint8_t nl, uint8_t sl) { - scancode *codes = scan_table; + const scancode *codes = scan_table; int i; diff --git a/src/keyboard.h b/src/keyboard.h index 4897fea..abfe22e 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -8,7 +8,7 @@ * * Definitions for the keyboard interface. * - * Version: @(#)keyboard.h 1.0.2 2018/02/28 + * Version: @(#)keyboard.h 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -69,7 +69,7 @@ extern int64_t keyboard_delay; extern void (*keyboard_send)(uint16_t val); extern void kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val)); -extern scancode scancode_xt[512]; +extern const scancode scancode_xt[512]; extern uint8_t keyboard_set3_flags[512]; extern uint8_t keyboard_set3_all_repeat; @@ -78,20 +78,20 @@ extern int mouse_queue_start, mouse_queue_end; extern int mouse_scan; #ifdef EMU_DEVICE_H -extern device_t keyboard_xt_device; -extern device_t keyboard_tandy_device; -extern device_t keyboard_at_device; -extern device_t keyboard_at_ami_device; -extern device_t keyboard_at_toshiba_device; -extern device_t keyboard_ps2_device; -extern device_t keyboard_ps2_ami_device; -extern device_t keyboard_ps2_mca_device; -extern device_t keyboard_ps2_quadtel_device; +extern const device_t keyboard_xt_device; +extern const device_t keyboard_tandy_device; +extern const device_t keyboard_at_device; +extern const device_t keyboard_at_ami_device; +extern const device_t keyboard_at_toshiba_device; +extern const device_t keyboard_ps2_device; +extern const device_t keyboard_ps2_ami_device; +extern const device_t keyboard_ps2_mca_device; +extern const device_t keyboard_ps2_quadtel_device; #endif extern void keyboard_init(void); extern void keyboard_close(void); -extern void keyboard_set_table(scancode *ptr); +extern void keyboard_set_table(const scancode *ptr); extern void keyboard_poll_host(void); extern void keyboard_process(void); extern uint16_t keyboard_convert(int ch); diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 855ba22..d655228 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -8,7 +8,7 @@ * * Intel 8042 (AT keyboard controller) emulation. * - * Version: @(#)keyboard_at.c 1.0.6 2018/03/13 + * Version: @(#)keyboard_at.c 1.0.7 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -172,7 +172,7 @@ static atkbd_t *CurrentKbd = NULL; // FIXME: remove!!! --FvK /* Non-translated to translated scan codes. */ -static uint8_t nont_to_t[256] = { +static const uint8_t nont_to_t[256] = { 0xFF, 0x43, 0x41, 0x3F, 0x3D, 0x3B, 0x3C, 0x58, 0x64, 0x44, 0x42, 0x40, 0x3E, 0x0F, 0x29, 0x59, 0x65, 0x38, 0x2A, 0x70, 0x1D, 0x10, 0x02, 0x5A, @@ -207,7 +207,7 @@ static uint8_t nont_to_t[256] = { 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; -static scancode scancode_set1[512] = { +static const scancode scancode_set1[512] = { { { -1},{ -1} }, { { 0x01,-1},{ 0x81,-1} }, { { 0x02,-1},{ 0x82,-1} }, { { 0x03,-1},{ 0x83,-1} }, /*000*/ { { 0x04,-1},{ 0x84,-1} }, { { 0x05,-1},{ 0x85,-1} }, { { 0x06,-1},{ 0x86,-1} }, { { 0x07,-1},{ 0x87,-1} }, /*004*/ { { 0x08,-1},{ 0x88,-1} }, { { 0x09,-1},{ 0x89,-1} }, { { 0x0a,-1},{ 0x8a,-1} }, { { 0x0b,-1},{ 0x8b,-1} }, /*008*/ @@ -337,7 +337,7 @@ static scancode scancode_set1[512] = { { { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xfe,-1},{ -1} }, { {0xe0,0xff,-1},{ -1} } /*1fc*/ }; -static scancode scancode_set2[512] = { +static const scancode scancode_set2[512] = { { { -1},{ -1} }, { { 0x76,-1},{ 0xF0,0x76,-1} }, { { 0x16,-1},{ 0xF0,0x16,-1} }, { { 0x1E,-1},{ 0xF0,0x1E,-1} }, /*000*/ { { 0x26,-1},{ 0xF0,0x26,-1} }, { { 0x25,-1},{ 0xF0,0x25,-1} }, { { 0x2E,-1},{ 0xF0,0x2E,-1} }, { { 0x36,-1},{ 0xF0,0x36,-1} }, /*004*/ { { 0x3D,-1},{ 0xF0,0x3D,-1} }, { { 0x3E,-1},{ 0xF0,0x3E,-1} }, { { 0x46,-1},{ 0xF0,0x46,-1} }, { { 0x45,-1},{ 0xF0,0x45,-1} }, /*008*/ @@ -467,7 +467,7 @@ static scancode scancode_set2[512] = { { { -1},{ -1} }, { { -1},{ -1} }, { {0xe0,0xfe,-1},{0xe0,0xF0,0xFE,-1} }, { {0xe0,0xff,-1},{0xe0,0xF0,0xFF,-1} } /*1fc*/ }; -static scancode scancode_set3[512] = { +static const scancode scancode_set3[512] = { { { -1},{ -1} }, { { 0x08,-1},{ 0xf0,0x08,-1} }, { { 0x16,-1},{ 0xf0,0x16,-1} }, { { 0x1E,-1},{ 0xf0,0x1E,-1} }, /*000*/ { { 0x26,-1},{ 0xf0,0x26,-1} }, { { 0x25,-1},{ 0xf0,0x25,-1} }, { { 0x2E,-1},{ 0xf0,0x2E,-1} }, { { 0x36,-1},{ 0xf0,0x36,-1} }, /*004*/ { { 0x3D,-1},{ 0xf0,0x3D,-1} }, { { 0x3E,-1},{ 0xf0,0x3E,-1} }, { { 0x46,-1},{ 0xf0,0x46,-1} }, { { 0x45,-1},{ 0xf0,0x45,-1} }, /*008*/ @@ -616,7 +616,7 @@ kbdlog(const char *fmt, ...) static void kbd_setmap(atkbd_t *kbd) { - scancode *map = NULL; + const scancode *map = NULL; switch (keyboard_mode & 3) { case 1: @@ -1907,7 +1907,7 @@ kbd_reset(void *priv) static void * -kbd_init(device_t *info) +kbd_init(const device_t *info) { atkbd_t *kbd; @@ -1939,17 +1939,21 @@ kbd_init(device_t *info) case KBC_VEN_GENERIC: kbd->write64_ven = &kbd_write64_generic; break; + case KBC_VEN_AMI: kbd->write60_ven = &kbd_write60_ami; kbd->write64_ven = &kbd_write64_ami; break; + case KBC_VEN_IBM_MCA: kbd->write64_ven = &kbd_write64_ibm_mca; break; + case KBC_VEN_QUADTEL: kbd->write60_ven = &kbd_write60_quadtel; kbd->write64_ven = &kbd_write64_quadtel; break; + case KBC_VEN_TOSHIBA: kbd->write60_ven = &kbd_write60_toshiba; kbd->write64_ven = &kbd_write64_toshiba; @@ -1985,7 +1989,7 @@ kbd_close(void *priv) } -device_t keyboard_at_device = { +const device_t keyboard_at_device = { "PC/AT Keyboard", 0, KBC_TYPE_ISA | KBC_VEN_GENERIC, @@ -1995,7 +1999,7 @@ device_t keyboard_at_device = { NULL, NULL, NULL, NULL }; -device_t keyboard_at_ami_device = { +const device_t keyboard_at_ami_device = { "PC/AT Keyboard (AMI)", 0, KBC_TYPE_ISA | KBC_VEN_AMI, @@ -2005,7 +2009,7 @@ device_t keyboard_at_ami_device = { NULL, NULL, NULL, NULL }; -device_t keyboard_at_toshiba_device = { +const device_t keyboard_at_toshiba_device = { "PC/AT Keyboard (Toshiba)", 0, KBC_TYPE_ISA | KBC_VEN_TOSHIBA, @@ -2015,7 +2019,7 @@ device_t keyboard_at_toshiba_device = { NULL, NULL, NULL, NULL }; -device_t keyboard_ps2_device = { +const device_t keyboard_ps2_device = { "PS/2 Keyboard", 0, KBC_TYPE_PS2_1 | KBC_VEN_GENERIC, @@ -2025,7 +2029,7 @@ device_t keyboard_ps2_device = { NULL, NULL, NULL, NULL }; -device_t keyboard_ps2_ami_device = { +const device_t keyboard_ps2_ami_device = { "PS/2 Keyboard (AMI)", 0, KBC_TYPE_PS2_1 | KBC_VEN_AMI, @@ -2035,7 +2039,7 @@ device_t keyboard_ps2_ami_device = { NULL, NULL, NULL, NULL }; -device_t keyboard_ps2_mca_device = { +const device_t keyboard_ps2_mca_device = { "PS/2 Keyboard", 0, KBC_TYPE_PS2_1 | KBC_VEN_IBM_MCA, @@ -2045,7 +2049,7 @@ device_t keyboard_ps2_mca_device = { NULL, NULL, NULL, NULL }; -device_t keyboard_ps2_quadtel_device = { +const device_t keyboard_ps2_quadtel_device = { "PS/2 Keyboard (Quadtel/MegaPC)", 0, KBC_TYPE_PS2_1 | KBC_VEN_QUADTEL, diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index 0cee757..892e537 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -8,7 +8,7 @@ * * Implementation of the XT-style keyboard. * - * Version: @(#)keyboard_xt.c 1.0.3 2018/03/09 + * Version: @(#)keyboard_xt.c 1.0.4 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -76,7 +76,7 @@ typedef struct { /*XT keyboard has no escape scancodes, and no scancodes beyond 53*/ -scancode scancode_xt[512] = { +const scancode scancode_xt[512] = { { {-1}, {-1} }, { {0x01, -1}, {0x81, -1} }, { {0x02, -1}, {0x82, -1} }, { {0x03, -1}, {0x83, -1} }, { {0x04, -1}, {0x84, -1} }, { {0x05, -1}, {0x85, -1} }, @@ -429,7 +429,7 @@ kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val)) void kbd_adddata_ex(uint16_t val) { - kbd_adddata_process(val, kbd_adddata); + kbd_adddata_process(val, kbd_adddata); } @@ -546,7 +546,7 @@ kbd_reset(void *priv) static void * -kbd_init(device_t *info) +kbd_init(const device_t *info) { xtkbd_t *kbd; @@ -590,7 +590,7 @@ kbd_close(void *priv) } -device_t keyboard_xt_device = { +const device_t keyboard_xt_device = { "PC/XT Keyboard", 0, 0, @@ -600,7 +600,7 @@ device_t keyboard_xt_device = { NULL, NULL, NULL, NULL }; -device_t keyboard_tandy_device = { +const device_t keyboard_tandy_device = { "Tandy 1000 Keyboard", 0, 1, diff --git a/src/lpt.c b/src/lpt.c index a4ff090..352dd73 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -8,7 +8,7 @@ * * Implementation of the LPT style parallel ports. * - * Version: @(#)lpt.c 1.0.1 2018/02/14 + * Version: @(#)lpt.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -47,200 +47,254 @@ #include "sound/snd_lpt_dss.h" -char lpt_device_names[3][16]; +char lpt_device_names[3][16]; -static struct -{ - const char *name; - const char *internal_name; - lpt_device_t *device; -} lpt_devices[] = -{ - {"None", "none", NULL}, - {"Disney Sound Source", "dss", &dss_device}, - {"LPT DAC / Covox Speech Thing", "lpt_dac", &lpt_dac_device}, - {"Stereo LPT DAC", "lpt_dac_stereo", &lpt_dac_stereo_device}, - {"", "", NULL} +static const struct { + const char *name; + const char *internal_name; + const lpt_device_t *device; +} lpt_devices[] = { + { "None", "none", NULL }, + { "Disney Sound Source", "dss", &dss_device }, + { "LPT DAC / Covox Speech Thing", "lpt_dac", &lpt_dac_device }, + { "Stereo LPT DAC", "lpt_dac_stereo", &lpt_dac_stereo_device }, + { "", "", NULL } }; -char *lpt_device_get_name(int id) + +static const lpt_device_t *lpt_device_ts[3]; +static void *lpt_device_ps[3]; +static uint8_t lpt_dats[3], lpt_ctrls[3]; +static uint16_t lpt_addr[3] = { + 0x0378, 0x0278, 0x03bc +}; + + +static void +lpt_write(int i, uint16_t port, uint8_t val, void *priv) { - if (strlen((char *)lpt_devices[id].name) == 0) - return NULL; - return (char *)lpt_devices[id].name; -} -char *lpt_device_get_internal_name(int id) -{ - if (strlen((char *)lpt_devices[id].internal_name) == 0) - return NULL; - return (char *)lpt_devices[id].internal_name; + switch (port & 3) { + case 0: + if (lpt_device_ts[i]) + lpt_device_ts[i]->write_data(val, lpt_device_ps[i]); + lpt_dats[i] = val; + break; + + case 2: + if (lpt_device_ts[i]) + lpt_device_ts[i]->write_ctrl(val, lpt_device_ps[i]); + lpt_ctrls[i] = val; + break; + } } -static lpt_device_t *lpt_device_ts[3]; -static void *lpt_device_ps[3]; -void lpt_devices_init() +static uint8_t +lpt_read(int i, uint16_t port, void *priv) { - int i = 0; - int c; + uint8_t ret = 0xff; - for (i = 0; i < 3; i++) { - c = 0; + switch (port & 3) { + case 0: + ret = lpt_dats[i]; + break; - while ((char *)strcmp(lpt_devices[c].internal_name, lpt_device_names[i]) && strlen((char *)lpt_devices[c].internal_name) != 0) - c++; + case 1: + if (lpt_device_ts[i]) + ret = lpt_device_ts[i]->read_status(lpt_device_ps[i]); + else ret = 0x00; + break; - if (strlen((char *)lpt_devices[c].internal_name) == 0) - lpt_device_ts[i] = NULL; - else - { - lpt_device_ts[i] = lpt_devices[c].device; - if (lpt_device_ts[i]) - lpt_device_ps[i] = lpt_device_ts[i]->init(); - } + case 2: + ret = lpt_ctrls[i]; + break; + } + + return(ret); +} + + +static void +lpt1_write(uint16_t port, uint8_t val, void *priv) +{ + lpt_write(0, port, val, priv); +} + + +static uint8_t +lpt1_read(uint16_t port, void *priv) +{ + return(lpt_read(0, port, priv)); +} + + +static void +lpt2_write(uint16_t port, uint8_t val, void *priv) +{ + lpt_write(1, port, val, priv); +} + + +static uint8_t +lpt2_read(uint16_t port, void *priv) +{ + return(lpt_read(1, port, priv)); +} + + +static void +lpt3_write(uint16_t port, uint8_t val, void *priv) +{ + lpt_write(2, port, val, priv); +} + + +static uint8_t +lpt3_read(uint16_t port, void *priv) +{ + return(lpt_read(2, port, priv)); +} + + +void +lpt_init(void) +{ + if (lpt_enabled) { + lpt_addr[0] = 0x378; + io_sethandler(lpt_addr[0], 3, + lpt1_read,NULL,NULL, lpt1_write,NULL,NULL, NULL); + + lpt_addr[1] = 0x278; + io_sethandler(lpt_addr[1], 3, + lpt2_read,NULL,NULL, lpt2_write,NULL,NULL, NULL); + } +} + + +void +lpt_devices_close(void) +{ + int i; + + for (i = 0; i < 3; i++) { + if (lpt_device_ts[i]) + lpt_device_ts[i]->close(lpt_device_ps[i]); + lpt_device_ts[i] = NULL; + } +} + + +void +lpt1_init(uint16_t port) +{ + if (lpt_enabled) { + lpt_addr[0] = port; + io_sethandler(lpt_addr[0], 3, + lpt1_read,NULL,NULL, lpt1_write,NULL,NULL, NULL); + } +} + + +void +lpt1_remove(void) +{ + if (lpt_enabled) { + io_removehandler(lpt_addr[0], 3, + lpt1_read,NULL,NULL, lpt1_write,NULL,NULL, NULL); + } +} + + +void +lpt2_init(uint16_t port) +{ + if (lpt_enabled) { + lpt_addr[1] = port; + io_sethandler(lpt_addr[1], 3, + lpt2_read,NULL,NULL, lpt2_write,NULL,NULL, NULL); + } +} + + +void +lpt2_remove(void) +{ + if (lpt_enabled) { + io_removehandler(lpt_addr[1], 3, + lpt2_read,NULL,NULL, lpt2_write,NULL,NULL, NULL); + } +} + + +void +lpt2_remove_ams(void) +{ + if (lpt_enabled) { + io_removehandler(0x0379, 2, + lpt2_read,NULL,NULL, lpt2_write,NULL,NULL, NULL); + } +} + + +void +lpt3_init(uint16_t port) +{ + if (lpt_enabled) { + lpt_addr[2] = port; + io_sethandler(lpt_addr[2], 3, + lpt3_read,NULL,NULL, lpt3_write,NULL,NULL, NULL); + } +} + + +void +lpt3_remove(void) +{ + if (lpt_enabled) { + io_removehandler(lpt_addr[2], 3, + lpt3_read,NULL,NULL, lpt3_write,NULL,NULL, NULL); + } +} + + +void +lpt_devices_init(void) +{ + int c, i; + + for (i = 0; i < 3; i++) { + c = 0; + + while ((char *)strcmp(lpt_devices[c].internal_name, lpt_device_names[i]) && strlen((char *)lpt_devices[c].internal_name) != 0) + c++; + + if (strlen((char *)lpt_devices[c].internal_name) == 0) + lpt_device_ts[i] = NULL; + else { + lpt_device_ts[i] = lpt_devices[c].device; + if (lpt_device_ts[i]) + lpt_device_ps[i] = lpt_device_ts[i]->init(); } + } } -void lpt_devices_close() -{ - int i = 0; - for (i = 0; i < 3; i++) { - if (lpt_device_ts[i]) - lpt_device_ts[i]->close(lpt_device_ps[i]); - lpt_device_ts[i] = NULL; - } +char * +lpt_device_get_name(int id) +{ + if (strlen((char *)lpt_devices[id].name) == 0) + return(NULL); + + return((char *)lpt_devices[id].name); } -static uint8_t lpt_dats[3], lpt_ctrls[3]; -void lpt_write(int i, uint16_t port, uint8_t val, void *priv) +char * +lpt_device_get_internal_name(int id) { - switch (port & 3) - { - case 0: - if (lpt_device_ts[i]) - lpt_device_ts[i]->write_data(val, lpt_device_ps[i]); - lpt_dats[i] = val; - break; - case 2: - if (lpt_device_ts[i]) - lpt_device_ts[i]->write_ctrl(val, lpt_device_ps[i]); - lpt_ctrls[i] = val; - break; - } -} -uint8_t lpt_read(int i, uint16_t port, void *priv) -{ - switch (port & 3) - { - case 0: - return lpt_dats[i]; - case 1: - if (lpt_device_ts[i]) - return lpt_device_ts[i]->read_status(lpt_device_ps[i]); - return 0; - case 2: - return lpt_ctrls[i]; - } - return 0xff; -} + if (strlen((char *)lpt_devices[id].internal_name) == 0) + return(NULL); -void lpt1_write(uint16_t port, uint8_t val, void *priv) -{ - lpt_write(0, port, val, priv); -} - -uint8_t lpt1_read(uint16_t port, void *priv) -{ - return lpt_read(0, port, priv); -} - -void lpt2_write(uint16_t port, uint8_t val, void *priv) -{ - lpt_write(1, port, val, priv); -} - -uint8_t lpt2_read(uint16_t port, void *priv) -{ - return lpt_read(1, port, priv); -} - -void lpt3_write(uint16_t port, uint8_t val, void *priv) -{ - lpt_write(2, port, val, priv); -} - -uint8_t lpt3_read(uint16_t port, void *priv) -{ - return lpt_read(2, port, priv); -} - -uint16_t lpt_addr[3] = { 0x378, 0x278, 0x3bc }; - -void lpt_init(void) -{ - if (lpt_enabled) - { - io_sethandler(0x0378, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); - io_sethandler(0x0278, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); - lpt_addr[0] = 0x378; - lpt_addr[1] = 0x278; - } -} - -void lpt1_init(uint16_t port) -{ - if (lpt_enabled) - { - io_sethandler(port, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); - lpt_addr[0] = port; - } -} -void lpt1_remove(void) -{ - if (lpt_enabled) - { - io_removehandler(lpt_addr[0], 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); - } -} -void lpt2_init(uint16_t port) -{ - if (lpt_enabled) - { - io_sethandler(port, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); - lpt_addr[1] = port; - } -} -void lpt2_remove(void) -{ - if (lpt_enabled) - { - io_removehandler(lpt_addr[1], 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); - } -} - -void lpt2_remove_ams(void) -{ - if (lpt_enabled) - { - io_removehandler(0x0379, 0x0002, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); - } -} - -void lpt3_init(uint16_t port) -{ - if (lpt_enabled) - { - io_sethandler(port, 0x0003, lpt3_read, NULL, NULL, lpt3_write, NULL, NULL, NULL); - lpt_addr[2] = port; - } -} -void lpt3_remove(void) -{ - if (lpt_enabled) - { - io_removehandler(lpt_addr[2], 0x0003, lpt3_read, NULL, NULL, lpt3_write, NULL, NULL, NULL); - } + return((char *)lpt_devices[id].internal_name); } diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 3726f2d..3a866a3 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -32,7 +32,7 @@ * BIOSES: I need to re-do the bios.txt format so we can load non-BIOS * ROM files for a given machine, such as font roms here.. * - * Version: @(#)m_amstrad.c 1.0.2 2018/03/09 + * Version: @(#)m_amstrad.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -578,7 +578,7 @@ vid_speed_change_1512(void *priv) } -static device_t vid_1512_device = { +static const device_t vid_1512_device = { "Amstrad PC1512 (video)", 0, 0, NULL, vid_close_1512, NULL, @@ -742,7 +742,7 @@ vid_speed_changed_1640(void *priv) } -static device_t vid_1640_device = { +static const device_t vid_1640_device = { "Amstrad PC1640 (video)", 0, 0, NULL, vid_close_1640, NULL, @@ -880,7 +880,7 @@ vid_speed_changed_200(void *priv) } -static device_t vid_200_device = { +static const device_t vid_200_device = { "Amstrad PC200 (video)", 0, 0, NULL, vid_close_200, NULL, @@ -1222,7 +1222,7 @@ ams_read(uint16_t port, void *priv) void -machine_amstrad_init(machine_t *model) +machine_amstrad_init(const machine_t *model) { amstrad_t *ams; @@ -1252,7 +1252,7 @@ machine_amstrad_init(machine_t *model) switch(model->id) { case ROM_PC1512: device_add(&fdc_xt_device); - if (gfxcard == GFX_INTERNAL) { + if (vid_card == VID_INTERNAL) { vid_init_1512(ams); device_add_ex(&vid_1512_device, ams->vid); } @@ -1260,7 +1260,7 @@ machine_amstrad_init(machine_t *model) case ROM_PC1640: device_add(&fdc_xt_device); - if (gfxcard == GFX_INTERNAL) { + if (vid_card == VID_INTERNAL) { vid_init_1640(ams); device_add_ex(&vid_1640_device, ams->vid); } @@ -1268,7 +1268,7 @@ machine_amstrad_init(machine_t *model) case ROM_PC200: device_add(&fdc_xt_device); - if (gfxcard == GFX_INTERNAL) { + if (vid_card == VID_INTERNAL) { vid_init_200(ams); device_add_ex(&vid_200_device, ams->vid); } @@ -1276,21 +1276,21 @@ machine_amstrad_init(machine_t *model) case ROM_PC2086: device_add(&fdc_at_actlow_device); - if (gfxcard == GFX_INTERNAL) { + if (vid_card == VID_INTERNAL) { device_add(¶dise_pvga1a_pc2086_device); } break; case ROM_PC3086: device_add(&fdc_at_actlow_device); - if (gfxcard == GFX_INTERNAL) { + if (vid_card == VID_INTERNAL) { device_add(¶dise_pvga1a_pc3086_device); } break; case ROM_MEGAPC: device_add(&fdc_at_actlow_device); - if (gfxcard == GFX_INTERNAL) { + if (vid_card == VID_INTERNAL) { device_add(¶dise_wd90c11_megapc_device); } break; diff --git a/src/machine/m_at.c b/src/machine/m_at.c index e2a2d72..cfe1261 100644 --- a/src/machine/m_at.c +++ b/src/machine/m_at.c @@ -8,7 +8,7 @@ * * Standard PC/AT implementation. * - * Version: @(#)m_at.c 1.0.1 2018/02/14 + * Version: @(#)m_at.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -57,7 +57,7 @@ void -machine_at_common_init(machine_t *model) +machine_at_common_init(const machine_t *model) { machine_common_init(model); @@ -76,7 +76,7 @@ machine_at_common_init(machine_t *model) void -machine_at_init(machine_t *model) +machine_at_init(const machine_t *model) { machine_at_common_init(model); @@ -85,7 +85,7 @@ machine_at_init(machine_t *model) void -machine_at_ps2_init(machine_t *model) +machine_at_ps2_init(const machine_t *model) { machine_at_common_init(model); @@ -94,7 +94,7 @@ machine_at_ps2_init(machine_t *model) void -machine_at_common_ide_init(machine_t *model) +machine_at_common_ide_init(const machine_t *model) { machine_at_common_init(model); @@ -103,7 +103,7 @@ machine_at_common_ide_init(machine_t *model) void -machine_at_ide_init(machine_t *model) +machine_at_ide_init(const machine_t *model) { machine_at_init(model); @@ -112,7 +112,7 @@ machine_at_ide_init(machine_t *model) void -machine_at_ps2_ide_init(machine_t *model) +machine_at_ps2_ide_init(const machine_t *model) { machine_at_ps2_init(model); @@ -121,7 +121,7 @@ machine_at_ps2_ide_init(machine_t *model) void -machine_at_top_remap_init(machine_t *model) +machine_at_top_remap_init(const machine_t *model) { machine_at_init(model); @@ -130,7 +130,7 @@ machine_at_top_remap_init(machine_t *model) void -machine_at_ide_top_remap_init(machine_t *model) +machine_at_ide_top_remap_init(const machine_t *model) { machine_at_ide_init(model); @@ -139,7 +139,7 @@ machine_at_ide_top_remap_init(machine_t *model) void -machine_at_ibm_init(machine_t *model) +machine_at_ibm_init(const machine_t *model) { machine_at_top_remap_init(model); diff --git a/src/machine/m_at_430fx.c b/src/machine/m_at_430fx.c index 0216eac..315044a 100644 --- a/src/machine/m_at_430fx.c +++ b/src/machine/m_at_430fx.c @@ -8,7 +8,7 @@ * * Implementation of the Intel 430FX PCISet chip. * - * Version: @(#)m_at_430fx.c 1.0.3 2018/03/07 + * Version: @(#)m_at_430fx.c 1.0.5 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -227,7 +227,7 @@ static void i430fx_init(void) void -machine_at_p54tp4xe_init(machine_t *model) +machine_at_p54tp4xe_init(const machine_t *model) { machine_at_ps2_init(model); @@ -248,7 +248,7 @@ machine_at_p54tp4xe_init(machine_t *model) void -machine_at_endeavor_init(machine_t *model) +machine_at_endeavor_init(const machine_t *model) { machine_at_common_init(model); device_add(&keyboard_ps2_ami_device); @@ -268,12 +268,12 @@ machine_at_endeavor_init(machine_t *model) device_add(&intel_flash_bxt_ami_device); - if (gfxcard == GFX_INTERNAL) + if (vid_card == VID_INTERNAL) device_add(&s3_phoenix_trio64_onboard_pci_device); } -device_t * +const device_t * at_endeavor_get_device(void) { return &s3_phoenix_trio64_onboard_pci_device; @@ -281,7 +281,7 @@ at_endeavor_get_device(void) void -machine_at_zappa_init(machine_t *model) +machine_at_zappa_init(const machine_t *model) { machine_at_common_init(model); device_add(&keyboard_ps2_ami_device); @@ -302,7 +302,7 @@ machine_at_zappa_init(machine_t *model) void -machine_at_mb500n_init(machine_t *model) +machine_at_mb500n_init(const machine_t *model) { machine_at_ps2_init(model); @@ -322,7 +322,7 @@ machine_at_mb500n_init(machine_t *model) void -machine_at_president_init(machine_t *model) +machine_at_president_init(const machine_t *model) { machine_at_ps2_init(model); @@ -343,7 +343,7 @@ machine_at_president_init(machine_t *model) void -machine_at_thor_init(machine_t *model) +machine_at_thor_init(const machine_t *model) { machine_at_common_init(model); device_add(&keyboard_ps2_ami_device); diff --git a/src/machine/m_at_430hx.c b/src/machine/m_at_430hx.c index 590f49f..1f6d6bd 100644 --- a/src/machine/m_at_430hx.c +++ b/src/machine/m_at_430hx.c @@ -8,7 +8,7 @@ * * Implementation of the Intel 430HX PCISet chip. * - * Version: @(#)m_at_430hx.c 1.0.2 2018/03/07 + * Version: @(#)m_at_430hx.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -236,7 +236,7 @@ acerm3a_in(uint16_t port, void *p) void -machine_at_acerm3a_init(machine_t *model) +machine_at_acerm3a_init(const machine_t *model) { machine_at_ps2_init(model); @@ -259,7 +259,7 @@ machine_at_acerm3a_init(machine_t *model) void -machine_at_acerv35n_init(machine_t *model) +machine_at_acerv35n_init(const machine_t *model) { machine_at_ps2_init(model); @@ -282,7 +282,7 @@ machine_at_acerv35n_init(machine_t *model) void -machine_at_ap53_init(machine_t *model) +machine_at_ap53_init(const machine_t *model) { machine_at_common_init(model); device_add(&keyboard_ps2_ami_device); @@ -306,7 +306,7 @@ machine_at_ap53_init(machine_t *model) void -machine_at_p55t2p4_init(machine_t *model) +machine_at_p55t2p4_init(const machine_t *model) { machine_at_ps2_init(model); @@ -327,7 +327,7 @@ machine_at_p55t2p4_init(machine_t *model) void -machine_at_p55t2s_init(machine_t *model) +machine_at_p55t2s_init(const machine_t *model) { machine_at_common_init(model); device_add(&keyboard_ps2_ami_device); diff --git a/src/machine/m_at_430lx_nx.c b/src/machine/m_at_430lx_nx.c index 1721e61..59c70a6 100644 --- a/src/machine/m_at_430lx_nx.c +++ b/src/machine/m_at_430lx_nx.c @@ -8,7 +8,7 @@ * * Implementation of the Intel 430LX and 430NX PCISet chips. * - * Version: @(#)m_at_430lx_nx.c 1.0.2 2018/03/07 + * Version: @(#)m_at_430lx_nx.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -231,7 +231,7 @@ static void i430nx_init(void) static void -machine_at_premiere_common_init(machine_t *model) +machine_at_premiere_common_init(const machine_t *model) { machine_at_common_init(model); device_add(&keyboard_ps2_ami_device); @@ -253,7 +253,7 @@ machine_at_premiere_common_init(machine_t *model) void -machine_at_batman_init(machine_t *model) +machine_at_batman_init(const machine_t *model) { machine_at_premiere_common_init(model); @@ -262,7 +262,7 @@ machine_at_batman_init(machine_t *model) void -machine_at_plato_init(machine_t *model) +machine_at_plato_init(const machine_t *model) { machine_at_premiere_common_init(model); diff --git a/src/machine/m_at_430vx.c b/src/machine/m_at_430vx.c index 22fb4e9..9cbf7a8 100644 --- a/src/machine/m_at_430vx.c +++ b/src/machine/m_at_430vx.c @@ -8,7 +8,7 @@ * * Implementation of the Intel 430VX PCISet chip. * - * Version: @(#)m_at_430vx.c 1.0.2 2018/03/07 + * Version: @(#)m_at_430vx.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -213,7 +213,7 @@ void i430vx_init(void) void -machine_at_p55tvp4_init(machine_t *model) +machine_at_p55tvp4_init(const machine_t *model) { machine_at_ps2_init(model); @@ -234,7 +234,7 @@ machine_at_p55tvp4_init(machine_t *model) void -machine_at_i430vx_init(machine_t *model) +machine_at_i430vx_init(const machine_t *model) { machine_at_ps2_init(model); @@ -255,7 +255,7 @@ machine_at_i430vx_init(machine_t *model) void -machine_at_p55va_init(machine_t *model) +machine_at_p55va_init(const machine_t *model) { machine_at_ps2_init(model); diff --git a/src/machine/m_at_440fx.c b/src/machine/m_at_440fx.c index aa62025..bb4e941 100644 --- a/src/machine/m_at_440fx.c +++ b/src/machine/m_at_440fx.c @@ -8,7 +8,7 @@ * * Implementation of the Intel 440FX PCISet chip. * - * Version: @(#)m_at_440fx.c 1.0.2 2018/03/07 + * Version: @(#)m_at_440fx.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -215,7 +215,7 @@ static void i440fx_init(void) void -machine_at_i440fx_init(machine_t *model) +machine_at_i440fx_init(const machine_t *model) { machine_at_ps2_init(model); @@ -237,7 +237,7 @@ machine_at_i440fx_init(machine_t *model) void -machine_at_s1668_init(machine_t *model) +machine_at_s1668_init(const machine_t *model) { machine_at_common_init(model); device_add(&keyboard_ps2_ami_device); diff --git a/src/machine/m_at_4gpv31.c b/src/machine/m_at_4gpv31.c index 62856ca..98619a9 100644 --- a/src/machine/m_at_4gpv31.c +++ b/src/machine/m_at_4gpv31.c @@ -11,7 +11,7 @@ * NOTE: The NEAT 82c206 code should be moved into a 82c206 module, * so it can be re-used by other boards. * - * Version: @(#)m_4gpv31.c 1.0.1 2018/02/14 + * Version: @(#)m_4gpv31.c 1.0.2 2018/03/15 * * Author: Fred N. van Kempen, * @@ -174,7 +174,7 @@ neat_init(void) void -machine_at_4gpv31_init(machine_t *model) +machine_at_4gpv31_init(const machine_t *model) { machine_at_common_ide_init(model); device_add(&keyboard_at_ami_device); diff --git a/src/machine/m_at_ali1429.c b/src/machine/m_at_ali1429.c index b3a0619..30c7592 100644 --- a/src/machine/m_at_ali1429.c +++ b/src/machine/m_at_ali1429.c @@ -8,7 +8,7 @@ * * Implementation the ALI M1429 mainboard. * - * Version: @(#)m_at_ali1429.c 1.0.1 2018/02/14 + * Version: @(#)m_at_ali1429.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -133,7 +133,7 @@ static void ali1429_init(void) void -machine_at_ali1429_init(machine_t *model) +machine_at_ali1429_init(const machine_t *model) { ali1429_reset(); diff --git a/src/machine/m_at_commodore.c b/src/machine/m_at_commodore.c index 89f5eaa..4b1668b 100644 --- a/src/machine/m_at_commodore.c +++ b/src/machine/m_at_commodore.c @@ -8,7 +8,7 @@ * * Implementation of the Commodore PC3 system. * - * Version: @(#)m_at_commodore.c 1.0.1 2018/02/14 + * Version: @(#)m_at_commodore.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -50,44 +50,52 @@ #include "machine.h" -static void cbm_io_write(uint16_t port, uint8_t val, void *p) +static void +pc3_write(uint16_t port, uint8_t val, void *priv) { - lpt1_remove(); - lpt2_remove(); - switch (val & 3) - { - case 1: - lpt1_init(0x3bc); - break; - case 2: - lpt1_init(0x378); - break; - case 3: - lpt1_init(0x278); - break; - } - switch (val & 0xc) - { - case 0x4: - serial_setup(1, 0x2f8, 3); - break; - case 0x8: - serial_setup(1, 0x3f8, 4); - break; - } + lpt1_remove(); + lpt2_remove(); + + switch (val & 3) { + case 1: + lpt1_init(0x3bc); + break; + + case 2: + lpt1_init(0x378); + break; + + case 3: + lpt1_init(0x278); + break; + } + + switch (val & 0xc) { + case 0x4: + serial_setup(1, 0x2f8, 3); + break; + + case 0x8: + serial_setup(1, 0x3f8, 4); + break; + } } -static void cbm_io_init() + +static void +pc3_init(void) { - io_sethandler(0x0230, 0x0001, NULL,NULL,NULL, cbm_io_write,NULL,NULL, NULL); + io_sethandler(0x0230, 1, + NULL,NULL,NULL, pc3_write,NULL,NULL, NULL); } void -machine_at_cmdpc_init(machine_t *model) +machine_at_cmdpc_init(const machine_t *model) { - machine_at_ide_top_remap_init(model); - device_add(&fdc_at_device); + machine_at_ide_top_remap_init(model); - cbm_io_init(); + device_add(&fdc_at_device); + + pc3_init(); } diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 3d32936..0a94abf 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -8,7 +8,7 @@ * * Emulation of various Compaq PC's. * - * Version: @(#)m_at_compaq.c 1.0.2 2018/03/09 + * Version: @(#)m_at_compaq.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -118,7 +118,7 @@ write_raml(uint32_t addr, uint32_t val, void *priv) void -machine_at_compaq_init(machine_t *model) +machine_at_compaq_init(const machine_t *model) { machine_at_top_remap_init(model); device_add(&fdc_at_device); diff --git a/src/machine/m_at_headland.c b/src/machine/m_at_headland.c index fff1400..a548169 100644 --- a/src/machine/m_at_headland.c +++ b/src/machine/m_at_headland.c @@ -8,7 +8,7 @@ * * Implementation of the HEADLAND AT286 chipset. * - * Version: @(#)m_at_headland.c 1.0.1 2018/02/14 + * Version: @(#)m_at_headland.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -56,61 +56,60 @@ static int headland_index; static uint8_t headland_regs[256]; -static void headland_write(uint16_t addr, uint8_t val, void *priv) +static void +headland_write(uint16_t addr, uint8_t val, void *priv) { - uint8_t old_val; + uint8_t old_val; - if (addr & 1) - { - old_val = headland_regs[headland_index]; + if (addr & 1) { + old_val = headland_regs[headland_index]; - if (headland_index == 0xc1 && !is486) val = 0; - headland_regs[headland_index] = val; - if (headland_index == 0x82) - { - shadowbios = val & 0x10; - shadowbios_write = !(val & 0x10); - if (shadowbios) - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); - else - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - } - else if (headland_index == 0x87) - { - if ((val & 1) && !(old_val & 1)) - softresetx86(); - } - } - else - headland_index = val; + if (headland_index == 0xc1 && !is486) val = 0; + headland_regs[headland_index] = val; + if (headland_index == 0x82) { + shadowbios = val & 0x10; + shadowbios_write = !(val & 0x10); + if (shadowbios) + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); + else + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + } else if (headland_index == 0x87) { + if ((val & 1) && !(old_val & 1)) + softresetx86(); + } + } else + headland_index = val; } -static uint8_t headland_read(uint16_t addr, void *priv) +static uint8_t +headland_read(uint16_t addr, void *priv) { - if (addr & 1) - { - if ((headland_index >= 0xc0 || headland_index == 0x20) && cpu_iscyrix) - return 0xff; /*Don't conflict with Cyrix config registers*/ - return headland_regs[headland_index]; - } - return headland_index; + if (addr & 1) { + if ((headland_index >= 0xc0 || headland_index == 0x20) && cpu_iscyrix) + return(0xff); /*Don't conflict with Cyrix config registers*/ + return(headland_regs[headland_index]); + } + + return(headland_index); } -static void headland_init(void) +static void +headland_init(void) { - io_sethandler(0x0022, 0x0002, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); + io_sethandler(0x0022, 2, + headland_read,NULL,NULL, headland_write,NULL,NULL, NULL); } void -machine_at_headland_init(machine_t *model) +machine_at_headland_init(const machine_t *model) { - machine_at_common_ide_init(model); + machine_at_common_ide_init(model); - device_add(&keyboard_at_ami_device); - device_add(&fdc_at_device); + device_add(&keyboard_at_ami_device); + device_add(&fdc_at_device); - headland_init(); + headland_init(); } diff --git a/src/machine/m_at_neat.c b/src/machine/m_at_neat.c index e6b381e..3ca936f 100644 --- a/src/machine/m_at_neat.c +++ b/src/machine/m_at_neat.c @@ -10,7 +10,7 @@ * * This is the chipset used in the AMI 286 clone model. * - * Version: @(#)m_at_neat.c 1.0.1 2018/02/14 + * Version: @(#)m_at_neat.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -51,95 +51,102 @@ #include "machine.h" -static uint8_t neat_regs[256]; -static int neat_index; -static int neat_emspage[4]; +static uint8_t neat_regs[256]; +static int neat_index; +static int neat_emspage[4]; -static void neat_write(uint16_t port, uint8_t val, void *priv) +static void +neat_write(uint16_t port, uint8_t val, void *priv) { - switch (port) - { - case 0x22: - neat_index = val; - break; - - case 0x23: - neat_regs[neat_index] = val; - switch (neat_index) - { - case 0x6E: /*EMS page extension*/ - neat_emspage[3] = (neat_emspage[3] & 0x7F) | (( val & 3) << 7); - neat_emspage[2] = (neat_emspage[2] & 0x7F) | (((val >> 2) & 3) << 7); - neat_emspage[1] = (neat_emspage[1] & 0x7F) | (((val >> 4) & 3) << 7); - neat_emspage[0] = (neat_emspage[0] & 0x7F) | (((val >> 6) & 3) << 7); - break; - } - break; + switch (port) { + case 0x22: + neat_index = val; + break; - case 0x0208: case 0x0209: case 0x4208: case 0x4209: - case 0x8208: case 0x8209: case 0xC208: case 0xC209: - neat_emspage[port >> 14] = (neat_emspage[port >> 14] & 0x180) | (val & 0x7F); - break; - } + case 0x23: + neat_regs[neat_index] = val; + switch (neat_index) { + case 0x6E: /*EMS page extension*/ + neat_emspage[3] = (neat_emspage[3] & 0x7F) | (( val & 3) << 7); + neat_emspage[2] = (neat_emspage[2] & 0x7F) | (((val >> 2) & 3) << 7); + neat_emspage[1] = (neat_emspage[1] & 0x7F) | (((val >> 4) & 3) << 7); + neat_emspage[0] = (neat_emspage[0] & 0x7F) | (((val >> 6) & 3) << 7); + break; + } + break; + + case 0x0208: case 0x0209: case 0x4208: case 0x4209: + case 0x8208: case 0x8209: case 0xC208: case 0xC209: + neat_emspage[port >> 14] = (neat_emspage[port >> 14] & 0x180) | (val & 0x7F); + break; + } } -static uint8_t neat_read(uint16_t port, void *priv) +static uint8_t +neat_read(uint16_t port, void *priv) { - switch (port) - { - case 0x22: - return neat_index; - - case 0x23: - return neat_regs[neat_index]; - } - return 0xff; + switch (port) { + case 0x22: + return(neat_index); + + case 0x23: + return(neat_regs[neat_index]); + } + + return(0xff); } #if NOT_USED -static void neat_writeems(uint32_t addr, uint8_t val) +static void +neat_writeems(uint32_t addr, uint8_t val) { - ram[(neat_emspage[(addr >> 14) & 3] << 14) + (addr & 0x3FFF)] = val; + ram[(neat_emspage[(addr >> 14) & 3] << 14) + (addr & 0x3fff)] = val; } static uint8_t neat_readems(uint32_t addr) { - return ram[(neat_emspage[(addr >> 14) & 3] << 14) + (addr & 0x3FFF)]; + return(ram[(neat_emspage[(addr >> 14) & 3] << 14) + (addr & 0x3fff)]); } #endif -static void neat_init(void) +static void +neat_init(void) { - io_sethandler(0x0022, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); - io_sethandler(0x0208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); - io_sethandler(0x4208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); - io_sethandler(0x8208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); - io_sethandler(0xc208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); + io_sethandler(0x0022, 2, + neat_read,NULL,NULL, neat_write,NULL,NULL, NULL); + io_sethandler(0x0208, 2, + neat_read,NULL,NULL, neat_write,NULL,NULL, NULL); + io_sethandler(0x4208, 2, + neat_read,NULL,NULL, neat_write,NULL,NULL, NULL); + io_sethandler(0x8208, 2, + neat_read,NULL,NULL, neat_write,NULL,NULL, NULL); + io_sethandler(0xc208, 2, + neat_read,NULL,NULL, neat_write,NULL,NULL, NULL); } void -machine_at_neat_init(machine_t *model) +machine_at_neat_init(const machine_t *model) { - machine_at_init(model); - device_add(&fdc_at_device); + machine_at_init(model); + device_add(&fdc_at_device); - neat_init(); + neat_init(); } void -machine_at_neat_ami_init(machine_t *model) +machine_at_neat_ami_init(const machine_t *model) { - machine_at_common_init(model); + machine_at_common_init(model); - device_add(&keyboard_at_ami_device); - device_add(&fdc_at_device); + device_add(&keyboard_at_ami_device); + device_add(&fdc_at_device); - neat_init(); + neat_init(); } diff --git a/src/machine/m_at_opti495.c b/src/machine/m_at_opti495.c index bbce5c3..b295e0f 100644 --- a/src/machine/m_at_opti495.c +++ b/src/machine/m_at_opti495.c @@ -260,7 +260,7 @@ Note: the block address is forced to be a multiple of the block size by ignoring the appropriate number of the least-significant bits SeeAlso: #P0178,#P0187 * - * Version: @(#)m_at_opti495.c 1.0.1 2018/02/14 + * Version: @(#)m_at_opti495.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -303,81 +303,85 @@ SeeAlso: #P0178,#P0187 #include "machine.h" -static uint8_t optiregs[0x10]; -static int optireg; +static uint8_t optiregs[0x10]; +static int optireg; -static void opti495_write(uint16_t addr, uint8_t val, void *p) +static void +opti495_write(uint16_t addr, uint8_t val, void *p) { - switch (addr) - { - case 0x22: - optireg=val; - break; - case 0x24: - pclog("OPTI: writing reg %02X %02X\n",optireg,val); - if (optireg>=0x20 && optireg<=0x2C) - { - optiregs[optireg-0x20]=val; - if (optireg == 0x21) - { - cpu_cache_ext_enabled = val & 0x10; - cpu_update_waitstates(); - } - if (optireg == 0x22) - { - shadowbios = !(val & 0x80); - shadowbios_write = val & 0x80; - if (shadowbios) - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); - else - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - } - } - break; - } + switch (addr) { + case 0x22: + optireg=val; + break; + + case 0x24: + pclog("OPTI: writing reg %02X %02X\n",optireg,val); + if (optireg>=0x20 && optireg<=0x2C) { + optiregs[optireg-0x20]=val; + if (optireg == 0x21) { + cpu_cache_ext_enabled = val & 0x10; + cpu_update_waitstates(); + } + if (optireg == 0x22) { + shadowbios = !(val & 0x80); + shadowbios_write = val & 0x80; + if (shadowbios) + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); + else + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + } + } + break; + } } -static uint8_t opti495_read(uint16_t addr, void *p) +static uint8_t +opti495_read(uint16_t addr, void *p) { - switch (addr) - { - case 0x24: - if (optireg>=0x20 && optireg<=0x2C) return optiregs[optireg-0x20]; - break; - } - return 0xFF; + switch (addr) { + case 0x24: + if (optireg>=0x20 && optireg<=0x2c) + return(optiregs[optireg-0x20]); + break; + } + + return(0xff); } -static void opti495_init(void) +static void +opti495_init(void) { - io_sethandler(0x0022, 0x0001, opti495_read, NULL, NULL, opti495_write, NULL, NULL, NULL); - io_sethandler(0x0024, 0x0001, opti495_read, NULL, NULL, opti495_write, NULL, NULL, NULL); - optiregs[0x22-0x20] = 0x80; + io_sethandler(0x0022, 1, + opti495_read,NULL,NULL, opti495_write,NULL,NULL, NULL); + io_sethandler(0x0024, 1, + opti495_read,NULL,NULL, opti495_write,NULL,NULL, NULL); + + optiregs[0x22-0x20] = 0x80; } void -machine_at_opti495_init(machine_t *model) +machine_at_opti495_init(const machine_t *model) { - machine_at_common_ide_init(model); + machine_at_common_ide_init(model); - device_add(&keyboard_at_device); - device_add(&fdc_at_device); + device_add(&keyboard_at_device); + device_add(&fdc_at_device); - opti495_init(); + opti495_init(); } void -machine_at_opti495_ami_init(machine_t *model) +machine_at_opti495_ami_init(const machine_t *model) { - machine_at_common_ide_init(model); + machine_at_common_ide_init(model); - device_add(&keyboard_at_ami_device); - device_add(&fdc_at_device); + device_add(&keyboard_at_ami_device); + device_add(&fdc_at_device); - opti495_init(); + opti495_init(); } diff --git a/src/machine/m_at_scat.c b/src/machine/m_at_scat.c index 0a8f85a..6ffc6c3 100644 --- a/src/machine/m_at_scat.c +++ b/src/machine/m_at_scat.c @@ -10,7 +10,7 @@ * * Re-worked version based on the 82C235 datasheet and errata. * - * Version: @(#)m_at_scat.c 1.0.2 2018/03/04 + * Version: @(#)m_at_scat.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Original by GreatPsycho for PCem. @@ -662,7 +662,7 @@ scat_init(void) static void -scatsx_init() +scatsx_init(void) { int i; @@ -733,7 +733,7 @@ scatsx_init() void -machine_at_scat_init(machine_t *model) +machine_at_scat_init(const machine_t *model) { machine_at_init(model); device_add(&fdc_at_device); @@ -743,7 +743,7 @@ machine_at_scat_init(machine_t *model) void -machine_at_scatsx_init(machine_t *model) +machine_at_scatsx_init(const machine_t *model) { machine_at_init(model); device_add(&fdc_at_device); diff --git a/src/machine/m_at_sis_85c471.c b/src/machine/m_at_sis_85c471.c index f31d746..3382487 100644 --- a/src/machine/m_at_sis_85c471.c +++ b/src/machine/m_at_sis_85c471.c @@ -12,7 +12,7 @@ * * Used by DTK PKM-0038S E-2 * - * Version: @(#)m_at_sis85c471.c 1.0.2 2018/03/07 + * Version: @(#)m_at_sis85c471.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -263,7 +263,7 @@ static void sis_85c471_init(void) void -machine_at_dtk486_init(machine_t *model) +machine_at_dtk486_init(const machine_t *model) { machine_at_ide_init(model); device_add(&fdc_at_device); diff --git a/src/machine/m_at_sis_85c496.c b/src/machine/m_at_sis_85c496.c index 9fe9683..b31bb54 100644 --- a/src/machine/m_at_sis_85c496.c +++ b/src/machine/m_at_sis_85c496.c @@ -8,7 +8,7 @@ * * Implementation of the SiS 85C496 chipset. * - * Version: @(#)m_at_sis_85c496.c 1.0.2 2018/03/07 + * Version: @(#)m_at_sis_85c496.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -197,7 +197,7 @@ static void sis_85c496_init(void) static void -machine_at_sis_85c496_common_init(machine_t *model) +machine_at_sis_85c496_common_init(const machine_t *model) { machine_at_ps2_init(model); device_add(&ide_pci_device); @@ -215,7 +215,7 @@ machine_at_sis_85c496_common_init(machine_t *model) void -machine_at_r418_init(machine_t *model) +machine_at_r418_init(const machine_t *model) { machine_at_sis_85c496_common_init(model); diff --git a/src/machine/m_at_sis_85c50x.c b/src/machine/m_at_sis_85c50x.c index ac3fcae..f652970 100644 --- a/src/machine/m_at_sis_85c50x.c +++ b/src/machine/m_at_sis_85c50x.c @@ -8,7 +8,7 @@ * * Emulation of the SiS 85C50x PCI chips. * - * Version: @(#)m_at_sis_85c50x.c 1.0.1 2018/02/14 + * Version: @(#)m_at_sis_85c50x.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, diff --git a/src/machine/m_at_t3100e.c b/src/machine/m_at_t3100e.c index 8c2a30d..24355da 100644 --- a/src/machine/m_at_t3100e.c +++ b/src/machine/m_at_t3100e.c @@ -117,15 +117,15 @@ * bit 2 set for single-pixel LCD font * bits 0,1 for display font * - * Version: @(#)m_at_t3100e.c 1.0.3 2018/03/05 + * Version: @(#)m_at_t3100e.c 1.0.4 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, - * Sarah Walker, + * John Elliott, * * Copyright 2017,2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. - * Copyright 2008-2018 Sarah Walker. + * Copyright 2017-2018 John Elliott. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -165,8 +165,6 @@ extern uint8_t *ram; /* Physical RAM */ -void at_init(); - static const int t3100e_log = 0; @@ -716,7 +714,7 @@ static void upper_write_raml(uint32_t addr, uint32_t val, void *priv) -void machine_at_t3100e_init(machine_t *model) +void machine_at_t3100e_init(const machine_t *model) { int pg; diff --git a/src/machine/m_at_t3100e.h b/src/machine/m_at_t3100e.h index 0de5cf6..187a5cd 100644 --- a/src/machine/m_at_t3100e.h +++ b/src/machine/m_at_t3100e.h @@ -8,7 +8,7 @@ * * Definitions for the Toshiba T3100e system. * - * Version: @(#)m_at_t3100e.h 1.0.2 2018/03/05 + * Version: @(#)m_at_t3100e.h 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define MACHINE_T3100E_H -extern device_t t3100e_device; +extern const device_t t3100e_device; extern void t3100e_notify_set(uint8_t value); diff --git a/src/machine/m_at_t3100e_vid.c b/src/machine/m_at_t3100e_vid.c index f02ecd9..80e39c5 100644 --- a/src/machine/m_at_t3100e_vid.c +++ b/src/machine/m_at_t3100e_vid.c @@ -22,7 +22,7 @@ * 61 50 52 0F 19 06 19 19 02 0D 0B 0C MONO * 2D 28 22 0A 67 00 64 67 02 03 06 07 640x400 * - * Version: @(#)m_at_t3100e_vid.c 1.0.3 2018/03/07 + * Version: @(#)m_at_t3100e_vid.c 1.0.4 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -703,7 +703,7 @@ void t3100e_recalcattrs(t3100e_t *t3100e) } -void *t3100e_init(device_t *info) +void *t3100e_init(const device_t *info) { t3100e_t *t3100e = malloc(sizeof(t3100e_t)); memset(t3100e, 0, sizeof(t3100e_t)); @@ -748,7 +748,7 @@ void t3100e_speed_changed(void *p) t3100e_recalctimings(t3100e); } -device_t t3100e_device = +const device_t t3100e_device = { "Toshiba T3100e", 0, diff --git a/src/machine/m_at_wd76c10.c b/src/machine/m_at_wd76c10.c index cf06de6..a67be06 100644 --- a/src/machine/m_at_wd76c10.c +++ b/src/machine/m_at_wd76c10.c @@ -8,7 +8,7 @@ * * Implementation of the WD76C10 system controller. * - * Version: @(#)m_at_wd76c10.c 1.0.1 2018/02/14 + * Version: @(#)m_at_wd76c10.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -64,127 +64,126 @@ static fdc_t *wd76c10_fdc; static uint16_t wd76c10_read(uint16_t port, void *priv) { - switch (port) - { - case 0x0092: - return wd76c10_0092; - - case 0x2072: - return wd76c10_2072; + switch (port) { + case 0x0092: + return wd76c10_0092; - case 0x2872: - return wd76c10_2872; - - case 0x5872: - return wd76c10_5872; - } - return 0; + case 0x2072: + return wd76c10_2072; + + case 0x2872: + return wd76c10_2872; + + case 0x5872: + return wd76c10_5872; + } + + return(0); } static void wd76c10_write(uint16_t port, uint16_t val, void *priv) { - pclog("WD76C10 write %04X %04X\n", port, val); - switch (port) - { - case 0x0092: - wd76c10_0092 = val; - - mem_a20_alt = val & 2; - mem_a20_recalc(); - break; - - case 0x2072: - wd76c10_2072 = val; - - serial_remove(1); - if (!(val & 0x10)) - { - switch ((val >> 5) & 7) - { - case 1: serial_setup(1, 0x3f8, 4); break; - case 2: serial_setup(1, 0x2f8, 4); break; - case 3: serial_setup(1, 0x3e8, 4); break; - case 4: serial_setup(1, 0x2e8, 4); break; - default: serial_remove(1); break; - } - } - serial_remove(2); - if (!(val & 0x01)) - { - switch ((val >> 1) & 7) - { - case 1: serial_setup(2, 0x3f8, 3); break; - case 2: serial_setup(2, 0x2f8, 3); break; - case 3: serial_setup(2, 0x3e8, 3); break; - case 4: serial_setup(2, 0x2e8, 3); break; - default: serial_remove(1); break; - } - } - break; + pclog("WD76C10 write %04X %04X\n", port, val); - case 0x2872: - wd76c10_2872 = val; - - fdc_remove(wd76c10_fdc); - if (!(val & 1)) - fdc_set_base(wd76c10_fdc, 0x03f0); - break; - - case 0x5872: - wd76c10_5872 = val; - break; - } + switch (port) { + case 0x0092: + wd76c10_0092 = val; + + mem_a20_alt = val & 2; + mem_a20_recalc(); + break; + + case 0x2072: + wd76c10_2072 = val; + + serial_remove(1); + if (! (val & 0x10)) { + switch ((val >> 5) & 7) { + case 1: serial_setup(1, 0x3f8, 4); break; + case 2: serial_setup(1, 0x2f8, 4); break; + case 3: serial_setup(1, 0x3e8, 4); break; + case 4: serial_setup(1, 0x2e8, 4); break; + default: serial_remove(1); break; + } + } + serial_remove(2); + if (! (val & 0x01)) { + switch ((val >> 1) & 7) { + case 1: serial_setup(2, 0x3f8, 3); break; + case 2: serial_setup(2, 0x2f8, 3); break; + case 3: serial_setup(2, 0x3e8, 3); break; + case 4: serial_setup(2, 0x2e8, 3); break; + default: serial_remove(1); break; + } + } + break; + + case 0x2872: + wd76c10_2872 = val; + + fdc_remove(wd76c10_fdc); + if (! (val & 1)) + fdc_set_base(wd76c10_fdc, 0x03f0); + break; + + case 0x5872: + wd76c10_5872 = val; + break; + } } static uint8_t wd76c10_readb(uint16_t port, void *priv) { - if (port & 1) - return wd76c10_read(port & ~1, priv) >> 8; - return wd76c10_read(port, priv) & 0xff; + if (port & 1) + return(wd76c10_read(port & ~1, priv) >> 8); + + return(wd76c10_read(port, priv) & 0xff); } static void wd76c10_writeb(uint16_t port, uint8_t val, void *priv) { - uint16_t temp = wd76c10_read(port, priv); - if (port & 1) - wd76c10_write(port & ~1, (temp & 0x00ff) | (val << 8), priv); - else - wd76c10_write(port , (temp & 0xff00) | val, priv); + uint16_t temp = wd76c10_read(port, priv); + + if (port & 1) + wd76c10_write(port & ~1, (temp & 0x00ff) | (val << 8), priv); + else + wd76c10_write(port , (temp & 0xff00) | val, priv); } -static void wd76c10_init(void) +static void +wd76c10_init(void) { - io_sethandler(0x0092, 2, - wd76c10_readb, wd76c10_read, NULL, - wd76c10_writeb, wd76c10_write, NULL, NULL); - io_sethandler(0x2072, 2, - wd76c10_readb, wd76c10_read, NULL, - wd76c10_writeb, wd76c10_write, NULL, NULL); - io_sethandler(0x2872, 2, - wd76c10_readb, wd76c10_read, NULL, - wd76c10_writeb, wd76c10_write, NULL, NULL); - io_sethandler(0x5872, 2, - wd76c10_readb, wd76c10_read, NULL, - wd76c10_writeb, wd76c10_write, NULL, NULL); + io_sethandler(0x0092, 2, + wd76c10_readb, wd76c10_read, NULL, + wd76c10_writeb, wd76c10_write, NULL, NULL); + io_sethandler(0x2072, 2, + wd76c10_readb, wd76c10_read, NULL, + wd76c10_writeb, wd76c10_write, NULL, NULL); + io_sethandler(0x2872, 2, + wd76c10_readb, wd76c10_read, NULL, + wd76c10_writeb, wd76c10_write, NULL, NULL); + io_sethandler(0x5872, 2, + wd76c10_readb, wd76c10_read, NULL, + wd76c10_writeb, wd76c10_write, NULL, NULL); } void -machine_at_wd76c10_init(machine_t *model) +machine_at_wd76c10_init(const machine_t *model) { - machine_at_common_ide_init(model); + machine_at_common_ide_init(model); - device_add(&keyboard_ps2_quadtel_device); - wd76c10_fdc = device_add(&fdc_at_device); + device_add(&keyboard_ps2_quadtel_device); + wd76c10_fdc = device_add(&fdc_at_device); - wd76c10_init(); + wd76c10_init(); - device_add(¶dise_wd90c11_megapc_device); + device_add(¶dise_wd90c11_megapc_device); } diff --git a/src/machine/m_europc.c b/src/machine/m_europc.c index 342d91e..0f72318 100644 --- a/src/machine/m_europc.c +++ b/src/machine/m_europc.c @@ -66,9 +66,7 @@ * bit 1: b8000 memory available * 0000:046a: 00 jim 250 01 jim 350 * - * WARNING THIS IS A WORK-IN-PROGRESS MODULE. USE AT OWN RISK. - * - * Version: @(#)europc.c 1.0.2 2018/03/11 + * Version: @(#)europc.c 1.0.3 2018/03/15 * * Author: Fred N. van Kempen, * @@ -546,7 +544,7 @@ jim_read(uint16_t addr, void *priv) /* Initialize the mainboard 'device' of the machine. */ static void * -europc_boot(device_t *info) +europc_boot(const device_t *info) { europc_t *sys = &europc; uint8_t b; @@ -567,15 +565,15 @@ europc_boot(device_t *info) * with values set by the user. */ b = (sys->nvr.regs[MRTC_CONF_D] & ~0x17); - switch(gfxcard) { - case GFX_CGA: /* Color, CGA */ - case GFX_COLORPLUS: /* Color, Hercules ColorPlus */ + switch(vid_card) { + case VID_CGA: /* Color, CGA */ + case VID_COLORPLUS: /* Color, Hercules ColorPlus */ b |= 0x12; /* external video, CGA80 */ break; - case GFX_MDA: /* Monochrome, MDA */ - case GFX_HERCULES: /* Monochrome, Hercules */ - case GFX_INCOLOR: /* Color, ? */ + case VID_MDA: /* Monochrome, MDA */ + case VID_HERCULES: /* Monochrome, Hercules */ + case VID_INCOLOR: /* Color, ? */ b |= 0x03; /* external video, mono */ break; @@ -674,7 +672,7 @@ europc_close(void *priv) } -static device_config_t europc_config[] = { +static const device_config_t europc_config[] = { { "js9", "JS9 Jumper (JIM)", CONFIG_INT, "", 0, { @@ -695,7 +693,7 @@ static device_config_t europc_config[] = { }; -device_t europc_device = { +const device_t europc_device = { "EuroPC System Board", 0, 0, europc_boot, europc_close, NULL, @@ -713,7 +711,7 @@ device_t europc_device = { * user. */ void -machine_europc_init(machine_t *model) +machine_europc_init(const machine_t *model) { /* Clear the machine state. */ memset(&europc, 0x00, sizeof(europc_t)); diff --git a/src/machine/m_europc_hdc.c b/src/machine/m_europc_hdc.c index 81f6f8b..471e648 100644 --- a/src/machine/m_europc_hdc.c +++ b/src/machine/m_europc_hdc.c @@ -22,7 +22,7 @@ * * Based on the original "xebec.c" from Sarah Walker. * - * Version: @(#)m_europc_hdc.c 1.0.2 2018/03/11 + * Version: @(#)m_europc_hdc.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Sarah Walker, @@ -902,7 +902,7 @@ hd20_write(uint16_t port, uint8_t val, void *priv) static void * -hd20_init(device_t *info) +hd20_init(const device_t *info) { drive_t *drive; hd20_t *dev; @@ -978,7 +978,7 @@ hd20_available(void) } -device_t europc_hdc_device = { +const device_t europc_hdc_device = { "EuroPC HD20", 0, 0, hd20_init, hd20_close, NULL, diff --git a/src/machine/m_olivetti_m24.c b/src/machine/m_olivetti_m24.c index a322b73..a7cfae5 100644 --- a/src/machine/m_olivetti_m24.c +++ b/src/machine/m_olivetti_m24.c @@ -8,7 +8,7 @@ * * Emulation of the Olivetti M24. * - * Version: @(#)m_olivetti_m24.c 1.0.2 2018/03/09 + * Version: @(#)m_olivetti_m24.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -812,7 +812,7 @@ vid_close(void *priv) } -device_t m24_device = { +const device_t m24_device = { "Olivetti M24 Video", 0, 0, NULL, vid_close, NULL, @@ -824,7 +824,7 @@ device_t m24_device = { void -machine_olim24_init(machine_t *model) +machine_olim24_init(const machine_t *model) { olim24_t *m24; diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index 0b98a9f..af17d3d 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -8,7 +8,7 @@ * * Emulation of the IBM PCjr. * - * Version: @(#)m_pcjr.c 1.0.1 2018/02/14 + * Version: @(#)m_pcjr.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -693,8 +693,6 @@ kbd_adddata(uint16_t val) } - - static void kbd_adddata_ex(uint16_t val) { @@ -711,7 +709,7 @@ speed_changed(void *priv) } -static device_config_t pcjr_config[] = { +static const device_config_t pcjr_config[] = { { "display_type", "Display type", CONFIG_SELECTION, "", PCJR_RGB, { @@ -732,7 +730,7 @@ static device_config_t pcjr_config[] = { }; -static device_t pcjr_device = { +static const device_t pcjr_device = { "IBM PCjr", 0, 0, NULL, NULL, NULL, @@ -744,7 +742,7 @@ static device_t pcjr_device = { }; -device_t * +const device_t * pcjr_get_device(void) { return &pcjr_device; @@ -752,7 +750,7 @@ pcjr_get_device(void) void -machine_pcjr_init(machine_t *model) +machine_pcjr_init(const machine_t *model) { int display_type; pcjr_t *pcjr; diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index 97f5513..dcf78fc 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -28,7 +28,7 @@ * boot. Sometimes, they do, and then it shows an "Incorrect * DOS" error message?? --FvK * - * Version: @(#)m_ps1.c 1.0.1 2018/02/14 + * Version: @(#)m_ps1.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -90,15 +90,15 @@ typedef struct { - sn76489_t sn76489; - uint8_t status, ctrl; - int64_t timer_latch, timer_count, timer_enable; - uint8_t fifo[2048]; - int fifo_read_idx, fifo_write_idx; - int fifo_threshold; - uint8_t dac_val; - int16_t buffer[SOUNDBUFLEN]; - int pos; + sn76489_t sn76489; + uint8_t status, ctrl; + int64_t timer_latch, timer_count, timer_enable; + uint8_t fifo[2048]; + int fifo_read_idx, fifo_write_idx; + int fifo_threshold; + uint8_t dac_val; + int16_t buffer[SOUNDBUFLEN]; + int pos; } ps1snd_t; typedef struct { @@ -254,7 +254,7 @@ snd_get_buffer(int32_t *buffer, int len, void *priv) static void * -snd_init(device_t *info) +snd_init(const device_t *info) { ps1snd_t *snd; @@ -283,7 +283,7 @@ snd_close(void *priv) } -static device_t snd_device = { +static const device_t snd_device = { "PS/1 Audio Card", 0, 0, snd_init, snd_close, NULL, @@ -542,7 +542,7 @@ ps1_setup(int model) lpt1_init(0x03bc); /* Initialize the video controller. */ - if (gfxcard == GFX_INTERNAL) + if (vid_card == VID_INTERNAL) device_add(&ibm_ps1_2121_device); } @@ -553,7 +553,7 @@ ps1_setup(int model) static void -ps1_common_init(machine_t *model) +ps1_common_init(const machine_t *model) { machine_common_init(model); @@ -588,7 +588,7 @@ ps1_common_init(machine_t *model) void -machine_ps1_m2011_init(machine_t *model) +machine_ps1_m2011_init(const machine_t *model) { ps1_common_init(model); @@ -597,7 +597,7 @@ machine_ps1_m2011_init(machine_t *model) void -machine_ps1_m2121_init(machine_t *model) +machine_ps1_m2121_init(const machine_t *model) { ps1_common_init(model); @@ -606,7 +606,7 @@ machine_ps1_m2121_init(machine_t *model) void -machine_ps1_m2133_init(machine_t *model) +machine_ps1_m2133_init(const machine_t *model) { ps1_common_init(model); diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index 0e403fd..eae5e71 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -8,7 +8,7 @@ * * Implementation of ISA-based PS/2 machines. * - * Version: @(#)m_ps2_isa.c 1.0.1 2018/02/14 + * Version: @(#)m_ps2_isa.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -186,7 +186,7 @@ static void ps2board_init(void) void -machine_ps2_m30_286_init(machine_t *model) +machine_ps2_m30_286_init(const machine_t *model) { machine_common_init(model); device_add(&fdc_at_ps1_device); diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index 084634c..598f089 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -8,7 +8,7 @@ * * Implementation of MCA-based PS/2 machines. * - * Version: @(#)m_ps2_mca.c 1.0.2 2018/03/12 + * Version: @(#)m_ps2_mca.c 1.0.3 2018/03/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -78,6 +78,7 @@ static struct uint8_t io_id; mem_mapping_t shadow_mapping; + mem_mapping_t split_mapping; mem_mapping_t expansion_mapping; mem_mapping_t cache_mapping; @@ -87,6 +88,7 @@ static struct uint8_t mem_regs[3]; uint32_t split_addr, split_size; + uint32_t split_phys; uint8_t mem_pos_regs[8]; uint8_t mem_2mb_pos_regs[8]; @@ -213,6 +215,36 @@ static void ps2_write_shadow_raml(uint32_t addr, uint32_t val, void *priv) mem_write_raml(addr, val, priv); } +static uint8_t ps2_read_split_ram(uint32_t addr, void *priv) +{ + addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; + return mem_read_ram(addr, priv); +} +static uint16_t ps2_read_split_ramw(uint32_t addr, void *priv) +{ + addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; + return mem_read_ramw(addr, priv); +} +static uint32_t ps2_read_split_raml(uint32_t addr, void *priv) +{ + addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; + return mem_read_raml(addr, priv); +} +static void ps2_write_split_ram(uint32_t addr, uint8_t val, void *priv) +{ + addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; + mem_write_ram(addr, val, priv); +} +static void ps2_write_split_ramw(uint32_t addr, uint16_t val, void *priv) +{ + addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; + mem_write_ramw(addr, val, priv); +} +static void ps2_write_split_raml(uint32_t addr, uint32_t val, void *priv) +{ + addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; + mem_write_raml(addr, val, priv); +} #define PS2_SETUP_IO 0x80 #define PS2_SETUP_VGA 0x20 @@ -879,7 +911,7 @@ static void ps2_mca_board_model_55sx_init() static void mem_encoding_update() { - mem_split_disable(ps2.split_size, ps2.split_addr); + mem_mapping_disable(&ps2.split_mapping); ps2.split_addr = ((uint32_t) (ps2.mem_regs[0] & 0xf)) << 20; @@ -901,12 +933,16 @@ static void mem_encoding_update() if (!(ps2.mem_regs[1] & 8)) { - if (ps2.mem_regs[1] & 4) + if (ps2.mem_regs[1] & 4) { ps2.split_size = 384; - else + ps2.split_phys = 0x80000; + } else { ps2.split_size = 256; + ps2.split_phys = 0xa0000; + } - mem_split_enable(ps2.split_size, ps2.split_addr); + mem_mapping_set_exec(&ps2.split_mapping, &ram[ps2.split_phys]); + mem_mapping_set_addr(&ps2.split_mapping, ps2.split_addr, ps2.split_size << 10); /* pclog("PS/2 Model 80-111: Split memory block enabled at %08X\n", ps2.split_addr); */ } /* else { @@ -1148,6 +1184,20 @@ static void ps2_mca_board_model_80_type2_init(int is486) ps2.mem_regs[0] |= ((mem_size/1024) & 0x0f); + mem_mapping_add(&ps2.split_mapping, + (mem_size+256) * 1024, + 256*1024, + ps2_read_split_ram, + ps2_read_split_ramw, + ps2_read_split_raml, + ps2_write_split_ram, + ps2_write_split_ramw, + ps2_write_split_raml, + &ram[0xa0000], + MEM_MAPPING_INTERNAL, + NULL); + mem_mapping_disable(&ps2.split_mapping); + if ((mem_size > 4096) && !is486) { /* Only 4 MB supported on planar, create a memory expansion card for the rest */ @@ -1207,7 +1257,7 @@ static void ps2_mca_board_model_80_type2_init(int is486) static void -machine_ps2_common_init(machine_t *model) +machine_ps2_common_init(const machine_t *model) { machine_common_init(model); device_add(&fdc_at_device); @@ -1225,7 +1275,7 @@ machine_ps2_common_init(machine_t *model) void -machine_ps2_model_50_init(machine_t *model) +machine_ps2_model_50_init(const machine_t *model) { machine_ps2_common_init(model); @@ -1234,7 +1284,7 @@ machine_ps2_model_50_init(machine_t *model) void -machine_ps2_model_55sx_init(machine_t *model) +machine_ps2_model_55sx_init(const machine_t *model) { machine_ps2_common_init(model); @@ -1243,7 +1293,7 @@ machine_ps2_model_55sx_init(machine_t *model) void -machine_ps2_model_70_type3_init(machine_t *model) +machine_ps2_model_70_type3_init(const machine_t *model) { machine_ps2_common_init(model); @@ -1251,7 +1301,7 @@ machine_ps2_model_70_type3_init(machine_t *model) } void -machine_ps2_model_70_type4_init(machine_t *model) +machine_ps2_model_70_type4_init(const machine_t *model) { machine_ps2_common_init(model); @@ -1260,7 +1310,7 @@ machine_ps2_model_70_type4_init(machine_t *model) void -machine_ps2_model_80_init(machine_t *model) +machine_ps2_model_80_init(const machine_t *model) { machine_ps2_common_init(model); diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index 0b5bc73..243b892 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -8,7 +8,7 @@ * * Emulation of Tandy models 1000, 1000HX and 1000SL2. * - * Version: @(#)m_tandy.c 1.0.1 2018/02/14 + * Version: @(#)m_tandy.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -141,7 +141,7 @@ typedef struct { } tandy_t; -static scancode scancode_tandy[512] = { +static const scancode scancode_tandy[512] = { { {-1}, {-1} }, { {0x01, -1}, {0x81, -1} }, { {0x02, -1}, {0x82, -1} }, { {0x03, -1}, {0x83, -1} }, { {0x04, -1}, {0x84, -1} }, { {0x05, -1}, {0x85, -1} }, @@ -1373,7 +1373,7 @@ vid_init(tandy_t *dev) } -static device_config_t vid_config[] = { +static const device_config_t vid_config[] = { { "display_type", "Display type", CONFIG_SELECTION, "", TANDY_RGB, { @@ -1394,7 +1394,7 @@ static device_config_t vid_config[] = { }; -static device_t vid_device = { +static const device_t vid_device = { "Tandy 1000", 0, 0, NULL, vid_close, NULL, @@ -1405,7 +1405,7 @@ static device_t vid_device = { vid_config }; -static device_t vid_device_hx = { +static const device_t vid_device_hx = { "Tandy 1000 HX", 0, 0, NULL, vid_close, NULL, @@ -1416,7 +1416,7 @@ static device_t vid_device_hx = { vid_config }; -static device_t vid_device_sl = { +static const device_t vid_device_sl = { "Tandy 1000SL2", 0, 1, NULL, vid_close, NULL, @@ -1428,14 +1428,14 @@ static device_t vid_device_sl = { }; -device_t * +const device_t * tandy1k_get_device(void) { return &vid_device; } -device_t * +const device_t * tandy1k_hx_get_device(void) { return &vid_device_hx; @@ -1521,7 +1521,7 @@ eep_write(uint16_t addr, uint8_t val, void *priv) static void * -eep_init(device_t *info) +eep_init(const device_t *info) { t1keep_t *eep; FILE *f = NULL; @@ -1568,7 +1568,7 @@ eep_close(void *priv) } -static device_t eep_device = { +static const device_t eep_device = { "Tandy 1000 EEPROM", 0, 0, eep_init, eep_close, NULL, @@ -1712,7 +1712,7 @@ init_rom(tandy_t *dev) void -machine_tandy1k_init(machine_t *model) +machine_tandy1k_init(const machine_t *model) { tandy_t *dev; diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 75b0726..e817f27 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -8,7 +8,7 @@ * * Implementation of standard IBM PC/XT class machine. * - * Version: @(#)m_xt.c 1.0.1 2018/02/14 + * Version: @(#)m_xt.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -53,7 +53,7 @@ void -machine_xt_init(machine_t *model) +machine_xt_init(const machine_t *model) { machine_common_init(model); diff --git a/src/machine/m_xt_compaq.c b/src/machine/m_xt_compaq.c index 51a33aa..fb7815c 100644 --- a/src/machine/m_xt_compaq.c +++ b/src/machine/m_xt_compaq.c @@ -8,7 +8,7 @@ * * Emulation of various Compaq XT-class PC's. * - * Version: @(#)m_xt_compaq.c 1.0.2 2018/03/04 + * Version: @(#)m_xt_compaq.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -57,7 +57,7 @@ void -machine_xt_compaq_init(machine_t *model) +machine_xt_compaq_init(const machine_t *model) { machine_common_init(model); diff --git a/src/machine/m_xt_laserxt.c b/src/machine/m_xt_laserxt.c index 1f16ac9..5b4e483 100644 --- a/src/machine/m_xt_laserxt.c +++ b/src/machine/m_xt_laserxt.c @@ -8,7 +8,7 @@ * * Emulation of the Laser XT series of machines. * - * Version: @(#)m_xt_laserxt.c 1.0.1 2018/02/14 + * Version: @(#)m_xt_laserxt.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -169,7 +169,7 @@ static void laserxt_init(void) void -machine_xt_laserxt_init(machine_t *model) +machine_xt_laserxt_init(const machine_t *model) { machine_xt_init(model); diff --git a/src/machine/m_xt_t1000.c b/src/machine/m_xt_t1000.c index c2e2563..3a523b3 100644 --- a/src/machine/m_xt_t1000.c +++ b/src/machine/m_xt_t1000.c @@ -51,15 +51,15 @@ * NOTE: Still need to figure out a way to load/save ConfigSys and * HardRAM stuff. Needs to be linked in to the NVR code. * - * Version: @(#)m_xt_t1000.c 1.0.3 2018/03/12 + * Version: @(#)m_xt_t1000.c 1.0.4 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, - * Sarah Walker, + * John Elliott, * * Copyright 2018 Fred N. van Kempen. * Copyright 2018 Miran Grca. - * Copyright 2018 Sarah Walker. + * Copyright 2017,2018 John Elliott. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -784,7 +784,7 @@ t1000_read_roml(uint32_t addr, void *priv) } -device_t * +const device_t * t1000_get_device(void) { return(&t1000_video_device); @@ -792,7 +792,7 @@ t1000_get_device(void) void -machine_xt_t1000_init(machine_t *model) +machine_xt_t1000_init(const machine_t *model) { FILE *f; int pg; @@ -862,7 +862,7 @@ machine_xt_t1000_init(machine_t *model) } -device_t * +const device_t * t1200_get_device(void) { return(&t1200_video_device); @@ -870,7 +870,7 @@ t1200_get_device(void) void -machine_xt_t1200_init(machine_t *model) +machine_xt_t1200_init(const machine_t *model) { int pg; diff --git a/src/machine/m_xt_t1000.h b/src/machine/m_xt_t1000.h index 545861e..c8cde38 100644 --- a/src/machine/m_xt_t1000.h +++ b/src/machine/m_xt_t1000.h @@ -8,7 +8,7 @@ * * Definitions for the Toshiba T1000/T1200 machines. * - * Version: @(#)m_xt_t1000.h 1.0.2 2018/03/10 + * Version: @(#)m_xt_t1000.h 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,8 +40,8 @@ # define MACHINE_T1000_H -extern device_t t1000_video_device; -extern device_t t1200_video_device; +extern const device_t t1000_video_device; +extern const device_t t1200_video_device; extern void t1000_video_options_set(uint8_t options); diff --git a/src/machine/m_xt_t1000_vid.c b/src/machine/m_xt_t1000_vid.c index 00b94c3..9a12dee 100644 --- a/src/machine/m_xt_t1000_vid.c +++ b/src/machine/m_xt_t1000_vid.c @@ -9,7 +9,7 @@ * Implementation of the Toshiba T1000 plasma display, which * has a fixed resolution of 640x200 pixels. * - * Version: @(#)m_xt_t1000_vid.c 1.0.4 2018/03/10 + * Version: @(#)m_xt_t1000_vid.c 1.0.5 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -74,45 +74,50 @@ static uint8_t language; static uint8_t st_video_options; static int8_t st_display_internal = -1; -void t1000_video_options_set(uint8_t options) -{ - st_video_options = options & 1; - st_video_options |= language; -} -void t1000_display_set(uint8_t internal) +void +t1000_video_options_set(uint8_t options) { - st_display_internal = (int8_t)internal; -} - -uint8_t t1000_display_get() -{ - return (uint8_t)st_display_internal; + st_video_options = options & 1; + st_video_options |= language; } -typedef struct t1000_t +void +t1000_display_set(uint8_t internal) { - mem_mapping_t mapping; + st_display_internal = (int8_t)internal; +} - cga_t cga; /* The CGA is used for the external + +uint8_t +t1000_display_get(void) +{ + return((uint8_t)st_display_internal); +} + + +typedef struct t1000_t { + mem_mapping_t mapping; + + cga_t cga; /* The CGA is used for the external * display; most of its registers are * ignored by the plasma display. */ - int font; /* Current font, 0-3 */ - int enabled; /* Hardware enabled, 0 or 1 */ - int internal; /* Using internal display? */ - uint8_t attrmap; /* Attribute mapping register */ + int font; /* Current font, 0-3 */ + int enabled; /* Hardware enabled, 0 or 1 */ + int internal; /* Using internal display? */ + uint8_t attrmap; /* Attribute mapping register */ - int dispontime, dispofftime; - - int linepos, displine; - int vc; - int dispon; - int vsynctime; - uint8_t video_options; + int dispontime, dispofftime; - uint8_t *vram; + int linepos, displine; + int vc; + int dispon; + int vsynctime; + uint8_t video_options; + + uint8_t *vram; } t1000_t; @@ -122,7 +127,8 @@ static uint8_t t1000_read(uint32_t addr, void *p); static void t1000_recalcattrs(t1000_t *t1000); -static void t1000_out(uint16_t addr, uint8_t val, void *p) +static void +t1000_out(uint16_t addr, uint8_t val, void *p) { t1000_t *t1000 = (t1000_t *)p; switch (addr) @@ -158,7 +164,9 @@ static void t1000_out(uint16_t addr, uint8_t val, void *p) } } -static uint8_t t1000_in(uint16_t addr, void *p) + +static uint8_t +t1000_in(uint16_t addr, void *p) { t1000_t *t1000 = (t1000_t *)p; uint8_t val; @@ -178,9 +186,8 @@ static uint8_t t1000_in(uint16_t addr, void *p) } - - -static void t1000_write(uint32_t addr, uint8_t val, void *p) +static void +t1000_write(uint32_t addr, uint8_t val, void *p) { t1000_t *t1000 = (t1000_t *)p; egawrites++; @@ -189,8 +196,10 @@ static void t1000_write(uint32_t addr, uint8_t val, void *p) t1000->vram[addr & 0x3fff] = val; cycles -= 4; } - -static uint8_t t1000_read(uint32_t addr, void *p) + + +static uint8_t +t1000_read(uint32_t addr, void *p) { t1000_t *t1000 = (t1000_t *)p; egareads++; @@ -201,8 +210,8 @@ static uint8_t t1000_read(uint32_t addr, void *p) } - -static void t1000_recalctimings(t1000_t *t1000) +static void +t1000_recalctimings(t1000_t *t1000) { double disptime; double _dispontime, _dispofftime; @@ -219,8 +228,10 @@ static void t1000_recalctimings(t1000_t *t1000) t1000->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); } + /* Draw a row of text in 80-column mode */ -static void t1000_text_row80(t1000_t *t1000) +static void +t1000_text_row80(t1000_t *t1000) { uint32_t cols[2]; int x, c; @@ -291,8 +302,10 @@ static void t1000_text_row80(t1000_t *t1000) } } + /* Draw a row of text in 40-column mode */ -static void t1000_text_row40(t1000_t *t1000) +static void +t1000_text_row40(t1000_t *t1000) { uint32_t cols[2]; int x, c; @@ -367,8 +380,10 @@ static void t1000_text_row40(t1000_t *t1000) } } + /* Draw a line in CGA 640x200 mode */ -static void t1000_cgaline6(t1000_t *t1000) +static void +t1000_cgaline6(t1000_t *t1000) { int x, c; uint8_t dat; @@ -399,9 +414,11 @@ static void t1000_cgaline6(t1000_t *t1000) } } + /* Draw a line in CGA 320x200 mode. Here the CGA colours are converted to * dither patterns: colour 1 to 25% grey, colour 2 to 50% grey */ -static void t1000_cgaline4(t1000_t *t1000) +static void +t1000_cgaline4(t1000_t *t1000) { int x, c; uint8_t dat, pattern; @@ -455,7 +472,9 @@ static void t1000_cgaline4(t1000_t *t1000) } } -static void t1000_poll(void *p) + +static void +t1000_poll(void *p) { t1000_t *t1000 = (t1000_t *)p; @@ -561,7 +580,9 @@ static void t1000_poll(void *p) } } -static void t1000_recalcattrs(t1000_t *t1000) + +static void +t1000_recalcattrs(t1000_t *t1000) { int n; @@ -658,7 +679,8 @@ static void t1000_recalcattrs(t1000_t *t1000) } -static void *t1000_init(device_t *info) +static void * +t1000_init(const device_t *info) { t1000_t *t1000 = malloc(sizeof(t1000_t)); memset(t1000, 0, sizeof(t1000_t)); @@ -689,7 +711,9 @@ static void *t1000_init(device_t *info) return t1000; } -static void t1000_close(void *p) + +static void +t1000_close(void *p) { t1000_t *t1000 = (t1000_t *)p; @@ -697,14 +721,17 @@ static void t1000_close(void *p) free(t1000); } -static void t1000_speed_changed(void *p) + +static void +t1000_speed_changed(void *p) { t1000_t *t1000 = (t1000_t *)p; t1000_recalctimings(t1000); } -static device_config_t t1000_config[] = + +static const device_config_t t1000_config[] = { { .name = "display_language", @@ -729,7 +756,7 @@ static device_config_t t1000_config[] = }; -device_t t1000_video_device = { +const device_t t1000_video_device = { "Toshiba T1000 Video", 0, 0, t1000_init, t1000_close, NULL, @@ -740,8 +767,7 @@ device_t t1000_video_device = { t1000_config }; - -device_t t1200_video_device = { +const device_t t1200_video_device = { "Toshiba T1200 Video", 0, 0, t1000_init, t1000_close, NULL, diff --git a/src/machine/m_xt_xi8088.c b/src/machine/m_xt_xi8088.c index 42a89e2..27e3bc1 100644 --- a/src/machine/m_xt_xi8088.c +++ b/src/machine/m_xt_xi8088.c @@ -8,7 +8,7 @@ * * Implementation of the Xi8088 open-source machine. * - * Version: @(#)m_xt_xi8088.c 1.0.1 2018/03/05 + * Version: @(#)m_xt_xi8088.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -59,121 +59,128 @@ #include "m_xt_xi8088.h" -typedef struct xi8088_t -{ - uint8_t turbo; +typedef struct { + uint8_t turbo; - int turbo_setting; - int bios_128kb; + int turbo_setting; + int bios_128kb; } xi8088_t; + static xi8088_t xi8088; -uint8_t xi8088_turbo_get() + +uint8_t +xi8088_turbo_get(void) { - return xi8088.turbo; + return(xi8088.turbo); } -void xi8088_turbo_set(uint8_t value) -{ - if (!xi8088.turbo_setting) - return; - xi8088.turbo = value; - if (!value) - { - pclog("Xi8088 turbo off\n"); - int c = cpu; - cpu = 0; /* 8088/4.77 */ - cpu_set(); - cpu = c; - } - else - { - pclog("Xi8088 turbo on\n"); - cpu_set(); - } +void +xi8088_turbo_set(uint8_t value) +{ + if (! xi8088.turbo_setting) return; + + xi8088.turbo = value; + if (! value) { + pclog("Xi8088 turbo off\n"); + int c = cpu; + cpu = 0; /* 8088/4.77 */ + cpu_set(); + cpu = c; + } else { + pclog("Xi8088 turbo on\n"); + cpu_set(); + } } -void xi8088_bios_128kb_set(int val) + +void +xi8088_bios_128kb_set(int val) { - xi8088.bios_128kb = val; + xi8088.bios_128kb = val; } -int xi8088_bios_128kb() + +int +xi8088_bios_128kb(void) { - return xi8088.bios_128kb; + return(xi8088.bios_128kb); } -static void *xi8088_init() -{ - /* even though the bios by default turns the turbo off when controlling by hotkeys, we always start at full speed */ - xi8088.turbo = 1; - xi8088.turbo_setting = device_get_config_int("turbo_setting"); - return &xi8088; +static void * +xi8088_init(const device_t *info) +{ + /* even though the bios by default turns the turbo off when controlling by hotkeys, we always start at full speed */ + xi8088.turbo = 1; + xi8088.turbo_setting = device_get_config_int("turbo_setting"); + + return(&xi8088); } -static device_config_t xi8088_config[] = + +static const device_config_t xi8088_config[] = { - { - .name = "turbo_setting", - .description = "Turbo", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Always at selected speed", - .value = 0 - }, - { - .description = "Hotkeys (starts off)", - .value = 1 - } - }, - .default_int = 0 - }, - { - .type = -1 - } + { + .name = "turbo_setting", + .description = "Turbo", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "Always at selected speed", + .value = 0 + }, + { + .description = "Hotkeys (starts off)", + .value = 1 + } + }, + .default_int = 0 + }, + { + .type = -1 + } }; -device_t xi8088_device = +const device_t xi8088_device = { - "Xi8088", - 0, - 0, - xi8088_init, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - xi8088_config + "Xi8088", + 0, 0, + xi8088_init, NULL, NULL, + NULL, + NULL, + NULL, + NULL, + xi8088_config }; -device_t * + +const device_t * xi8088_get_device(void) { return &xi8088_device; } -void machine_xt_xi8088_init(machine_t *model) + +void +machine_xt_xi8088_init(const machine_t *model) { if (biosmask < 0x010000) xi8088_bios_128kb_set(0); else xi8088_bios_128kb_set(1); - /* TODO: set UMBs? See if PCem always sets when we have > 640KB ram and avoids conflicts when a peripheral uses the same memory space */ - machine_common_init(model); + /* TODO: set UMBs? See if PCem always sets when we have > 640KB ram and avoids conflicts when a peripheral uses the same memory space */ + machine_common_init(model); device_add(&fdc_xt_device); device_add(&keyboard_ps2_device); - nmi_init(); + nmi_init(); nvr_at_init(8); - pic2_init(); + pic2_init(); if (joystick_type != 7) - device_add(&gameport_device); + device_add(&gameport_device); } diff --git a/src/machine/m_xt_xi8088.h b/src/machine/m_xt_xi8088.h index 21b9602..e7786c3 100644 --- a/src/machine/m_xt_xi8088.h +++ b/src/machine/m_xt_xi8088.h @@ -8,7 +8,7 @@ * * Definitions for the Xi8088 open-source machine. * - * Version: @(#)m_xt_xi8088.h 1.0.1 2018/03/05 + * Version: @(#)m_xt_xi8088.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -41,7 +41,7 @@ #ifdef EMU_DEVICE_H -extern device_t xi8088_device; +extern const device_t xi8088_device; #endif diff --git a/src/machine/machine.c b/src/machine/machine.c index 79afd27..49e30ad 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -8,7 +8,7 @@ * * Handling of the emulated machines. * - * Version: @(#)machine.c 1.0.5 2018/03/07 + * Version: @(#)machine.c 1.0.7 2018/03/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -68,12 +68,13 @@ machine_init(void) pclog("Initializing as \"%s\"\n", machine_getname()); - ide_set_bus_master(NULL, NULL, NULL); - /* Set up the architecture flags. */ AT = IS_ARCH(machine, MACHINE_AT); PCI = IS_ARCH(machine, MACHINE_PCI); + /* Reset memory and the MMU. */ + mem_reset(); + /* Load the machine's ROM BIOS. */ wcscpy(temp, MACHINES_PATH); plat_append_slash(temp); @@ -83,6 +84,8 @@ machine_init(void) /* Activate the ROM BIOS. */ mem_add_bios(); + ide_set_bus_master(NULL, NULL, NULL); + /* All good, boot the machine! */ machines[machine].init(&machines[machine]); } @@ -131,7 +134,7 @@ machine_detect(void) void -machine_common_init(machine_t *model) +machine_common_init(const machine_t *model) { /* System devices first. */ dma_init(); diff --git a/src/machine/machine.h b/src/machine/machine.h index bdb098a..317b9da 100644 --- a/src/machine/machine.h +++ b/src/machine/machine.h @@ -8,7 +8,7 @@ * * Handling of the emulated machines. * - * Version: @(#)machine.h 1.0.9 2018/03/12 + * Version: @(#)machine.h 1.0.10 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -209,23 +209,23 @@ typedef struct _machine_ { void *cpus; #endif } cpu[5]; - int fixed_gfxcard; + int fixed_vidcard; /* FIXME: change to "fixed_flags" */ int flags; int min_ram, max_ram; int ram_granularity; int nvrsz; - void (*init)(struct _machine_ *); + void (*init)(const struct _machine_ *); #ifdef EMU_DEVICE_H - device_t *(*get_device)(void); + const device_t *(*get_device)(void); #else - void *get_device; + const void *get_device; #endif void (*nvr_close)(void); } machine_t; /* Global variables. */ -extern machine_t machines[]; +extern const machine_t machines[]; extern int machine; extern int romset; extern int AT, PCI; @@ -243,7 +243,7 @@ extern int machine_available(int id); extern int machine_detect(void); extern void machine_init(void); #ifdef EMU_DEVICE_H -extern device_t *machine_getdevice(int machine); +extern const device_t *machine_getdevice(int machine); #endif extern int machine_getromset_ex(int m); extern char *machine_get_internal_name_ex(int m); @@ -252,116 +252,116 @@ extern void machine_close(void); /* Initialization functions for boards and systems. */ -extern void machine_common_init(machine_t *); +extern void machine_common_init(const machine_t *); -extern void machine_at_common_init(machine_t *); -extern void machine_at_init(machine_t *); -extern void machine_at_ps2_init(machine_t *); -extern void machine_at_common_ide_init(machine_t *); -extern void machine_at_ide_init(machine_t *); -extern void machine_at_ps2_ide_init(machine_t *); -extern void machine_at_top_remap_init(machine_t *); -extern void machine_at_ide_top_remap_init(machine_t *); +extern void machine_at_common_init(const machine_t *); +extern void machine_at_init(const machine_t *); +extern void machine_at_ps2_init(const machine_t *); +extern void machine_at_common_ide_init(const machine_t *); +extern void machine_at_ide_init(const machine_t *); +extern void machine_at_ps2_ide_init(const machine_t *); +extern void machine_at_top_remap_init(const machine_t *); +extern void machine_at_ide_top_remap_init(const machine_t *); -extern void machine_at_ibm_init(machine_t *); +extern void machine_at_ibm_init(const machine_t *); -extern void machine_at_t3100e_init(machine_t *); +extern void machine_at_t3100e_init(const machine_t *); -extern void machine_at_p54tp4xe_init(machine_t *); -extern void machine_at_endeavor_init(machine_t *); -extern void machine_at_zappa_init(machine_t *); -extern void machine_at_mb500n_init(machine_t *); -extern void machine_at_president_init(machine_t *); -extern void machine_at_thor_init(machine_t *); +extern void machine_at_p54tp4xe_init(const machine_t *); +extern void machine_at_endeavor_init(const machine_t *); +extern void machine_at_zappa_init(const machine_t *); +extern void machine_at_mb500n_init(const machine_t *); +extern void machine_at_president_init(const machine_t *); +extern void machine_at_thor_init(const machine_t *); -extern void machine_at_acerm3a_init(machine_t *); -extern void machine_at_acerv35n_init(machine_t *); -extern void machine_at_ap53_init(machine_t *); -extern void machine_at_p55t2p4_init(machine_t *); -extern void machine_at_p55t2s_init(machine_t *); +extern void machine_at_acerm3a_init(const machine_t *); +extern void machine_at_acerv35n_init(const machine_t *); +extern void machine_at_ap53_init(const machine_t *); +extern void machine_at_p55t2p4_init(const machine_t *); +extern void machine_at_p55t2s_init(const machine_t *); -extern void machine_at_batman_init(machine_t *); -extern void machine_at_plato_init(machine_t *); +extern void machine_at_batman_init(const machine_t *); +extern void machine_at_plato_init(const machine_t *); -extern void machine_at_p55tvp4_init(machine_t *); -extern void machine_at_i430vx_init(machine_t *); -extern void machine_at_p55va_init(machine_t *); +extern void machine_at_p55tvp4_init(const machine_t *); +extern void machine_at_i430vx_init(const machine_t *); +extern void machine_at_p55va_init(const machine_t *); #if defined(DEV_BRANCH) && defined(USE_I686) -extern void machine_at_i440fx_init(machine_t *); -extern void machine_at_s1668_init(machine_t *); +extern void machine_at_i440fx_init(const machine_t *); +extern void machine_at_s1668_init(const machine_t *); #endif -extern void machine_at_ali1429_init(machine_t *); -extern void machine_at_cmdpc_init(machine_t *); +extern void machine_at_ali1429_init(const machine_t *); +extern void machine_at_cmdpc_init(const machine_t *); -extern void machine_at_headland_init(machine_t *); -extern void machine_at_neat_init(machine_t *); -extern void machine_at_neat_ami_init(machine_t *); -extern void machine_at_opti495_init(machine_t *); -extern void machine_at_opti495_ami_init(machine_t *); -extern void machine_at_scat_init(machine_t *); -extern void machine_at_scatsx_init(machine_t *); -extern void machine_at_compaq_init(machine_t *); +extern void machine_at_headland_init(const machine_t *); +extern void machine_at_neat_init(const machine_t *); +extern void machine_at_neat_ami_init(const machine_t *); +extern void machine_at_opti495_init(const machine_t *); +extern void machine_at_opti495_ami_init(const machine_t *); +extern void machine_at_scat_init(const machine_t *); +extern void machine_at_scatsx_init(const machine_t *); +extern void machine_at_compaq_init(const machine_t *); -extern void machine_at_dtk486_init(machine_t *); -extern void machine_at_r418_init(machine_t *); +extern void machine_at_dtk486_init(const machine_t *); +extern void machine_at_r418_init(const machine_t *); -extern void machine_at_wd76c10_init(machine_t *); +extern void machine_at_wd76c10_init(const machine_t *); #if defined(DEV_BRANCH) && defined(USE_GREENB) -extern void machine_at_4gpv31_init(machine_t *); +extern void machine_at_4gpv31_init(const machine_t *); #endif -extern void machine_pcjr_init(machine_t *); +extern void machine_pcjr_init(const machine_t *); -extern void machine_ps1_m2011_init(machine_t *); -extern void machine_ps1_m2121_init(machine_t *); -extern void machine_ps1_m2133_init(machine_t *); +extern void machine_ps1_m2011_init(const machine_t *); +extern void machine_ps1_m2121_init(const machine_t *); +extern void machine_ps1_m2133_init(const machine_t *); -extern void machine_ps2_m30_286_init(machine_t *); -extern void machine_ps2_model_50_init(machine_t *); -extern void machine_ps2_model_55sx_init(machine_t *); -extern void machine_ps2_model_70_type3_init(machine_t *); -extern void machine_ps2_model_70_type4_init(machine_t *); -extern void machine_ps2_model_80_init(machine_t *); +extern void machine_ps2_m30_286_init(const machine_t *); +extern void machine_ps2_model_50_init(const machine_t *); +extern void machine_ps2_model_55sx_init(const machine_t *); +extern void machine_ps2_model_70_type3_init(const machine_t *); +extern void machine_ps2_model_70_type4_init(const machine_t *); +extern void machine_ps2_model_80_init(const machine_t *); -extern void machine_amstrad_init(machine_t *); +extern void machine_amstrad_init(const machine_t *); -extern void machine_europc_init(machine_t *); +extern void machine_europc_init(const machine_t *); #ifdef EMU_DEVICE_H -extern device_t europc_device, +extern const device_t europc_device, europc_hdc_device; #endif -extern void machine_olim24_init(machine_t *); +extern void machine_olim24_init(const machine_t *); extern void machine_olim24_video_init(void); -extern void machine_tandy1k_init(machine_t *); +extern void machine_tandy1k_init(const machine_t *); extern int tandy1k_eeprom_read(void); -extern void machine_xt_init(machine_t *); -extern void machine_xt_compaq_init(machine_t *); +extern void machine_xt_init(const machine_t *); +extern void machine_xt_compaq_init(const machine_t *); #if defined(DEV_BRANCH) && defined(USE_LASERXT) -extern void machine_xt_laserxt_init(machine_t *); +extern void machine_xt_laserxt_init(const machine_t *); #endif -extern void machine_xt_t1000_init(machine_t *); -extern void machine_xt_t1200_init(machine_t *); +extern void machine_xt_t1000_init(const machine_t *); +extern void machine_xt_t1200_init(const machine_t *); -extern void machine_xt_xi8088_init(machine_t *); +extern void machine_xt_xi8088_init(const machine_t *); #ifdef EMU_DEVICE_H -extern device_t *xi8088_get_device(void); +extern const device_t *xi8088_get_device(void); -extern device_t *pcjr_get_device(void); +extern const device_t *pcjr_get_device(void); -extern device_t *tandy1k_get_device(void); -extern device_t *tandy1k_hx_get_device(void); +extern const device_t *tandy1k_get_device(void); +extern const device_t *tandy1k_hx_get_device(void); -extern device_t *t1000_get_device(void); -extern device_t *t1200_get_device(void); +extern const device_t *t1000_get_device(void); +extern const device_t *t1200_get_device(void); -extern device_t *at_endeavor_get_device(void); +extern const device_t *at_endeavor_get_device(void); #endif diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 5ca1294..dc1d32f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11,7 +11,7 @@ * NOTES: OpenAT wip for 286-class machine with open BIOS. * PS2_M80-486 wip, pending receipt of TRM's for machine. * - * Version: @(#)machine_table.c 1.0.10 2018/03/13 + * Version: @(#)machine_table.c 1.0.11 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -52,7 +52,7 @@ #include "machine.h" -machine_t machines[] = { +const machine_t machines[] = { { "[8088] AMI XT clone", ROM_AMIXT, "ami_xt", L"generic/ami/xt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL, NULL }, { "[8088] Compaq Portable", ROM_PORTABLE, "compaq_portable", L"compaq/portable", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_init, NULL, NULL }, { "[8088] DTK XT clone", ROM_DTKXT, "dtk_xt", L"dtk/xt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL, NULL }, @@ -233,7 +233,7 @@ machine_getname(void) } -device_t * +const device_t * machine_getdevice(int machine) { if (machines[machine].get_device) diff --git a/src/mem.c b/src/mem.c index 954c634..e096403 100644 --- a/src/mem.c +++ b/src/mem.c @@ -8,7 +8,7 @@ * * Memory handling and MMU. * - * Version: @(#)mem.c 1.0.5 2018/03/14 + * Version: @(#)mem.c 1.0.6 2018/03/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -54,10 +54,10 @@ #ifdef USE_DYNAREC # include "cpu/codegen.h" #else -#define PAGE_MASK_INDEX_MASK 3 -#define PAGE_MASK_INDEX_SHIFT 10 -#define PAGE_MASK_MASK 63 -#define PAGE_MASK_SHIFT 4 +# define PAGE_MASK_INDEX_MASK 3 +# define PAGE_MASK_INDEX_SHIFT 10 +# define PAGE_MASK_MASK 63 +# define PAGE_MASK_SHIFT 4 #endif @@ -68,17 +68,18 @@ mem_mapping_t bios_mapping[8]; mem_mapping_t bios_high_mapping[8]; mem_mapping_t romext_mapping; -page_t *pages, - **page_lookup; -uint32_t page_lookup_sz; +page_t *pages, /* RAM page table */ + **page_lookup; /* pagetable lookup */ +uint32_t pages_sz; /* #pages in table */ uint8_t isram[0x10000]; -uint8_t *ram; +uint8_t *ram; /* the virtual RAM */ uint32_t rammask; -uint8_t *rom; +uint8_t *rom; /* the virtual ROM */ uint8_t romext[32768]; +uint32_t biosmask; uint32_t pccache; uint8_t *pccache2; @@ -96,10 +97,7 @@ uint32_t mem_logical_addr; int shadowbios = 0, shadowbios_write; - -int mem_size; -uint32_t biosmask; -int readlnum = 0, +int readlnum = 0, writelnum = 0; int pctrans = 0; int cachesize = 256; @@ -137,7 +135,11 @@ static mem_mapping_t base_mapping; static mem_mapping_t ram_remapped_mapping; static mem_mapping_t ram_split_mapping; +#if 0 static uint8_t ff_array[0x1000]; +#else +static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; +#endif static int port_92_reg = 0; @@ -150,16 +152,16 @@ resetreadlookup(void) /* This is NULL after app startup, when mem_init() has not yet run. */ if (page_lookup == NULL) return; - memset(page_lookup, 0x00, page_lookup_sz); + memset(page_lookup, 0x00, pages_sz * sizeof(page_t *)); for (c = 0; c < 256; c++) readlookup[c] = 0xffffffff; - memset(readlookup2, 0xff, 1024*1024*sizeof(uintptr_t)); + memset(readlookup2, 0xff, pages_sz*sizeof(uintptr_t)); readlnext = 0; for (c = 0; c < 256; c++) writelookup[c] = 0xffffffff; - memset(writelookup2, 0xff, 1024*1024*sizeof(uintptr_t)); + memset(writelookup2, 0xff, pages_sz*sizeof(uintptr_t)); writelnext = 0; pccache = 0xffffffff; @@ -388,7 +390,7 @@ addreadlookup(uint32_t virt, uint32_t phys) readlookup2[readlookup[readlnext]] = -1; readlookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; - + readlookupp[readlnext] = mmu_perm; readlookup[readlnext++] = virt >> 12; readlnext &= (cachesize-1); @@ -417,7 +419,7 @@ addwritelookup(uint32_t virt, uint32_t phys) page_lookup[virt >> 12] = &pages[phys >> 12]; else writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; - + writelookupp[writelnext] = mmu_perm; writelookup[writelnext++] = virt >> 12; writelnext &= (cachesize - 1); @@ -460,7 +462,11 @@ getpccache(uint32_t a) pclog("Bad getpccache %08X\n", a); +#if 0 return &ff_array[0-(uintptr_t)(a2 & ~0xfff)]; +#else + return (uint8_t *)&ff_pccache; +#endif } @@ -1449,7 +1455,7 @@ mem_add_bios(void) mem_write_null,mem_write_nullw,mem_write_nulll, rom + (0xc000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - } + } mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, mem_read_bios,mem_read_biosw,mem_read_biosl, @@ -1471,7 +1477,7 @@ mem_add_bios(void) mem_write_null,mem_write_nullw,mem_write_nulll, rom + (0x1c000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - + mem_mapping_add(&bios_high_mapping[0], (AT && cpu_16bitbus) ? 0xfe0000 : 0xfffe0000, 0x04000, mem_read_bios,mem_read_biosw,mem_read_biosl, @@ -1534,14 +1540,20 @@ mem_a20_init(void) void mem_reset(void) { - uint32_t c, m, p; + uint32_t c, m; split_mapping_enabled = 0; - /* Free existing memory. */ + /* Free existing memory and tables. */ if (ram != NULL) free(ram); + if (rom != NULL) free(rom); if (pages != NULL) free(pages); if (page_lookup != NULL) free(page_lookup); + if (readlookup2 != NULL) free(readlookup2); + if (writelookup2 != NULL) free(writelookup2); + + /* Reset the ROM size mask. */ + biosmask = 0xffff; /* * Always allocate the full 16 MB memory space if memory size @@ -1549,7 +1561,7 @@ mem_reset(void) * split mapping. */ if (mem_size < 16384) - m = 1024UL * 16384; + m = 1024UL * 16384; else m = 1024UL * (mem_size + 384); /* 386 extra kB for top remapping */ ram = malloc(m); /* allocate and clear the RAM block */ @@ -1560,24 +1572,40 @@ mem_reset(void) * We re-allocate the table on each (hard) reset, as the * memory amount could have changed. */ - if (m <= (1 << 24)) /* 80286 max address space (16M) */ - p = (m / 4096); /* allocated mem size / pagesize */ - else - p = (1 << 20); /* entire 4GB address space */ -pclog("MEM: mem_size=%i, m=%i, p=%i\n", mem_size, m, p); - pages = (page_t *)malloc(p * sizeof(page_t)); - memset(pages, 0x00, p * sizeof(page_t)); - for (c = 0; c < p; c++) { + if (AT) { + if (cpu_16bitbus) { + /* 80186/286; maximum address space is 16MB. */ + m = 4096; + } else { + /* 80386+; maximum address space is 4GB. */ + m = (mem_size + 384) >> 2; + if ((m << 2) < (mem_size + 384)) + m++; + if (m < 4096) + m = 4096; + } + } else { + /* 8088/86; maximum address space is 1MB. */ + m = 256; + } + + pages_sz = m; + pages = (page_t *)malloc(m * sizeof(page_t)); + memset(pages, 0x00, m * sizeof(page_t)); + for (c=0; c= 0xfe && c <= 0xff)) isram[c] = 0; } -pclog("MEM: isram done\n"); memset(_mem_read_b, 0x00, sizeof(_mem_read_b)); memset(_mem_read_w, 0x00, sizeof(_mem_read_w)); @@ -1655,7 +1682,6 @@ pclog("MEM: isram done\n"); mem_mapping_disable(&ram_split_mapping); mem_a20_init(); -pclog("MEM: reset done\n"); } @@ -1663,24 +1689,20 @@ void mem_init(void) { /* Perform a one-time init. */ - ram = NULL; + ram = rom = NULL; pages = NULL; page_lookup = NULL; + readlookup2 = NULL; + writelookup2 = NULL; - /* FIXME: move to reset? */ - rom = NULL; - biosmask = 0xffff; - - readlookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); - writelookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); - memset(ram_mapped_addr, 0x00, 64 * sizeof(uint32_t)); - + +#if 0 memset(ff_array, 0xff, sizeof(ff_array)); +#endif /* Reset the memory state. */ mem_reset(); -pclog("MEM: init done\n"); } @@ -1723,67 +1745,6 @@ mem_remap_top_384k(void) } -void -mem_split_enable(int max_size, uint32_t addr) -{ - uint8_t *mem_split_buffer = &ram[0x80000]; - int c; - - if (split_mapping_enabled) return; - -#if 0 - pclog("Split mapping enable at %08X\n", addr); -#endif - - mem_set_mem_state(addr, max_size * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_set_addr(&ram_split_mapping, addr, max_size * 1024); - mem_mapping_set_exec(&ram_split_mapping, &ram[addr]); - - if (max_size == 384) - memcpy(&ram[addr], mem_split_buffer, max_size); - else - memcpy(&ram[addr], &mem_split_buffer[128 * 1024], max_size); - - for (c = ((addr/1024)/64); c < (((addr/1024)+max_size-1)/64); c++) - isram[c] = 1; - - flushmmucache(); - - split_mapping_enabled = 1; -} - - -void -mem_split_disable(int max_size, uint32_t addr) -{ - uint8_t *mem_split_buffer = &ram[0x80000]; - int c; - - if (! split_mapping_enabled) return; - -#if 0 - pclog("Split mapping disable at %08X\n", addr); -#endif - - if (max_size == 384) - memcpy(mem_split_buffer, &ram[addr], max_size); - else - memcpy(&mem_split_buffer[128 * 1024], &ram[addr], max_size); - - mem_mapping_disable(&ram_split_mapping); - mem_set_mem_state(addr, max_size * 1024, 0); - mem_mapping_set_exec(&ram_split_mapping, NULL); - - for (c = ((addr/1024)/64); c < (((addr/1024)+max_size-1)/64); c++) - isram[c] = 0; - - flushmmucache(); - - split_mapping_enabled = 0; -} - - void mem_reset_page_blocks(void) { diff --git a/src/mem.h b/src/mem.h index 0e8448f..660bab6 100644 --- a/src/mem.h +++ b/src/mem.h @@ -8,7 +8,7 @@ * * Definitions for the memory interface. * - * Version: @(#)mem.h 1.0.3 2018/03/14 + * Version: @(#)mem.h 1.0.4 2018/03/16 * * Authors: Fred N. van Kempen, * Sarah Walker, @@ -243,9 +243,6 @@ extern void mem_reset(void); extern void mem_remap_top_256k(void); extern void mem_remap_top_384k(void); -extern void mem_split_enable(int max_size, uint32_t addr); -extern void mem_split_disable(int max_size, uint32_t addr); - extern uint8_t port_92_read(uint16_t port, void *priv); extern void port_92_write(uint16_t port, uint8_t val, void *priv); extern void port_92_clear_reset(void); diff --git a/src/mouse.c b/src/mouse.c index 6b1efe1..2cb6169 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -11,7 +11,7 @@ * TODO: Add the Genius bus- and serial mouse. * Remove the '3-button' flag from mouse types. * - * Version: @(#)mouse.c 1.0.1 2018/02/14 + * Version: @(#)mouse.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -59,8 +59,8 @@ typedef struct { - const char *internal_name; - device_t *device; + const char *internal_name; + const device_t *device; } mouse_t; @@ -71,14 +71,14 @@ int mouse_x, mouse_buttons; -static device_t mouse_none_device = { +static const device_t mouse_none_device = { "None", 0, MOUSE_TYPE_NONE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; -static device_t mouse_internal_device = { +static const device_t mouse_internal_device = { "Internal Mouse", 0, MOUSE_TYPE_INTERNAL, NULL, NULL, NULL, @@ -87,7 +87,7 @@ static device_t mouse_internal_device = { }; -static mouse_t mouse_devices[] = { +static const mouse_t mouse_devices[] = { { "none", &mouse_none_device }, { "internal", &mouse_internal_device }, { "logibus", &mouse_logibus_device }, @@ -102,9 +102,9 @@ static mouse_t mouse_devices[] = { }; -static device_t *mouse_curr; static void *mouse_priv; static int mouse_nbut; +static device_t mouse_dev; /* Initialize the mouse module. */ @@ -116,7 +116,6 @@ mouse_init(void) mouse_buttons = 0x00; mouse_type = MOUSE_TYPE_NONE; - mouse_curr = NULL; mouse_priv = NULL; mouse_nbut = 0; } @@ -125,11 +124,11 @@ mouse_init(void) void mouse_close(void) { - if (mouse_curr == NULL) return; + if (mouse_type == MOUSE_TYPE_NONE) return; - mouse_curr = NULL; mouse_priv = NULL; mouse_nbut = 0; + mouse_type = MOUSE_TYPE_NONE; } @@ -137,7 +136,7 @@ void mouse_reset(void) { /* Abort if already initialized by a machine with internal mouse. */ - if (mouse_curr != NULL) return; + if (mouse_type == MOUSE_TYPE_NONE) return; pclog("MOUSE: reset(type=%d, '%s')\n", mouse_type, mouse_devices[mouse_type].device->name); @@ -149,10 +148,12 @@ mouse_reset(void) /* If no mouse configured, we're done. */ if (mouse_type == 0) return; - mouse_curr = mouse_devices[mouse_type].device; - - if (mouse_curr != NULL) - mouse_priv = device_add(mouse_curr); + /* Copy the (R/O) mouse info. */ + if (mouse_devices[mouse_type].device != NULL) { + memcpy(&mouse_dev, mouse_devices[mouse_type].device, + sizeof(device_t)); + mouse_priv = device_add(&mouse_dev); + } } @@ -169,14 +170,14 @@ mouse_process(void) { static int poll_delay = 2; - if (mouse_curr == NULL) return; + if (mouse_devices[mouse_type].device == NULL) return; if (--poll_delay) return; mouse_poll(); - if (mouse_curr->available != NULL) { - mouse_curr->available(mouse_x,mouse_y,mouse_z,mouse_buttons, mouse_priv); + if (mouse_dev.available != NULL) { + mouse_dev.available(mouse_x,mouse_y,mouse_z,mouse_buttons, mouse_priv); /* Reset mouse deltas. */ mouse_x = mouse_y = mouse_z = 0; @@ -191,7 +192,7 @@ mouse_set_poll(int (*func)(int,int,int,int,void *), void *arg) { if (mouse_type != MOUSE_TYPE_INTERNAL) return; - mouse_curr->available = func; + mouse_dev.available = func; mouse_priv = arg; } @@ -235,7 +236,7 @@ mouse_has_config(int mouse) } -device_t * +const device_t * mouse_get_device(int mouse) { return(mouse_devices[mouse].device); diff --git a/src/mouse.h b/src/mouse.h index e6c687c..e5c824b 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -8,7 +8,7 @@ * * Definitions for the mouse driver. * - * Version: @(#)mouse.h 1.0.1 2018/02/14 + * Version: @(#)mouse.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -74,17 +74,17 @@ extern int mouse_buttons; #ifdef EMU_DEVICE_H -extern device_t *mouse_get_device(int mouse); -extern void *mouse_ps2_init(device_t *); +extern const device_t *mouse_get_device(int mouse); +extern void *mouse_ps2_init(const device_t *); -extern device_t mouse_logibus_device; -extern device_t mouse_msinport_device; +extern const device_t mouse_logibus_device; +extern const device_t mouse_msinport_device; #if 0 -extern device_t mouse_genibus_device; +extern const device_t mouse_genibus_device; #endif -extern device_t mouse_mssystems_device; -extern device_t mouse_msserial_device; -extern device_t mouse_ps2_device; +extern const device_t mouse_mssystems_device; +extern const device_t mouse_msserial_device; +extern const device_t mouse_ps2_device; #endif extern void mouse_init(void); diff --git a/src/mouse_bus.c b/src/mouse_bus.c index 89cab3c..c3af8ca 100644 --- a/src/mouse_bus.c +++ b/src/mouse_bus.c @@ -49,7 +49,7 @@ * * Based on an early driver for MINIX 1.5. * - * Version: @(#)mouse_bus.c 1.0.1 2018/02/14 + * Version: @(#)mouse_bus.c 1.0.2 2018/03/15 * * Author: Fred N. van Kempen, * @@ -699,7 +699,7 @@ bm_close(void *priv) /* Initialize the device for use by the user. */ static void * -bm_init(device_t *info) +bm_init(const device_t *info) { mouse_t *dev; int i; @@ -753,7 +753,7 @@ bm_init(device_t *info) } -static device_config_t bm_config[] = { +static const device_config_t bm_config[] = { { "irq", "IRQ", CONFIG_SELECTION, "", MOUSE_IRQ, { { @@ -792,7 +792,7 @@ static device_config_t bm_config[] = { }; -device_t mouse_logibus_device = { +const device_t mouse_logibus_device = { "Logitech Bus Mouse", DEVICE_ISA, MOUSE_TYPE_LOGIBUS, @@ -801,7 +801,7 @@ device_t mouse_logibus_device = { bm_config }; -device_t mouse_msinport_device = { +const device_t mouse_msinport_device = { "Microsoft Bus Mouse (InPort)", DEVICE_ISA, MOUSE_TYPE_INPORT, diff --git a/src/mouse_ps2.c b/src/mouse_ps2.c index 7f85415..ea7892d 100644 --- a/src/mouse_ps2.c +++ b/src/mouse_ps2.c @@ -8,7 +8,7 @@ * * Implementation of PS/2 series Mouse devices. * - * Version: @(#)mouse_ps2.c 1.0.1 2018/02/14 + * Version: @(#)mouse_ps2.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -248,7 +248,7 @@ ps2_poll(int x, int y, int z, int b, void *priv) * We also get called from the various machines. */ void * -mouse_ps2_init(device_t *info) +mouse_ps2_init(const device_t *info) { mouse_t *dev; int i; @@ -288,7 +288,7 @@ ps2_close(void *priv) } -static device_config_t ps2_config[] = { +static const device_config_t ps2_config[] = { { "buttons", "Buttons", CONFIG_SELECTION, "", 2, { { @@ -311,7 +311,7 @@ static device_config_t ps2_config[] = { }; -device_t mouse_ps2_device = { +const device_t mouse_ps2_device = { "Standard PS/2 Mouse", 0, MOUSE_TYPE_PS2, diff --git a/src/mouse_serial.c b/src/mouse_serial.c index 494604c..91ace91 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -10,7 +10,7 @@ * * TODO: Add the Genius Serial Mouse. * - * Version: @(#)mouse_serial.c 1.0.1 2018/02/14 + * Version: @(#)mouse_serial.c 1.0.2 2018/03/15 * * Author: Fred N. van Kempen, * @@ -228,7 +228,7 @@ sermouse_close(void *priv) /* Initialize the device for use by the user. */ static void * -sermouse_init(device_t *info) +sermouse_init(const device_t *info) { mouse_t *dev; int i; @@ -279,7 +279,7 @@ sermouse_init(device_t *info) } -static device_config_t sermouse_config[] = { +static const device_config_t sermouse_config[] = { { "port", "Serial Port", CONFIG_SELECTION, "", 0, { { @@ -315,7 +315,7 @@ static device_config_t sermouse_config[] = { }; -device_t mouse_mssystems_device = { +const device_t mouse_mssystems_device = { "Mouse Systems Serial Mouse", 0, MOUSE_TYPE_MSYSTEMS, @@ -324,7 +324,7 @@ device_t mouse_mssystems_device = { sermouse_config }; -device_t mouse_msserial_device = { +const device_t mouse_msserial_device = { "Microsoft/Logitech Serial Mouse", 0, 0, diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index 58f62e7..05b2ec6 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -12,7 +12,7 @@ * - Realtek RTL8019AS (ISA 16-bit, PnP); * - Realtek RTL8029AS (PCI). * - * Version: @(#)net_ne2000.c 1.0.2 2018/02/26 + * Version: @(#)net_ne2000.c 1.0.3 2018/03/15 * * Based on @(#)ne2k.cc v1.56.2.1 2004/02/02 22:37:22 cbothamy * @@ -2377,7 +2377,7 @@ nic_rom_init(nic_t *dev, wchar_t *s) static void * -nic_init(device_t *info) +nic_init(const device_t *info) { uint32_t mac; wchar_t *rom; @@ -2385,9 +2385,9 @@ nic_init(device_t *info) #ifdef ENABLE_NIC_LOG int i; #endif - int c; - char *ansi_id = "REALTEK PLUG & PLAY ETHERNET CARD"; - uint64_t *eeprom_pnp_id; + int c; + char *ansi_id = "REALTEK PLUG & PLAY ETHERNET CARD"; + uint64_t *eeprom_pnp_id; /* Get the desired debug level. */ #ifdef ENABLE_NIC_LOG @@ -2403,6 +2403,8 @@ nic_init(device_t *info) switch(dev->board) { case NE2K_NE1000: dev->is_8bit = 1; + /*FALLTHROUGH*/ + case NE2K_NE2000: dev->maclocal[0] = 0x00; /* 00:00:D8 (Novell OID) */ dev->maclocal[1] = 0x00; @@ -2445,8 +2447,11 @@ nic_init(device_t *info) /* See if we have a local MAC address configured. */ mac = device_get_config_mac("mac", -1); - /* Make this device known to the I/O system. */ - if (dev->board < NE2K_RTL8019AS) /* PnP and PCI devices start with address spaces inactive. */ + /* + * Make this device known to the I/O system. + * PnP and PCI devices start with address spaces inactive. + */ + if (dev->board < NE2K_RTL8019AS) nic_ioset(dev, dev->base_address); /* Set up our BIOS ROM space, if any. */ @@ -2488,21 +2493,21 @@ nic_init(device_t *info) dev->pci_regs[0x02] = (PCI_DEVID&0xff); dev->pci_regs[0x03] = (PCI_DEVID>>8); - dev->pci_regs[0x04] = 0x03; /* IOEN */ + dev->pci_regs[0x04] = 0x03; /* IOEN */ dev->pci_regs[0x05] = 0x00; - dev->pci_regs[0x07] = 0x02; /* DST0, medium devsel */ + dev->pci_regs[0x07] = 0x02; /* DST0, medium devsel */ - dev->pci_regs[0x09] = 0x00; /* PIFR */ + dev->pci_regs[0x09] = 0x00; /* PIFR */ - dev->pci_regs[0x0B] = 0x02; /* BCR: Network Controller */ - dev->pci_regs[0x0A] = 0x00; /* SCR: Ethernet */ + dev->pci_regs[0x0B] = 0x02; /* BCR: Network Controller */ + dev->pci_regs[0x0A] = 0x00; /* SCR: Ethernet */ dev->pci_regs[0x2C] = (PCI_VENDID&0xff); dev->pci_regs[0x2D] = (PCI_VENDID>>8); dev->pci_regs[0x2E] = (PCI_DEVID&0xff); dev->pci_regs[0x2F] = (PCI_DEVID>>8); - dev->pci_regs[0x3D] = PCI_INTA; /* PCI_IPR */ + dev->pci_regs[0x3D] = PCI_INTA; /* PCI_IPR */ /* Enable our address space in PCI. */ dev->pci_bar[0].addr_regs[0] = 0x01; @@ -2518,8 +2523,9 @@ nic_init(device_t *info) mem_mapping_disable(&dev->bios_rom.mapping); - /* Insert this device onto the PCI bus, keep its slot number. */ - dev->card = pci_add_card(PCI_ADD_NORMAL, nic_pci_read, nic_pci_write, dev); + /* Add device to the PCI bus, keep its slot number. */ + dev->card = pci_add_card(PCI_ADD_NORMAL, + nic_pci_read, nic_pci_write, dev); } else { io_sethandler(0x0279, 1, NULL, NULL, NULL, @@ -2551,52 +2557,52 @@ nic_init(device_t *info) eeprom_pnp_id = (uint64_t *) &dev->eeprom[0x12]; *eeprom_pnp_id = dev->pnp_id; - /* TAG: Plug and Play Version Number */ - dev->eeprom[0x1B] = 0x0A; /* Item byte */ - dev->eeprom[0x1C] = 0x10; /* PnP version */ - dev->eeprom[0x1D] = 0x10; /* Vendor version */ + /* TAG: Plug and Play Version Number. */ + dev->eeprom[0x1B] = 0x0A; /* Item byte */ + dev->eeprom[0x1C] = 0x10; /* PnP version */ + dev->eeprom[0x1D] = 0x10; /* Vendor version */ - /* TAG: ANSI Identifier String */ - dev->eeprom[0x1E] = 0x82; /* Item byte */ - dev->eeprom[0x1F] = 0x22; /* Length bits 7-0 */ - dev->eeprom[0x20] = 0x00; /* Length bits 15-8 */ - memcpy(&dev->eeprom[0x21], ansi_id, 0x22); /* Identifier string */ + /* TAG: ANSI Identifier String. */ + dev->eeprom[0x1E] = 0x82; /* Item byte */ + dev->eeprom[0x1F] = 0x22; /* Length bits 7-0 */ + dev->eeprom[0x20] = 0x00; /* Length bits 15-8 */ + memcpy(&dev->eeprom[0x21], ansi_id, 0x22); - /* TAG: Logical Device ID */ - dev->eeprom[0x43] = 0x16; /* Item byte */ - dev->eeprom[0x44] = 0x4A; /* Logical device ID0 */ - dev->eeprom[0x45] = 0x8C; /* Logical device ID1 */ - dev->eeprom[0x46] = 0x80; /* Logical device ID2 */ - dev->eeprom[0x47] = 0x19; /* Logical device ID3 */ - dev->eeprom[0x48] = 0x02; /* Flag 0 (02 = BROM is disabled) */ - dev->eeprom[0x49] = 0x00; /* Flag 1 */ + /* TAG: Logical Device ID. */ + dev->eeprom[0x43] = 0x16; /* Item byte */ + dev->eeprom[0x44] = 0x4A; /* Logical device ID0 */ + dev->eeprom[0x45] = 0x8C; /* Logical device ID1 */ + dev->eeprom[0x46] = 0x80; /* Logical device ID2 */ + dev->eeprom[0x47] = 0x19; /* Logical device ID3 */ + dev->eeprom[0x48] = 0x02; /* Flag0 (02=BROM/disabled) */ + dev->eeprom[0x49] = 0x00; /* Flag 1 */ - /* TAG: Compatible Device ID (NE2000) */ - dev->eeprom[0x4A] = 0x1C; /* Item byte */ - dev->eeprom[0x4B] = 0x41; /* Compatible ID0 */ - dev->eeprom[0x4C] = 0xD0; /* Compatible ID1 */ - dev->eeprom[0x4D] = 0x80; /* Compatible ID2 */ - dev->eeprom[0x4E] = 0xD6; /* Compatible ID3 */ + /* TAG: Compatible Device ID (NE2000) */ + dev->eeprom[0x4A] = 0x1C; /* Item byte */ + dev->eeprom[0x4B] = 0x41; /* Compatible ID0 */ + dev->eeprom[0x4C] = 0xD0; /* Compatible ID1 */ + dev->eeprom[0x4D] = 0x80; /* Compatible ID2 */ + dev->eeprom[0x4E] = 0xD6; /* Compatible ID3 */ - /* TAG: I/O Format */ - dev->eeprom[0x4F] = 0x47; /* Item byte */ - dev->eeprom[0x50] = 0x00; /* I/O information */ - dev->eeprom[0x51] = 0x20; /* Min. I/O base bits 7-0 */ - dev->eeprom[0x52] = 0x02; /* Min. I/O base bits 15-8 */ - dev->eeprom[0x53] = 0x80; /* Max. I/O base bits 7-0 */ - dev->eeprom[0x54] = 0x03; /* Max. I/O base bits 15-8 */ - dev->eeprom[0x55] = 0x20; /* Base alignment */ - dev->eeprom[0x56] = 0x20; /* Range length */ + /* TAG: I/O Format */ + dev->eeprom[0x4F] = 0x47; /* Item byte */ + dev->eeprom[0x50] = 0x00; /* I/O information */ + dev->eeprom[0x51] = 0x20; /* Min. I/O base bits 7-0 */ + dev->eeprom[0x52] = 0x02; /* Min. I/O base bits 15-8 */ + dev->eeprom[0x53] = 0x80; /* Max. I/O base bits 7-0 */ + dev->eeprom[0x54] = 0x03; /* Max. I/O base bits 15-8 */ + dev->eeprom[0x55] = 0x20; /* Base alignment */ + dev->eeprom[0x56] = 0x20; /* Range length */ - /* TAG: IRQ Format */ - dev->eeprom[0x57] = 0x23; /* Item byte */ - dev->eeprom[0x58] = 0x38; /* IRQ mask bits 7-0 */ - dev->eeprom[0x59] = 0x9E; /* IRQ mask bits 15-8 */ - dev->eeprom[0x5A] = 0x01; /* IRQ information */ + /* TAG: IRQ Format. */ + dev->eeprom[0x57] = 0x23; /* Item byte */ + dev->eeprom[0x58] = 0x38; /* IRQ mask bits 7-0 */ + dev->eeprom[0x59] = 0x9E; /* IRQ mask bits 15-8 */ + dev->eeprom[0x5A] = 0x01; /* IRQ information */ - /* TAG: END Tag */ - dev->eeprom[0x5B] = 0x79; /* Item byte */ - for (c = 0x1B; c < 0x5C; c++) /* Checksum (2's complement) */ + /* TAG: END Tag */ + dev->eeprom[0x5B] = 0x79; /* Item byte */ + for (c = 0x1b; c < 0x5c; c++) /* Checksum (2's compl) */ dev->eeprom[0x5C] += dev->eeprom[c]; dev->eeprom[0x5C] = -dev->eeprom[0x5C]; @@ -2635,7 +2641,7 @@ nic_close(void *priv) } -static device_config_t ne1000_config[] = +static const device_config_t ne1000_config[] = { { "base", "Address", CONFIG_HEX16, "", 0x300, @@ -2694,7 +2700,7 @@ static device_config_t ne1000_config[] = } }; -static device_config_t ne2000_config[] = +static const device_config_t ne2000_config[] = { { "base", "Address", CONFIG_HEX16, "", 0x300, @@ -2779,7 +2785,7 @@ static device_config_t ne2000_config[] = } }; -static device_config_t rtl8019as_config[] = +static const device_config_t rtl8019as_config[] = { { "mac", "MAC Address", CONFIG_MAC, "", -1 @@ -2789,7 +2795,7 @@ static device_config_t rtl8019as_config[] = } }; -static device_config_t rtl8029as_config[] = +static const device_config_t rtl8029as_config[] = { { "bios", "Enable BIOS", CONFIG_BINARY, "", 0 @@ -2803,7 +2809,7 @@ static device_config_t rtl8029as_config[] = }; -device_t ne1000_device = { +const device_t ne1000_device = { "Novell NE1000", DEVICE_ISA, NE2K_NE1000, @@ -2812,7 +2818,7 @@ device_t ne1000_device = { ne1000_config }; -device_t ne2000_device = { +const device_t ne2000_device = { "Novell NE2000", DEVICE_ISA | DEVICE_AT, NE2K_NE2000, @@ -2821,7 +2827,7 @@ device_t ne2000_device = { ne2000_config }; -device_t rtl8019as_device = { +const device_t rtl8019as_device = { "Realtek RTL8019AS", DEVICE_ISA | DEVICE_AT, NE2K_RTL8019AS, @@ -2830,7 +2836,7 @@ device_t rtl8019as_device = { rtl8019as_config }; -device_t rtl8029as_device = { +const device_t rtl8029as_device = { "Realtek RTL8029AS", DEVICE_PCI, NE2K_RTL8029AS, diff --git a/src/network/net_ne2000.h b/src/network/net_ne2000.h index 13796f6..0453a3b 100644 --- a/src/network/net_ne2000.h +++ b/src/network/net_ne2000.h @@ -8,7 +8,7 @@ * * Definitions for the NE2000 ethernet controller. * - * Version: @(#)net_ne2000.h 1.0.1 2018/02/14 + * Version: @(#)net_ne2000.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * @@ -45,10 +45,10 @@ enum { }; -extern device_t ne1000_device; -extern device_t ne2000_device; -extern device_t rtl8019as_device; -extern device_t rtl8029as_device; +extern const device_t ne1000_device; +extern const device_t ne2000_device; +extern const device_t rtl8019as_device; +extern const device_t rtl8029as_device; #endif /*NET_NE2000_H*/ diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index 6b727a9..9792b2c 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -8,7 +8,7 @@ * * Handle WinPcap library processing. * - * Version: @(#)net_pcap.c 1.0.2 2018/03/10 + * Version: @(#)net_pcap.c 1.0.3 2018/03/15 * * Author: Fred N. van Kempen, * @@ -60,7 +60,7 @@ static volatile void *pcap_handle; /* handle to WinPcap DLL */ static volatile pcap_t *pcap; /* handle to WinPcap library */ static volatile thread_t *poll_tid; -static netcard_t *poll_card; /* netcard linked to us */ +static const netcard_t *poll_card; /* netcard linked to us */ static event_t *poll_state; @@ -233,9 +233,7 @@ net_pcap_init(void) pclog("PCAP: initializing, %s\n", errbuf); /* Get the value of our capture interface. */ - if ((network_pcap == NULL) || - (network_pcap[0] == '\0') || - !strcmp(network_pcap, "none")) { + if ((network_host[0] == '\0') || !strcmp(network_host, "none")) { pclog("PCAP: no interface configured!\n"); return(-1); } @@ -303,33 +301,30 @@ net_pcap_close(void) * tries to attach to the network module. */ int -net_pcap_reset(netcard_t *card) +net_pcap_reset(const netcard_t *card, uint8_t *mac) { char errbuf[PCAP_ERRBUF_SIZE]; char filter_exp[255]; struct bpf_program fp; /* Open a PCAP live channel. */ - if ((pcap = f_pcap_open_live(network_pcap, /* interface name */ + if ((pcap = f_pcap_open_live(network_host, /* interface name */ 1518, /* max packet size */ 1, /* promiscuous mode? */ 10, /* timeout in msec */ errbuf)) == NULL) { /* error buffer */ - pclog(" Unable to open device: %s!\n", network_pcap); + pclog(" Unable to open device: %s!\n", network_host); return(-1); } - pclog("PCAP: interface: %s\n", network_pcap); + pclog("PCAP: interface: %s\n", network_host); /* Create a MAC address based packet filter. */ pclog("PCAP: installing filter for MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", - card->mac[0], card->mac[1], card->mac[2], - card->mac[3], card->mac[4], card->mac[5]); + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); sprintf(filter_exp, "( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", - card->mac[0], card->mac[1], card->mac[2], - card->mac[3], card->mac[4], card->mac[5], - card->mac[0], card->mac[1], card->mac[2], - card->mac[3], card->mac[4], card->mac[5]); + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); if (f_pcap_compile((pcap_t *)pcap, &fp, filter_exp, 0, 0xffffffff) != -1) { if (f_pcap_setfilter((pcap_t *)pcap, &fp) != 0) { pclog("PCAP: error installing filter (%s) !\n", filter_exp); @@ -347,7 +342,7 @@ net_pcap_reset(netcard_t *card) pclog("PCAP: starting thread..\n"); poll_state = thread_create_event(); - poll_tid = thread_create(poll_thread, card->mac); + poll_tid = thread_create(poll_thread, mac); thread_wait_event(poll_state, -1); return(0); diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 47d3fb8..9ca6b41 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -8,7 +8,7 @@ * * Handle SLiRP library processing. * - * Version: @(#)net_slirp.c 1.0.1 2018/02/14 + * Version: @(#)net_slirp.c 1.0.2 2018/03/15 * * Author: Fred N. van Kempen, * @@ -60,7 +60,7 @@ static volatile queueADT slirpq; /* SLiRP library handle */ static volatile thread_t *poll_tid; -static netcard_t *poll_card; /* netcard attached to us */ +static const netcard_t *poll_card; /* netcard attached to us */ static event_t *poll_state; @@ -173,14 +173,14 @@ net_slirp_init(void) /* Initialize SLiRP for use. */ int -net_slirp_reset(netcard_t *card) +net_slirp_reset(const netcard_t *card, uint8_t *mac) { /* Save the callback info. */ poll_card = card; pclog("SLiRP: creating thread..\n"); poll_state = thread_create_event(); - poll_tid = thread_create(poll_thread, card->mac); + poll_tid = thread_create(poll_thread, mac); thread_wait_event(poll_state, -1); return(0); diff --git a/src/network/network.c b/src/network/network.c index 488064c..78ba03d 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -12,7 +12,7 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.2 2018/02/22 + * Version: @(#)network.c 1.0.3 2018/03/15 * * Author: Fred N. van Kempen, * @@ -66,17 +66,17 @@ static netcard_t net_cards[] = { { "None", "none", NULL, - NULL, NULL }, + NULL }, { "[ISA] Novell NE1000", "ne1k", &ne1000_device, - NULL, NULL }, + NULL }, { "[ISA] Novell NE2000", "ne2k", &ne2000_device, - NULL, NULL }, + NULL }, { "[ISA] Realtek RTL8019AS", "ne2kpnp", &rtl8019as_device, - NULL, NULL }, + NULL }, { "[PCI] Realtek RTL8029AS", "ne2kpci", &rtl8029as_device, - NULL, NULL }, + NULL }, { "", "", NULL, - NULL, NULL } + NULL } }; @@ -84,12 +84,13 @@ static netcard_t net_cards[] = { int network_type; int network_ndev; int network_card; -netdev_t network_devs[32]; char network_pcap[512]; +netdev_t network_devs[32]; #ifdef ENABLE_NIC_LOG int nic_do_log = ENABLE_NIC_LOG; #endif static mutex_t *network_mutex; +static uint8_t *network_mac; static struct { @@ -263,7 +264,7 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx) /* Save the card's info. */ net_cards[network_card].priv = dev; net_cards[network_card].rx = rx; - net_cards[network_card].mac = mac; + network_mac = mac; /* Create the network events. */ poll_data.wake_poll_thread = thread_create_event(); @@ -272,11 +273,11 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx) /* Activate the platform module. */ switch(network_type) { case NET_TYPE_PCAP: - (void)net_pcap_reset(&net_cards[network_card]); + (void)net_pcap_reset(&net_cards[network_card], network_mac); break; case NET_TYPE_SLIRP: - (void)net_slirp_reset(&net_cards[network_card]); + (void)net_slirp_reset(&net_cards[network_card], network_mac); break; } } @@ -308,6 +309,7 @@ network_close(void) /* Close the network thread mutex. */ thread_close_mutex(network_mutex); network_mutex = NULL; + network_mac = NULL; pclog("NETWORK: closed.\n"); } @@ -455,7 +457,7 @@ network_card_getname(int card) /* UI */ -device_t * +const device_t * network_card_getdevice(int card) { return(net_cards[card].device); diff --git a/src/network/network.h b/src/network/network.h index 26f075b..bdd4beb 100644 --- a/src/network/network.h +++ b/src/network/network.h @@ -8,7 +8,7 @@ * * Definitions for the network module. * - * Version: @(#)network.h 1.0.1 2018/02/14 + * Version: @(#)network.h 1.0.2 2018/03/15 * * Author: Fred N. van Kempen, * @@ -68,18 +68,17 @@ typedef void (*NETRXCB)(void *, uint8_t *, int); typedef struct { - const char *name; - const char *internal_name; - device_t *device; - void *priv; - int (*poll)(void *); - NETRXCB rx; - uint8_t *mac; + const char *name; + const char *internal_name; + const device_t *device; + void *priv; + int (*poll)(void *); + NETRXCB rx; } netcard_t; typedef struct { - char device[128]; - char description[128]; + char device[128]; + char description[128]; } netdev_t; @@ -89,9 +88,6 @@ extern "C" { /* Global variables. */ extern int nic_do_log; /* config */ -extern int network_card; /* config */ -extern int network_type; /* config */ -extern char network_pcap[512]; /* config */ extern int network_ndev; extern netdev_t network_devs[32]; @@ -111,12 +107,12 @@ extern void network_tx(uint8_t *, int); extern int net_pcap_prepare(netdev_t *); extern int net_pcap_init(void); -extern int net_pcap_reset(netcard_t *); +extern int net_pcap_reset(const netcard_t *, uint8_t *); extern void net_pcap_close(void); extern void net_pcap_in(uint8_t *, int); extern int net_slirp_init(void); -extern int net_slirp_reset(netcard_t *); +extern int net_slirp_reset(const netcard_t *, uint8_t *); extern void net_slirp_close(void); extern void net_slirp_in(uint8_t *, int); @@ -126,7 +122,7 @@ extern char *network_card_getname(int); extern int network_card_has_config(int); extern char *network_card_get_internal_name(int); extern int network_card_get_from_internal_name(char *); -extern device_t *network_card_getdevice(int); +extern const device_t *network_card_getdevice(int); #ifdef __cplusplus } diff --git a/src/nvr_ps2.c b/src/nvr_ps2.c index 439bcc2..844b975 100644 --- a/src/nvr_ps2.c +++ b/src/nvr_ps2.c @@ -8,7 +8,7 @@ * * Handling of the PS/2 series CMOS devices. * - * Version: @(#)nvr_ps2.c 1.0.4 2018/03/12 + * Version: @(#)nvr_ps2.c 1.0.5 2018/03/15 * * Authors: Fred N. van Kempen, * Sarah Walker, @@ -101,7 +101,7 @@ ps2_nvr_write(uint16_t port, uint8_t val, void *priv) static void * -ps2_nvr_init(device_t *info) +ps2_nvr_init(const device_t *info) { ps2_nvr_t *nvr; FILE *f = NULL; @@ -167,7 +167,7 @@ ps2_nvr_close(void *priv) } -device_t ps2_nvr_device = { +const device_t ps2_nvr_device = { "PS/2 Secondary NVRAM", 0, 0, ps2_nvr_init, ps2_nvr_close, NULL, diff --git a/src/nvr_ps2.h b/src/nvr_ps2.h index 802c27f..932d295 100644 --- a/src/nvr_ps2.h +++ b/src/nvr_ps2.h @@ -8,7 +8,7 @@ * * Definitions for the PS/2 cmos/nvr device. * - * Version: @(#)nvr_ps2.h 1.0.1 2018/02/14 + * Version: @(#)nvr_ps2.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Sarah Walker, @@ -38,7 +38,7 @@ # define EMU_NVRPS2_H -extern device_t ps2_nvr_device; +extern const device_t ps2_nvr_device; #endif /*EMU_NVRPS2_H*/ diff --git a/src/pc.c b/src/pc.c index 3d44197..3f01249 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Main emulator module where most things are controlled. * - * Version: @(#)pc.c 1.0.9 2018/03/14 + * Version: @(#)pc.c 1.0.10 2018/03/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -126,6 +126,7 @@ int vid_cga_contrast = 0, /* (C) video */ video_fullscreen_first = 0, /* (C) video */ enable_overscan = 0, /* (C) video */ force_43 = 0, /* (C) video */ + vid_card = 0, /* (C) graphics/video card */ video_speed = 0; /* (C) video */ int serial_enabled[SERIAL_MAX] = {0,0}, /* (C) enable serial ports */ lpt_enabled = 0, /* (C) enable LPT ports */ @@ -135,7 +136,6 @@ int update_icons; /* (C) enable icons updates */ #ifdef WALTJE int romdos_enabled = 0; /* (C) enable ROM DOS */ #endif -int gfxcard = 0; /* (C) graphics/video card */ int sound_is_float = 1, /* (C) sound uses FP values */ GAMEBLASTER = 0, /* (C) sound option */ GUS = 0, /* (C) sound option */ @@ -147,6 +147,10 @@ int cpu_manufacturer = 0, /* (C) cpu manufacturer */ cpu = 3, /* (C) cpu type */ enable_external_fpu = 0; /* (C) enable external FPU */ int enable_sync = 0; /* (C) enable time sync */ +int network_type; /* (C) net provider type */ +int network_card; /* (C) net interface num */ +char network_host[512]; /* (C) host network intf */ + /* Statistics. */ @@ -167,14 +171,10 @@ int insc = 0; /* cpu */ int emu_fps = 0, fps; /* video */ int framecount; -int CPUID; -int output; int atfullspeed; int cpuspeed2; int clockrate; -int gfx_present[GFX_MAX]; /* should not be here */ - char emu_title[128]; /* full name of application */ char emu_version[128]; /* version ID string */ wchar_t emu_path[1024]; /* emu installation path */ @@ -640,8 +640,6 @@ pc_reload(wchar_t *fn) fdd_load(2, floppyfns[2]); fdd_load(3, floppyfns[3]); - mem_reset(); - network_init(); pc_reset_hard_init(); @@ -670,7 +668,7 @@ pc_init_modules(void) return(2); } - if (! video_card_available(video_old_to_new(gfxcard))) { + if (! video_card_available(video_old_to_new(vid_card))) { /* Whoops, selected video not available. */ str = plat_get_string(IDS_2064); mbstowcs(name, machine_getname(), sizeof_w(name)); @@ -778,7 +776,6 @@ pc_reset_hard_init(void) /* Reset the general machine support modules. */ io_init(); - mem_reset(); timer_reset(); device_init(); @@ -823,7 +820,7 @@ pc_reset_hard_init(void) mouse_reset(); /* Reset the video card. */ - video_reset(gfxcard); + video_reset(vid_card); /* Reset the Hard Disk Controller module. */ hdc_reset(); @@ -966,6 +963,8 @@ pc_close(thread_t *ptr) network_close(); sound_cd_thread_end(); + + ide_destroy_buffers(); } @@ -1088,7 +1087,11 @@ pc_thread(void *param) if (title_update) { swprintf(temp, sizeof_w(temp), +#ifdef _WIN32 L"%S v%S - %i%% - %S - %S - %s", +#else + L"%s v%s - %i%% - %s - %s - %s", +#endif EMU_NAME,emu_version,fps,machine_getname(), machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].name, (!mouse_capture) ? plat_get_string(IDS_2077) diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index c98682a..a79e6c4 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -8,7 +8,7 @@ * * Handling of the SCSI controllers. * - * Version: @(#)scsi.c 1.0.2 2018/02/24 + * Version: @(#)scsi.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -77,10 +77,10 @@ mutex_t *scsiMutex; typedef struct { - const char *name; - const char *internal_name; - device_t *device; - void (*reset)(void *p); + const char *name; + const char *internal_name; + const device_t *device; + void (*reset)(void *p); } SCSI_CARD; @@ -124,7 +124,7 @@ scsi_card_getname(int card) } -device_t * +const device_t * scsi_card_getdevice(int card) { return(scsi_cards[card].device); diff --git a/src/scsi/scsi.h b/src/scsi/scsi.h index 7849258..8504e02 100644 --- a/src/scsi/scsi.h +++ b/src/scsi/scsi.h @@ -8,7 +8,7 @@ * * SCSI controller handler header. * - * Version: @(#)scsi.h 1.0.1 2018/02/14 + * Version: @(#)scsi.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -311,7 +311,7 @@ extern int scsi_card_current; extern int scsi_card_available(int card); extern char *scsi_card_getname(int card); #ifdef EMU_DEVICE_H -extern device_t *scsi_card_getdevice(int card); +extern const device_t *scsi_card_getdevice(int card); #endif extern int scsi_card_has_config(int card); extern char *scsi_card_get_internal_name(int card); @@ -379,6 +379,8 @@ typedef struct { #define MODE_SELECT_PHASE_PAGE_HEADER 3 #define MODE_SELECT_PHASE_PAGE 4 -#endif /*EMU_SCSI_H*/ extern void scsi_mutex_wait(uint8_t wait); + + +#endif /*EMU_SCSI_H*/ diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index 56b6e10..68b5a89 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -10,7 +10,7 @@ * made by Adaptec, Inc. These controllers were designed for * the ISA bus. * - * Version: @(#)scsi_aha154x.c 1.0.4 2018/03/08 + * Version: @(#)scsi_aha154x.c 1.0.5 2018/03/15 * * Based on original code from TheCollector1995 and Miran Grca. * @@ -753,7 +753,7 @@ aha_setnvr(x54x_t *dev) /* General initialization routine for all boards. */ static void * -aha_init(device_t *info) +aha_init(const device_t *info) { x54x_t *dev; @@ -897,7 +897,7 @@ aha_init(device_t *info) } -static device_config_t aha_154xb_config[] = { +static const device_config_t aha_154xb_config[] = { { "base", "Address", CONFIG_HEX16, "", 0x334, { @@ -1028,7 +1028,7 @@ static device_config_t aha_154xb_config[] = { }; -static device_config_t aha_154x_config[] = { +static const device_config_t aha_154x_config[] = { { "base", "Address", CONFIG_HEX16, "", 0x334, { @@ -1127,7 +1127,7 @@ static device_config_t aha_154x_config[] = { }; -device_t aha1540b_device = { +const device_t aha1540b_device = { "Adaptec AHA-1540B", DEVICE_ISA | DEVICE_AT, AHA_154xB, @@ -1136,7 +1136,7 @@ device_t aha1540b_device = { aha_154xb_config }; -device_t aha1542c_device = { +const device_t aha1542c_device = { "Adaptec AHA-1542C", DEVICE_ISA | DEVICE_AT, AHA_154xC, @@ -1145,7 +1145,7 @@ device_t aha1542c_device = { aha_154x_config }; -device_t aha1542cf_device = { +const device_t aha1542cf_device = { "Adaptec AHA-1542CF", DEVICE_ISA | DEVICE_AT, AHA_154xCF, @@ -1154,7 +1154,7 @@ device_t aha1542cf_device = { aha_154x_config }; -device_t aha1640_device = { +const device_t aha1640_device = { "Adaptec AHA-1640", DEVICE_MCA, AHA_1640, diff --git a/src/scsi/scsi_aha154x.h b/src/scsi/scsi_aha154x.h index 40b719e..c0d801f 100644 --- a/src/scsi/scsi_aha154x.h +++ b/src/scsi/scsi_aha154x.h @@ -8,7 +8,7 @@ * * Definitions for the Adaptec 154x driver. * - * Version: @(#)scsi_154x.h 1.0.1 2018/02/14 + * Version: @(#)scsi_154x.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -38,12 +38,12 @@ # define SCSI_AHA154X_H -extern device_t aha1540b_device; -extern device_t aha1542c_device; -extern device_t aha1542cf_device; -extern device_t aha1640_device; +extern const device_t aha1540b_device; +extern const device_t aha1542c_device; +extern const device_t aha1542cf_device; +extern const device_t aha1640_device; + +extern void aha_device_reset(void *p); + -extern void aha_device_reset(void *p); - - #endif /*SCSI_AHA154X_H*/ diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index e62c0d8..ff6fc8c 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -13,7 +13,7 @@ * 1 - BT-545S ISA; * 2 - BT-958D PCI * - * Version: @(#)scsi_buslogic.c 1.0.5 2018/03/08 + * Version: @(#)scsi_buslogic.c 1.0.6 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1466,7 +1466,7 @@ BuslogicDeviceReset(void *p) static void * -buslogic_init(device_t *info) +buslogic_init(const device_t *info) { x54x_t *dev; wchar_t *bios_rom_name; @@ -1548,6 +1548,7 @@ buslogic_init(device_t *info) dev->fw_rev = "AA335"; dev->ha_bps = 5000000.0; /* normal SCSI */ break; + case CHIP_BUSLOGIC_ISA: default: strcpy(dev->name, "BT-545S"); @@ -1561,6 +1562,7 @@ buslogic_init(device_t *info) dev->fw_rev = "AA421E"; dev->ha_bps = 10000000.0; /* fast SCSI */ break; + case CHIP_BUSLOGIC_MCA: strcpy(dev->name, "BT-640A"); bios_rom_name = L"roms/scsi/buslogic/bt-640a_bios.rom"; @@ -1575,6 +1577,7 @@ buslogic_init(device_t *info) mca_add(buslogic_mca_read, buslogic_mca_write, dev); dev->ha_bps = 5000000.0; /* normal SCSI */ break; + case CHIP_BUSLOGIC_VLB: strcpy(dev->name, "BT-445S"); bios_rom_name = L"roms/scsi/buslogic/bt-445s_bios.rom"; @@ -1588,6 +1591,7 @@ buslogic_init(device_t *info) dev->bit32 = 1; dev->ha_bps = 10000000.0; /* fast SCSI */ break; + case CHIP_BUSLOGIC_PCI: strcpy(dev->name, "BT-958D"); bios_rom_name = L"roms/scsi/buslogic/bt-958d_bios.rom"; @@ -1680,7 +1684,7 @@ buslogic_init(device_t *info) } -static device_config_t BT_ISA_Config[] = { +static const device_config_t BT_ISA_Config[] = { { "base", "Address", CONFIG_HEX16, "", 0x334, { @@ -1776,7 +1780,7 @@ static device_config_t BT_ISA_Config[] = { }; -static device_config_t BT958D_Config[] = { +static const device_config_t BT958D_Config[] = { { "bios", "Enable BIOS", CONFIG_BINARY, "", 0 }, @@ -1786,7 +1790,7 @@ static device_config_t BT958D_Config[] = { }; -device_t buslogic_device = { +const device_t buslogic_device = { "Buslogic BT-542BH ISA", DEVICE_ISA | DEVICE_AT, CHIP_BUSLOGIC_ISA_542, @@ -1795,7 +1799,7 @@ device_t buslogic_device = { BT_ISA_Config }; -device_t buslogic_545s_device = { +const device_t buslogic_545s_device = { "Buslogic BT-545S ISA", DEVICE_ISA | DEVICE_AT, CHIP_BUSLOGIC_ISA, @@ -1804,7 +1808,7 @@ device_t buslogic_545s_device = { BT_ISA_Config }; -device_t buslogic_640a_device = { +const device_t buslogic_640a_device = { "Buslogic BT-640A MCA", DEVICE_MCA, CHIP_BUSLOGIC_MCA, @@ -1813,7 +1817,7 @@ device_t buslogic_640a_device = { NULL }; -device_t buslogic_445s_device = { +const device_t buslogic_445s_device = { "Buslogic BT-445S ISA", DEVICE_VLB, CHIP_BUSLOGIC_VLB, @@ -1822,7 +1826,7 @@ device_t buslogic_445s_device = { BT_ISA_Config }; -device_t buslogic_pci_device = { +const device_t buslogic_pci_device = { "Buslogic BT-958D PCI", DEVICE_PCI, CHIP_BUSLOGIC_PCI, diff --git a/src/scsi/scsi_buslogic.h b/src/scsi/scsi_buslogic.h index f77b8a1..2361242 100644 --- a/src/scsi/scsi_buslogic.h +++ b/src/scsi/scsi_buslogic.h @@ -7,7 +7,7 @@ * Emulation of BusLogic BT-542B ISA and BT-958D PCI SCSI * controllers. * - * Version: @(#)scsi_buslogic.h 1.0.1 2018/02/14 + * Version: @(#)scsi_buslogic.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -37,11 +37,11 @@ # define SCSI_BUSLOGIC_H -extern device_t buslogic_device; -extern device_t buslogic_545s_device; -extern device_t buslogic_640a_device; -extern device_t buslogic_445s_device; -extern device_t buslogic_pci_device; +extern const device_t buslogic_device; +extern const device_t buslogic_545s_device; +extern const device_t buslogic_640a_device; +extern const device_t buslogic_445s_device; +extern const device_t buslogic_pci_device; extern void BuslogicDeviceReset(void *p); diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 41be788..893a8b1 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -8,7 +8,7 @@ * * Emulation of SCSI fixed and removable disks. * - * Version: @(#)scsi_disk.c 1.0.3 2018/03/08 + * Version: @(#)scsi_disk.c 1.0.4 2018/03/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -101,7 +101,7 @@ uint8_t scsi_hard_disks[16][8] = { /* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ -uint8_t scsi_hd_command_flags[0x100] = { +const uint8_t scsi_hd_command_flags[0x100] = { IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ 0, diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index 24b8d4c..82b3067 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -9,7 +9,7 @@ * Implementation of the NCR 5380 series of SCSI Host Adapters * made by NCR. These controllers were designed for the ISA bus. * - * Version: @(#)scsi_ncr5380.c 1.0.3 2018/03/08 + * Version: @(#)scsi_ncr5380.c 1.0.4 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -844,7 +844,7 @@ scsiat_out(uint16_t port, uint8_t val, void *priv) static void * -ncr_init(device_t *info) +ncr_init(const device_t *info) { char temp[128]; ncr_t *scsi; @@ -967,7 +967,7 @@ scsiat_available(void) } -static device_config_t scsiat_config[] = { +static const device_config_t scsiat_config[] = { { "base", "Address", CONFIG_HEX16, "", 0x0310, { @@ -1064,7 +1064,7 @@ static device_config_t scsiat_config[] = { }; -device_t scsi_lcs6821n_device = +const device_t scsi_lcs6821n_device = { "Longshine LCS-6821N", DEVICE_ISA, @@ -1075,7 +1075,7 @@ device_t scsi_lcs6821n_device = NULL }; -device_t scsi_rt1000b_device = +const device_t scsi_rt1000b_device = { "Ranco RT1000B", DEVICE_ISA, @@ -1086,7 +1086,7 @@ device_t scsi_rt1000b_device = NULL }; -device_t scsi_t130b_device = +const device_t scsi_t130b_device = { "Trantor T130B", DEVICE_ISA, @@ -1097,7 +1097,7 @@ device_t scsi_t130b_device = NULL }; -device_t scsi_scsiat_device = +const device_t scsi_scsiat_device = { "Sumo SCSI-AT", DEVICE_ISA, diff --git a/src/scsi/scsi_ncr5380.h b/src/scsi/scsi_ncr5380.h index 2cd43af..358cbd2 100644 --- a/src/scsi/scsi_ncr5380.h +++ b/src/scsi/scsi_ncr5380.h @@ -10,7 +10,7 @@ * made by NCR. These controllers were designed for * the ISA bus. * - * Version: @(#)scsi_ncr5380.c 1.0.1 2018/02/14 + * Version: @(#)scsi_ncr5380.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,10 +40,10 @@ # define SCSI_NCR5380_H -extern device_t scsi_lcs6821n_device; -extern device_t scsi_rt1000b_device; -extern device_t scsi_t130b_device; -extern device_t scsi_scsiat_device; +extern const device_t scsi_lcs6821n_device; +extern const device_t scsi_rt1000b_device; +extern const device_t scsi_t130b_device; +extern const device_t scsi_scsiat_device; + - #endif /*SCSI_NCR5380_H*/ diff --git a/src/scsi/scsi_ncr53c810.c b/src/scsi/scsi_ncr53c810.c index a9a4f9c..8b55ead 100644 --- a/src/scsi/scsi_ncr53c810.c +++ b/src/scsi/scsi_ncr53c810.c @@ -10,7 +10,7 @@ * NCR and later Symbios and LSI. This controller was designed * for the PCI bus. * - * Version: @(#)scsi_ncr53c810.c 1.0.4 2018/03/12 + * Version: @(#)scsi_ncr53c810.c 1.0.5 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -2156,7 +2156,7 @@ ncr53c810_pci_write(int func, int addr, uint8_t val, void *p) static void * -ncr53c810_init(device_t *info) +ncr53c810_init(const device_t *info) { ncr53c810_t *dev; @@ -2194,7 +2194,7 @@ ncr53c810_close(void *priv) } -device_t ncr53c810_pci_device = +const device_t ncr53c810_pci_device = { "NCR 53c810 (SCSI)", DEVICE_PCI, diff --git a/src/scsi/scsi_ncr53c810.h b/src/scsi/scsi_ncr53c810.h index c664546..3617926 100644 --- a/src/scsi/scsi_ncr53c810.h +++ b/src/scsi/scsi_ncr53c810.h @@ -8,7 +8,7 @@ * * Definitions for the NCR 53C810 SCSI Host Adapter driver. * - * Version: @(#)scsi_ncr53c810.h 1.0.1 2018/02/14 + * Version: @(#)scsi_ncr53c810.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -39,7 +39,7 @@ # define SCSI_NCR53C810_H -extern device_t ncr53c810_pci_device; +extern const device_t ncr53c810_pci_device; #endif /*SCSI_NCR53C810_H*/ diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index dc1a621..8ef2696 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -12,7 +12,7 @@ * * These controllers were designed for various buses. * - * Version: @(#)scsi_x54x.c 1.0.7 2018/03/12 + * Version: @(#)scsi_x54x.c 1.0.8 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1909,7 +1909,7 @@ x54x_mem_disable(x54x_t *dev) /* General initialization routine for all boards. */ void * -x54x_init(device_t *info) +x54x_init(const device_t *info) { x54x_t *dev; diff --git a/src/scsi/scsi_x54x.h b/src/scsi/scsi_x54x.h index 10e0d7c..aeb3154 100644 --- a/src/scsi/scsi_x54x.h +++ b/src/scsi/scsi_x54x.h @@ -8,7 +8,7 @@ * * Definitions for the common AHA/BL code. * - * Version: @(#)scsi_x54x.h 1.0.2 2018/03/08 + * Version: @(#)scsi_x54x.h 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -516,7 +516,7 @@ extern void x54x_mem_init(x54x_t *dev, uint32_t addr); extern void x54x_mem_enable(x54x_t *dev); extern void x54x_mem_set_addr(x54x_t *dev, uint32_t base); extern void x54x_mem_disable(x54x_t *dev); -extern void *x54x_init(device_t *info); +extern void *x54x_init(const device_t *info); extern void x54x_close(void *priv); extern void x54x_device_reset(void *priv); diff --git a/src/sound/midi.c b/src/sound/midi.c index a777fe7..41f56ff 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -8,7 +8,7 @@ * * MIDI support module, main file. * - * Version: @(#)midi.c 1.0.2 2018/03/10 + * Version: @(#)midi.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -58,25 +58,24 @@ int midi_device_current = 0; static int midi_device_last = 0; -typedef struct -{ - const char *name; - const char *internal_name; - device_t *device; +typedef struct { + const char *name; + const char *internal_name; + const device_t *device; } MIDI_DEVICE; -static MIDI_DEVICE devices[] = -{ - {"None", "none", NULL}, + +static const MIDI_DEVICE devices[] = { + {"None", "none", NULL}, #ifdef USE_FLUIDSYNTH - {"FluidSynth", "fluidsynth", &fluidsynth_device}, + {"FluidSynth", "fluidsynth", &fluidsynth_device}, #endif #ifdef USE_MUNT - {"Roland MT-32 Emulation", "mt32", &mt32_device}, - {"Roland CM-32L Emulation", "cm32l", &cm32l_device}, + {"Roland MT-32 Emulation", "mt32", &mt32_device}, + {"Roland CM-32L Emulation", "cm32l", &cm32l_device}, #endif - {SYSTEM_MIDI_NAME, SYSTEM_MIDI_INTERNAL_NAME, &system_midi_device}, - {"", "", NULL} + {SYSTEM_MIDI_NAME, SYSTEM_MIDI_INTERNAL_NAME, &system_midi_device}, + {"", "", NULL} }; static midi_device_t* m_device = NULL; @@ -94,7 +93,7 @@ char *midi_device_getname(int card) return (char *) devices[card].name; } -device_t *midi_device_getdevice(int card) +const device_t *midi_device_getdevice(int card) { return devices[card].device; } diff --git a/src/sound/midi.h b/src/sound/midi.h index 63479a3..806df87 100644 --- a/src/sound/midi.h +++ b/src/sound/midi.h @@ -8,7 +8,7 @@ * * Definitions for the MIDI module. * - * Version: @(#)midi.h 1.0.1 2018/02/14 + * Version: @(#)midi.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -46,7 +46,7 @@ extern int midi_device_current; int midi_device_available(int card); char *midi_device_getname(int card); #ifdef EMU_DEVICE_H -device_t *midi_device_getdevice(int card); +const device_t *midi_device_getdevice(int card); #endif int midi_device_has_config(int card); char *midi_device_get_internal_name(int card); diff --git a/src/sound/midi_fluidsynth.c b/src/sound/midi_fluidsynth.c index 10849c5..59836db 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -17,7 +17,7 @@ * website (for 32bit and 64bit Windows) are working, and * need no additional support files other than sound fonts. * - * Version: @(#)midi_fluidsynth.c 1.0.3 2018/03/10 + * Version: @(#)midi_fluidsynth.c 1.0.4 2018/03/15 * * Code borrowed from scummvm. * @@ -280,7 +280,7 @@ fluidsynth_sysex(uint8_t *data, unsigned int len) static void * -fluidsynth_init(device_t *info) +fluidsynth_init(const device_t *info) { fluidsynth_t* data = &fsdev; @@ -423,8 +423,7 @@ fluidsynth_close(void* priv) } -static device_config_t -fluidsynth_config[] = { +static const device_config_t fluidsynth_config[] = { { .name = "sound_font", .description = "Sound Font", @@ -600,7 +599,7 @@ fluidsynth_config[] = { }; -device_t fluidsynth_device = { +const device_t fluidsynth_device = { "FluidSynth", 0, 0, fluidsynth_init, diff --git a/src/sound/midi_fluidsynth.h b/src/sound/midi_fluidsynth.h index 21b0aa2..3c0efe5 100644 --- a/src/sound/midi_fluidsynth.h +++ b/src/sound/midi_fluidsynth.h @@ -8,7 +8,7 @@ * * Definitions for the FluidSynth driver. * - * Version: @(#)midi_fluidsynth.h 1.0.1 2018/02/14 + * Version: @(#)midi_fluidsynth.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -38,7 +38,7 @@ # define SOUND_MIDI_FLUIDSYNTH_H -extern device_t fluidsynth_device; +extern const device_t fluidsynth_device; #endif /*SOUND_MIDI_FLUIDSYNTH_H*/ diff --git a/src/sound/midi_mt32.c b/src/sound/midi_mt32.c index 83e6ec7..f9fb78f 100644 --- a/src/sound/midi_mt32.c +++ b/src/sound/midi_mt32.c @@ -8,7 +8,7 @@ * * Interface to the MuNT32 MIDI synthesizer. * - * Version: @(#)midi_mt32.c 1.0.1 2018/02/14 + * Version: @(#)midi_mt32.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -260,12 +260,12 @@ void* mt32emu_init(wchar_t *control_rom, wchar_t *pcm_rom) return dev; } -void *mt32_init(device_t *info) +void *mt32_init(const device_t *info) { return mt32emu_init(L"roms/sound/mt32/mt32_control.rom", L"roms/sound/mt32/mt32_pcm.rom"); } -void *cm32l_init(device_t *info) +void *cm32l_init(const device_t *info) { return mt32emu_init(L"roms/sound/cm32l/cm32l_control.rom", L"roms/sound/cm32l/cm32l_pcm.rom"); } @@ -303,7 +303,7 @@ void mt32_close(void* p) /* pclog("mt32 closed\n"); */ } -static device_config_t mt32_config[] = +static const device_config_t mt32_config[] = { { .name = "output_gain", @@ -350,7 +350,7 @@ static device_config_t mt32_config[] = } }; -device_t mt32_device = +const device_t mt32_device = { "Roland MT-32 Emulation", 0, @@ -365,7 +365,7 @@ device_t mt32_device = mt32_config }; -device_t cm32l_device = +const device_t cm32l_device = { "Roland CM-32L Emulation", 0, diff --git a/src/sound/midi_mt32.h b/src/sound/midi_mt32.h index 2fee668..70d3c55 100644 --- a/src/sound/midi_mt32.h +++ b/src/sound/midi_mt32.h @@ -8,7 +8,7 @@ * * Definitions for the MuNT32 synthesizer interface. * - * Version: @(#)midi_mt32.h 1.0.1 2018/02/14 + * Version: @(#)midi_mt32.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,8 +40,8 @@ # define SOUND_MIDI_MT32_H -extern device_t mt32_device; -extern device_t cm32l_device; +extern const device_t mt32_device; +extern const device_t cm32l_device; #endif /*SOUND_MIDI_MT32_H*/ diff --git a/src/sound/midi_system.c b/src/sound/midi_system.c index 6031a25..d5dd7ab 100644 --- a/src/sound/midi_system.c +++ b/src/sound/midi_system.c @@ -8,7 +8,7 @@ * * Interface to system MIDI driver. * - * Version: @(#)midi_system.c 1.0.2 2018/03/10 + * Version: @(#)midi_system.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -48,7 +48,7 @@ #include "midi_system.h" -void* system_midi_init(device_t *info) +void* system_midi_init(const device_t *info) { midi_device_t* dev = malloc(sizeof(midi_device_t)); memset(dev, 0, sizeof(midi_device_t)); @@ -76,7 +76,7 @@ int system_midi_available(void) return plat_midi_get_num_devs(); } -static device_config_t system_midi_config[] = +static const device_config_t system_midi_config[] = { { .name = "midi", @@ -89,7 +89,7 @@ static device_config_t system_midi_config[] = } }; -device_t system_midi_device = +const device_t system_midi_device = { SYSTEM_MIDI_NAME, 0, 0, diff --git a/src/sound/midi_system.h b/src/sound/midi_system.h index ff3932c..8e04958 100644 --- a/src/sound/midi_system.h +++ b/src/sound/midi_system.h @@ -8,7 +8,7 @@ * * Definitions for the System MIDI driver. * - * Version: @(#)midi_system.h 1.0.1 2018/02/14 + * Version: @(#)midi_system.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define SOUND_MIDI_SYSTEM_H -extern device_t system_midi_device; +extern const device_t system_midi_device; #endif /*SOUND_MIDI_SYSTEM_H*/ diff --git a/src/sound/snd_adlib.c b/src/sound/snd_adlib.c index 640a63c..515b2cf 100644 --- a/src/sound/snd_adlib.c +++ b/src/sound/snd_adlib.c @@ -8,7 +8,7 @@ * * Implementation of the ADLIB sound device. * - * Version: @(#)snd_adlib.c 1.0.1 2018/02/14 + * Version: @(#)snd_adlib.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -101,7 +101,7 @@ void adlib_mca_write(int port, uint8_t val, void *p) adlib->pos_regs[port & 7] = val; } -void *adlib_init(device_t *info) +void *adlib_init(const device_t *info) { adlib_t *adlib = malloc(sizeof(adlib_t)); memset(adlib, 0, sizeof(adlib_t)); @@ -113,7 +113,7 @@ void *adlib_init(device_t *info) return adlib; } -void *adlib_mca_init(device_t *info) +void *adlib_mca_init(const device_t *info) { adlib_t *adlib = adlib_init(info); @@ -132,7 +132,7 @@ void adlib_close(void *p) free(adlib); } -device_t adlib_device = +const device_t adlib_device = { "AdLib", DEVICE_ISA, @@ -142,7 +142,7 @@ device_t adlib_device = NULL }; -device_t adlib_mca_device = +const device_t adlib_mca_device = { "AdLib (MCA)", DEVICE_MCA, diff --git a/src/sound/snd_adlib.h b/src/sound/snd_adlib.h index 5ea3ad8..1955d74 100644 --- a/src/sound/snd_adlib.h +++ b/src/sound/snd_adlib.h @@ -8,7 +8,7 @@ * * Definitions for the ADLIB driver. * - * Version: @(#)snd_adlib.h 1.0.1 2018/02/14 + * Version: @(#)snd_adlib.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,8 +40,8 @@ # define SOUND_ADLIB_H -extern device_t adlib_device; -extern device_t adlib_mca_device; +extern const device_t adlib_device; +extern const device_t adlib_mca_device; #endif /*SOUND_ADLIB_H*/ diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index 41e6929..16c2d78 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -10,7 +10,7 @@ * * TODO: Stack allocation of big buffers (line 688 et al.) * - * Version: @(#)snd_adlibgold.c 1.0.3 2018/02/22 + * Version: @(#)snd_adlibgold.c 1.0.4 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -804,7 +804,7 @@ static void adgold_get_buffer(int32_t *buffer, int len, void *p) } -void *adgold_init(device_t *info) +void *adgold_init(const device_t *info) { FILE *f; int c; @@ -877,7 +877,7 @@ void adgold_close(void *p) free(adgold); } -static device_config_t adgold_config[] = +static const device_config_t adgold_config[] = { { "surround", "Surround module", CONFIG_BINARY, "", 1 @@ -887,7 +887,7 @@ static device_config_t adgold_config[] = } }; -device_t adgold_device = +const device_t adgold_device = { "AdLib Gold", DEVICE_ISA, 0, diff --git a/src/sound/snd_adlibgold.h b/src/sound/snd_adlibgold.h index e4b670e..3822dd8 100644 --- a/src/sound/snd_adlibgold.h +++ b/src/sound/snd_adlibgold.h @@ -8,7 +8,7 @@ * * Definitions for the Adlib Gold driver. * - * Version: @(#)snd_adlibgold.h 1.0.1 2018/02/14 + * Version: @(#)snd_adlibgold.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define SOUND_ADLIBGOLD_H -extern device_t adgold_device; +extern const device_t adgold_device; #endif /*SOUND_ADLIBGOLD_H*/ diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 51191c9..e90c878 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -8,7 +8,7 @@ * * Implementation of the AudioPCI sound device. * - * Version: @(#)snd_audiopci.c 1.0.3 2018/02/22 + * Version: @(#)snd_audiopci.c 1.0.4 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1139,7 +1139,7 @@ static void es1371_get_buffer(int32_t *buffer, int len, void *p) es1371->pos = 0; } -static void *es1371_init(device_t *info) +static void *es1371_init(const device_t *info) { es1371_t *es1371 = malloc(sizeof(es1371_t)); memset(es1371, 0, sizeof(es1371_t)); @@ -1167,7 +1167,7 @@ static void es1371_speed_changed(void *p) es1371->dac[1].latch = (int)((double)TIMER_USEC * (1000000.0 / 48000.0)); } -device_t es1371_device = +const device_t es1371_device = { "Ensoniq AudioPCI (ES1371)", DEVICE_PCI, diff --git a/src/sound/snd_audiopci.h b/src/sound/snd_audiopci.h index 39bba65..af775c9 100644 --- a/src/sound/snd_audiopci.h +++ b/src/sound/snd_audiopci.h @@ -8,7 +8,7 @@ * * Definitions for the AudioPCI driver. * - * Version: @(#)snd_audiopci.h 1.0.1 2018/02/14 + * Version: @(#)snd_audiopci.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define SOUND_AUDIOPCI_H -extern device_t es1371_device; +extern const device_t es1371_device; #endif /*SOUND_AUDIOPCI_H*/ diff --git a/src/sound/snd_cms.c b/src/sound/snd_cms.c index ac9118d..ec452f0 100644 --- a/src/sound/snd_cms.c +++ b/src/sound/snd_cms.c @@ -8,7 +8,7 @@ * * Implementation of the Create CMS/GameBlaster sound device. * - * Version: @(#)snd_cms.c 1.0.1 2018/02/14 + * Version: @(#)snd_cms.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -213,7 +213,7 @@ uint8_t cms_read(uint16_t addr, void *p) return 0xff; } -void *cms_init(device_t *info) +void *cms_init(const device_t *info) { cms_t *cms = malloc(sizeof(cms_t)); memset(cms, 0, sizeof(cms_t)); @@ -231,7 +231,7 @@ void cms_close(void *p) free(cms); } -device_t cms_device = +const device_t cms_device = { "Creative Music System / Game Blaster", 0, 0, diff --git a/src/sound/snd_cms.h b/src/sound/snd_cms.h index bf506fe..e76b35c 100644 --- a/src/sound/snd_cms.h +++ b/src/sound/snd_cms.h @@ -8,7 +8,7 @@ * * Definitions for the CMS/GameBlaster driver. * - * Version: @(#)snd_cms.h 1.0.1 2018/02/14 + * Version: @(#)snd_cms.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define SOUND_CMS_H -extern device_t cms_device; +extern const device_t cms_device; #endif /*SOUND_CMS_H*/ diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index f022208..b4b3f32 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -8,7 +8,7 @@ * * Implementation of Emu8000 emulator. * - * Version: @(#)snd_emu8k.c 1.0.2 2018/02/26 + * Version: @(#)snd_emu8k.c 1.0.3 2018/03/17 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -68,7 +68,7 @@ //#define EMU8K_DEBUG_REGISTERS -char *PORT_NAMES[][8] = +const char *PORT_NAMES[][8] = { /* Data 0 ( 0x620/0x622) */ { "AWE_CPF", @@ -151,23 +151,23 @@ int dmawritebit = 0; #define CUBIC_RESOLUTION_LOG 10 #define CUBIC_RESOLUTION (1<> 15 to move back to +/-1 range). */ -static int32_t lfotable[65536]; +static int32_t *lfotable; /* Table to transform the speed parameter to emu8k_mem_internal_t range. */ -static int64_t lfofreqtospeed[256]; +static int64_t *lfofreqtospeed; /* LFO used for the chorus. a sine wave.(signed 16bits with 32768 max int. >> 15 to move back to +/-1 range). */ -static double chortable[65536]; +static double *chortable; static const int REV_BUFSIZE_STEP=242; @@ -248,7 +248,7 @@ Coeff Low Fc(Hz)Low Q(dB)High Fc(kHz)High Q(dB)DC Attenuation(dB) * 15 100 28 7.0 18 -11.0 * * Attenuation as above, codified in amplitude.*/ -static int32_t filter_atten[16] = +static const int32_t filter_atten[16] = { 65536, 61869, 57079, 53269, 49145, 44820, 40877, 34792, 32845, 30653, 28607, 26392, 24630, 22463, 20487, 18470 @@ -2194,6 +2194,21 @@ void emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram) emu8k->empty = malloc(2*BLOCK_SIZE_WORDS); memset(emu8k->empty, 0, 2*BLOCK_SIZE_WORDS); + /* + * To save on .bss space, we allocate these on the + * heap as needed, and free them on device close. + */ + cubic_table = (float *)malloc(CUBIC_RESOLUTION*4*sizeof(float)); + freqtable = (int64_t *)malloc(65536*sizeof(int64_t)); + attentable = (int32_t *)malloc(256*sizeof(int32_t)); + env_vol_db_to_vol_target = (int32_t *)malloc(65537*sizeof(int32_t)); + env_vol_amplitude_to_db = (int32_t *)malloc(65537*sizeof(int32_t)); + env_mod_hertz_to_octave = (int32_t *)malloc(65537*sizeof(int32_t)); + env_attack_to_samples = (int32_t *)malloc(128*sizeof(int32_t)); + lfotable = (int32_t *)malloc(65536*sizeof(int32_t)); + lfofreqtospeed = (int64_t *)malloc(256*sizeof(int64_t)); + chortable = (double *)malloc(65536*sizeof(double)); + int j=0; for (;j<0x8;j++) { @@ -2420,5 +2435,17 @@ void emu8k_close(emu8k_t *emu8k) { free(emu8k->rom); free(emu8k->ram); + + /* Release the allocated buffers. */ + free(cubic_table); cubic_table = NULL; + free(freqtable); freqtable = NULL; + free(attentable); attentable = NULL; + free(env_vol_db_to_vol_target); env_vol_db_to_vol_target = NULL; + free(env_vol_amplitude_to_db); env_vol_amplitude_to_db = NULL; + free(env_mod_hertz_to_octave); env_mod_hertz_to_octave = NULL; + free(env_attack_to_samples); env_attack_to_samples = NULL; + free(lfotable); lfotable = NULL; + free(lfofreqtospeed); lfofreqtospeed = NULL; + free(chortable); chortable = NULL; } diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index 5c0f17c..72adbe8 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -8,7 +8,7 @@ * * Implementation of the Gravis UltraSound sound device. * - * Version: @(#)snd_gus.c 1.0.1 2018/02/14 + * Version: @(#)snd_gus.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1034,7 +1034,7 @@ static void gus_get_buffer(int32_t *buffer, int len, void *p) } -void *gus_init(device_t *info) +void *gus_init(const device_t *info) { int c; double out = 1.0; @@ -1096,7 +1096,7 @@ void gus_speed_changed(void *p) gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); } -device_t gus_device = +const device_t gus_device = { "Gravis UltraSound", 0, 0, diff --git a/src/sound/snd_gus.h b/src/sound/snd_gus.h index aec0c81..0656c0a 100644 --- a/src/sound/snd_gus.h +++ b/src/sound/snd_gus.h @@ -8,7 +8,7 @@ * * Definitions for the GUS device. * - * Version: @(#)snd_gus.h 1.0.1 2018/02/14 + * Version: @(#)snd_gus.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define SOUND_GUS_H -extern device_t gus_device; +extern const device_t gus_device; #endif /*SOUND_GUS_H*/ diff --git a/src/sound/snd_lpt_dac.c b/src/sound/snd_lpt_dac.c index 999623d..f98e447 100644 --- a/src/sound/snd_lpt_dac.c +++ b/src/sound/snd_lpt_dac.c @@ -8,7 +8,7 @@ * * Implemantation of LPT-based sound devices. * - * Version: @(#)snd_lpt_dac.c 1.0.1 2018/02/14 + * Version: @(#)snd_lpt_dac.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -142,7 +142,7 @@ static void dac_close(void *p) free(lpt_dac); } -lpt_device_t lpt_dac_device = +const lpt_device_t lpt_dac_device = { "LPT DAC / Covox Speech Thing", dac_init, @@ -151,7 +151,7 @@ lpt_device_t lpt_dac_device = dac_write_ctrl, dac_read_status }; -lpt_device_t lpt_dac_stereo_device = +const lpt_device_t lpt_dac_stereo_device = { "Stereo LPT DAC", dac_stereo_init, diff --git a/src/sound/snd_lpt_dac.h b/src/sound/snd_lpt_dac.h index 374a42e..32b7160 100644 --- a/src/sound/snd_lpt_dac.h +++ b/src/sound/snd_lpt_dac.h @@ -8,7 +8,7 @@ * * Definitions for the LPT-based sound devices. * - * Version: @(#)snd_lpt_dac.h 1.0.1 2018/02/14 + * Version: @(#)snd_lpt_dac.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,8 +40,8 @@ # define SOUND_LPT_DAC_H -extern lpt_device_t lpt_dac_device; -extern lpt_device_t lpt_dac_stereo_device; +extern const lpt_device_t lpt_dac_device; +extern const lpt_device_t lpt_dac_stereo_device; #endif /*SOUND_LPT_DAC_H*/ diff --git a/src/sound/snd_lpt_dss.c b/src/sound/snd_lpt_dss.c index 56be0c1..158f64b 100644 --- a/src/sound/snd_lpt_dss.c +++ b/src/sound/snd_lpt_dss.c @@ -8,7 +8,7 @@ * * Implementation of the LPT-based DSS sound device. * - * Version: @(#)snd_lpt_dss.c 1.0.1 2018/02/14 + * Version: @(#)snd_lpt_dss.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -148,7 +148,7 @@ static void dss_close(void *p) free(dss); } -lpt_device_t dss_device = +const lpt_device_t dss_device = { "Disney Sound Source", dss_init, diff --git a/src/sound/snd_lpt_dss.h b/src/sound/snd_lpt_dss.h index f51de7b..1096c2c 100644 --- a/src/sound/snd_lpt_dss.h +++ b/src/sound/snd_lpt_dss.h @@ -8,7 +8,7 @@ * * Definitions for the LPT-based DSS driver. * - * Version: @(#)snd_lpt_dss.h 1.0.1 2018/02/14 + * Version: @(#)snd_lpt_dss.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define SOUND_LPT_DSS_H -extern lpt_device_t dss_device; +extern const lpt_device_t dss_device; #endif /*SOUND_LPT_DSS_H*/ diff --git a/src/sound/snd_mpu401.c b/src/sound/snd_mpu401.c index cff271f..bdb06f7 100644 --- a/src/sound/snd_mpu401.c +++ b/src/sound/snd_mpu401.c @@ -8,7 +8,7 @@ * * Roland MPU-401 emulation. * - * Version: @(#)snd_mpu401.c 1.0.1 2018/02/14 + * Version: @(#)snd_mpu401.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -915,7 +915,7 @@ mpu401_device_add(void) static void * -mpu401_standalone_init(device_t *info) +mpu401_standalone_init(const device_t *info) { mpu_t *mpu; @@ -938,7 +938,7 @@ mpu401_standalone_close(void *priv) } -static device_config_t mpu401_standalone_config[] = +static const device_config_t mpu401_standalone_config[] = { { "base", "MPU-401 Address", CONFIG_HEX16, "", 0x330, @@ -1000,7 +1000,7 @@ static device_config_t mpu401_standalone_config[] = }; -device_t mpu401_device = { +const device_t mpu401_device = { "MPU-401 (Standalone)", 0, 0, mpu401_standalone_init, mpu401_standalone_close, NULL, diff --git a/src/sound/snd_mpu401.h b/src/sound/snd_mpu401.h index d82dc30..3295361 100644 --- a/src/sound/snd_mpu401.h +++ b/src/sound/snd_mpu401.h @@ -8,7 +8,7 @@ * * Roland MPU-401 emulation. * - * Version: @(#)snd_mpu401.h 1.0.1 2018/02/14 + * Version: @(#)snd_mpu401.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -112,7 +112,7 @@ void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode); extern int mpu401_standalone_enable; void mpu401_device_add(void); -device_t mpu401_device; +extern const device_t mpu401_device; void mpu401_uart_init(mpu_t *mpu, uint16_t addr); diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 3073db2..e39285f 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -79,7 +79,7 @@ * FF88 - board model * 3 = PAS16 * - * Version: @(#)snd_pas16.c 1.0.1 2018/02/14 + * Version: @(#)snd_pas16.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -758,7 +758,7 @@ void pas16_get_buffer(int32_t *buffer, int len, void *p) } -static void *pas16_init(device_t *info) +static void *pas16_init(const device_t *info) { pas16_t *pas16 = malloc(sizeof(pas16_t)); memset(pas16, 0, sizeof(pas16_t)); @@ -782,7 +782,7 @@ static void pas16_close(void *p) free(pas16); } -device_t pas16_device = +const device_t pas16_device = { "Pro Audio Spectrum 16", DEVICE_ISA | DEVICE_NOT_WORKING, diff --git a/src/sound/snd_pas16.h b/src/sound/snd_pas16.h index 37f5552..790bbd4 100644 --- a/src/sound/snd_pas16.h +++ b/src/sound/snd_pas16.h @@ -8,7 +8,7 @@ * * Definitions for the PAS16 driver. * - * Version: @(#)snd_pas16.h 1.0.1 2018/02/14 + * Version: @(#)snd_pas16.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define SOUND_PAS16_H -extern device_t pas16_device; +extern const device_t pas16_device; #endif /*SOUND_FLUIDSYNTH_H*/ diff --git a/src/sound/snd_pssj.c b/src/sound/snd_pssj.c index 3e98ced..54a8751 100644 --- a/src/sound/snd_pssj.c +++ b/src/sound/snd_pssj.c @@ -10,7 +10,7 @@ * * NOTE: Should be moved to the Tandy machine file. * - * Version: @(#)snd_pssj.c 1.0.1 2018/02/14 + * Version: @(#)snd_pssj.c 1.0.1 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -224,7 +224,7 @@ static void pssj_get_buffer(int32_t *buffer, int len, void *p) pssj->pos = 0; } -void *pssj_init(device_t *info) +void *pssj_init(const device_t *info) { pssj_t *pssj = malloc(sizeof(pssj_t)); memset(pssj, 0, sizeof(pssj_t)); @@ -245,7 +245,7 @@ void pssj_close(void *p) free(pssj); } -device_t pssj_device = +const device_t pssj_device = { "Tandy PSSJ", 0, 0, diff --git a/src/sound/snd_pssj.h b/src/sound/snd_pssj.h index 3a741cd..4b95537 100644 --- a/src/sound/snd_pssj.h +++ b/src/sound/snd_pssj.h @@ -8,7 +8,7 @@ * * Definitions for the PSSJ driver. * - * Version: @(#)snd_pssj.h 1.0.1 2018/02/14 + * Version: @(#)snd_pssj.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define SOUND_PSSJ_H -extern device_t pssj_device; +extern const device_t pssj_device; #endif /*SOUND_PSSJ_H*/ diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index ffee9c1..0fd3ca4 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -8,7 +8,7 @@ * * Sound Blaster emulation. * - * Version: @(#)sound_sb.c 1.0.2 2018/02/21 + * Version: @(#)sound_sb.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1036,7 +1036,7 @@ void sb_pro_mcv_write(int port, uint8_t val, void *p) sb_dsp_setdma8(&sb->dsp, sb->pos_regs[4] & 3); } -void *sb_1_init(struct _device_ *dev) +void *sb_1_init(const device_t *info) { /*sb1/2 port mappings, 210h to 260h in 10h steps 2x0 to 2x3 -> CMS chip @@ -1063,7 +1063,7 @@ void *sb_1_init(struct _device_ *dev) sound_add_handler(sb_get_buffer_sb2, sb); return sb; } -void *sb_15_init(struct _device_ *dev) +void *sb_15_init(const device_t *info) { /*sb1/2 port mappings, 210h to 260h in 10h steps 2x0 to 2x3 -> CMS chip @@ -1090,7 +1090,7 @@ void *sb_15_init(struct _device_ *dev) return sb; } -void *sb_mcv_init(struct _device_ *dev) +void *sb_mcv_init(const device_t *info) { /*sb1/2 port mappings, 210h to 260h in 10h steps 2x6, 2xA, 2xC, 2xE -> DSP chip @@ -1113,7 +1113,7 @@ void *sb_mcv_init(struct _device_ *dev) sb->pos_regs[1] = 0x50; return sb; } -void *sb_2_init(struct _device_ *dev) +void *sb_2_init(const device_t *info) { /*sb2 port mappings. 220h or 240h. 2x0 to 2x3 -> CMS chip @@ -1154,7 +1154,7 @@ void *sb_2_init(struct _device_ *dev) return sb; } -void *sb_pro_v1_init(struct _device_ *dev) +void *sb_pro_v1_init(const device_t *info) { /*sbpro port mappings. 220h or 240h. 2x0 to 2x3 -> FM chip, Left and Right (9*2 voices) @@ -1188,7 +1188,7 @@ void *sb_pro_v1_init(struct _device_ *dev) return sb; } -void *sb_pro_v2_init(struct _device_ *dev) +void *sb_pro_v2_init(const device_t *info) { /*sbpro port mappings. 220h or 240h. 2x0 to 2x3 -> FM chip (18 voices) @@ -1221,7 +1221,7 @@ void *sb_pro_v2_init(struct _device_ *dev) return sb; } -void *sb_pro_mcv_init(struct _device_ *dev) +void *sb_pro_mcv_init(const device_t *info) { /*sbpro port mappings. 220h or 240h. 2x0 to 2x3 -> FM chip, Left and Right (18 voices) @@ -1246,7 +1246,7 @@ void *sb_pro_mcv_init(struct _device_ *dev) return sb; } -void *sb_16_init(struct _device_ *dev) +void *sb_16_init(const device_t *info) { sb_t *sb = malloc(sizeof(sb_t)); uint16_t addr = device_get_config_hex16("base"); @@ -1280,7 +1280,7 @@ int sb_awe32_available() return rom_present(L"roms/sound/awe32.raw"); } -void *sb_awe32_init(struct _device_ *dev) +void *sb_awe32_init(const device_t *info) { sb_t *sb = malloc(sizeof(sb_t)); uint16_t addr = device_get_config_hex16("base"); @@ -1358,7 +1358,7 @@ void sb_add_status_info(char *s, int max_len, void *p) sb_dsp_add_status_info(s, max_len, &sb->dsp); } -static device_config_t sb_config[] = +static const device_config_t sb_config[] = { { "base", "Address", CONFIG_HEX16, "", 0x220, @@ -1416,7 +1416,7 @@ static device_config_t sb_config[] = } }; -static device_config_t sb_mcv_config[] = +static const device_config_t sb_mcv_config[] = { { "irq", "IRQ", CONFIG_SELECTION, "", 7, @@ -1457,7 +1457,7 @@ static device_config_t sb_mcv_config[] = } }; -static device_config_t sb_pro_config[] = +static const device_config_t sb_pro_config[] = { { "base", "Address", CONFIG_HEX16, "", 0x220, @@ -1515,7 +1515,7 @@ static device_config_t sb_pro_config[] = } }; -static device_config_t sb_16_config[] = +static const device_config_t sb_16_config[] = { { "base", "Address", CONFIG_HEX16, "", 0x220, @@ -1653,7 +1653,7 @@ static device_config_t sb_16_config[] = } }; -static device_config_t sb_awe32_config[] = +static const device_config_t sb_awe32_config[] = { { "base", "Address", CONFIG_HEX16, "", 0x220, @@ -1834,7 +1834,7 @@ static device_config_t sb_awe32_config[] = } }; -device_t sb_1_device = +const device_t sb_1_device = { "Sound Blaster v1.0", DEVICE_ISA, @@ -1845,7 +1845,7 @@ device_t sb_1_device = sb_add_status_info, sb_config }; -device_t sb_15_device = +const device_t sb_15_device = { "Sound Blaster v1.5", DEVICE_ISA, @@ -1856,7 +1856,7 @@ device_t sb_15_device = sb_add_status_info, sb_config }; -device_t sb_mcv_device = +const device_t sb_mcv_device = { "Sound Blaster MCV", DEVICE_MCA, @@ -1867,7 +1867,7 @@ device_t sb_mcv_device = sb_add_status_info, sb_mcv_config }; -device_t sb_2_device = +const device_t sb_2_device = { "Sound Blaster v2.0", DEVICE_ISA, @@ -1878,7 +1878,7 @@ device_t sb_2_device = sb_add_status_info, sb_config }; -device_t sb_pro_v1_device = +const device_t sb_pro_v1_device = { "Sound Blaster Pro v1", DEVICE_ISA, @@ -1889,7 +1889,7 @@ device_t sb_pro_v1_device = sb_add_status_info, sb_pro_config }; -device_t sb_pro_v2_device = +const device_t sb_pro_v2_device = { "Sound Blaster Pro v2", DEVICE_ISA, @@ -1900,7 +1900,7 @@ device_t sb_pro_v2_device = sb_add_status_info, sb_pro_config }; -device_t sb_pro_mcv_device = +const device_t sb_pro_mcv_device = { "Sound Blaster Pro MCV", DEVICE_MCA, @@ -1911,7 +1911,7 @@ device_t sb_pro_mcv_device = sb_add_status_info, NULL }; -device_t sb_16_device = +const device_t sb_16_device = { "Sound Blaster 16", DEVICE_ISA, @@ -1922,7 +1922,7 @@ device_t sb_16_device = sb_add_status_info, sb_16_config }; -device_t sb_awe32_device = +const device_t sb_awe32_device = { "Sound Blaster AWE32", DEVICE_ISA, diff --git a/src/sound/snd_sb.h b/src/sound/snd_sb.h index 60c36e5..9453985 100644 --- a/src/sound/snd_sb.h +++ b/src/sound/snd_sb.h @@ -8,7 +8,7 @@ * * Definitions for the Sound Blaster driver. * - * Version: @(#)sound_sb.h 1.0.1 2018/02/14 + * Version: @(#)sound_sb.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -53,15 +53,15 @@ #define SND_PAS16 10 /* Pro Audio Spectrum 16 */ -extern device_t sb_1_device; -extern device_t sb_15_device; -extern device_t sb_mcv_device; -extern device_t sb_2_device; -extern device_t sb_pro_v1_device; -extern device_t sb_pro_v2_device; -extern device_t sb_pro_mcv_device; -extern device_t sb_16_device; -extern device_t sb_awe32_device; +extern const device_t sb_1_device; +extern const device_t sb_15_device; +extern const device_t sb_mcv_device; +extern const device_t sb_2_device; +extern const device_t sb_pro_v1_device; +extern const device_t sb_pro_v2_device; +extern const device_t sb_pro_mcv_device; +extern const device_t sb_16_device; +extern const device_t sb_awe32_device; #endif /*SOUND_SNDB_H*/ diff --git a/src/sound/snd_sn76489.c b/src/sound/snd_sn76489.c index 5eaddba..c454b10 100644 --- a/src/sound/snd_sn76489.c +++ b/src/sound/snd_sn76489.c @@ -8,7 +8,7 @@ * * Implementation of the TI SN74689 PSG sound devices. * - * Version: @(#)snd_sn76489.c 1.0.1 2018/02/14 + * Version: @(#)snd_sn76489.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -243,7 +243,7 @@ void sn76489_init(sn76489_t *sn76489, uint16_t base, uint16_t size, int type, in io_sethandler(base, size, NULL, NULL, NULL, sn76489_write, NULL, NULL, sn76489); } -void *sn76489_device_init(device_t *info) +void *sn76489_device_init(const device_t *info) { sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); memset(sn76489, 0, sizeof(sn76489_t)); @@ -252,7 +252,7 @@ void *sn76489_device_init(device_t *info) return sn76489; } -void *ncr8496_device_init(device_t *info) +void *ncr8496_device_init(const device_t *info) { sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); memset(sn76489, 0, sizeof(sn76489_t)); @@ -269,7 +269,7 @@ void sn76489_device_close(void *p) free(sn76489); } -device_t sn76489_device = +const device_t sn76489_device = { "TI SN74689 PSG", 0, @@ -279,7 +279,7 @@ device_t sn76489_device = NULL, NULL, NULL, NULL, NULL }; -device_t ncr8496_device = +const device_t ncr8496_device = { "NCR8496 PSG", 0, diff --git a/src/sound/snd_sn76489.h b/src/sound/snd_sn76489.h index ca03eb4..5d9505d 100644 --- a/src/sound/snd_sn76489.h +++ b/src/sound/snd_sn76489.h @@ -8,7 +8,7 @@ * * Definitions for the TI SN74689 PSG driver. * - * Version: @(#)snd_sn76489.h 1.0.1 2018/02/14 + * Version: @(#)snd_sn76489.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -47,8 +47,8 @@ enum PSSJ }; -extern device_t sn76489_device; -extern device_t ncr8496_device; +extern const device_t sn76489_device; +extern const device_t ncr8496_device; extern int sn76489_mute; diff --git a/src/sound/snd_ssi2001.c b/src/sound/snd_ssi2001.c index 9cfac03..f1b7580 100644 --- a/src/sound/snd_ssi2001.c +++ b/src/sound/snd_ssi2001.c @@ -8,7 +8,7 @@ * * Implementation of the SSI2001 sound device. * - * Version: @(#)snd_si2001.c 1.0.1 2018/02/14 + * Version: @(#)snd_si2001.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -95,7 +95,7 @@ static void ssi2001_write(uint16_t addr, uint8_t val, void *p) sid_write(addr, val, p); } -void *ssi2001_init(device_t *info) +void *ssi2001_init(const device_t *info) { ssi2001_t *ssi2001 = malloc(sizeof(ssi2001_t)); memset(ssi2001, 0, sizeof(ssi2001_t)); @@ -117,7 +117,7 @@ void ssi2001_close(void *p) free(ssi2001); } -device_t ssi2001_device = +const device_t ssi2001_device = { "Innovation SSI-2001", 0, 0, diff --git a/src/sound/snd_ssi2001.h b/src/sound/snd_ssi2001.h index 862cf5e..d119e68 100644 --- a/src/sound/snd_ssi2001.h +++ b/src/sound/snd_ssi2001.h @@ -8,7 +8,7 @@ * * Definitions for the SSI2001 driver. * - * Version: @(#)snd_si2001.h 1.0.1 2018/02/14 + * Version: @(#)snd_si2001.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define SOUND_SSI2001_H -extern device_t ssi2001_device; +extern const device_t ssi2001_device; #endif /*SOUND_SSI2001_H*/ diff --git a/src/sound/snd_wss.c b/src/sound/snd_wss.c index a5f0f18..7d5413e 100644 --- a/src/sound/snd_wss.c +++ b/src/sound/snd_wss.c @@ -8,7 +8,7 @@ * * Implementation of the Windows Sound System sound device. * - * Version: @(#)snd_wss.c 1.0.1 2018/02/14 + * Version: @(#)snd_wss.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -111,7 +111,7 @@ static void wss_get_buffer(int32_t *buffer, int len, void *p) wss->ad1848.pos = 0; } -void *wss_init(device_t *info) +void *wss_init(const device_t *info) { wss_t *wss = malloc(sizeof(wss_t)); @@ -146,7 +146,7 @@ void wss_speed_changed(void *p) ad1848_speed_changed(&wss->ad1848); } -device_t wss_device = +const device_t wss_device = { "Windows Sound System", DEVICE_ISA, 0, diff --git a/src/sound/snd_wss.h b/src/sound/snd_wss.h index 2fed3d6..c837224 100644 --- a/src/sound/snd_wss.h +++ b/src/sound/snd_wss.h @@ -8,7 +8,7 @@ * * Definitions for the WSS driver. * - * Version: @(#)snd_wss.h 1.0.1 2018/02/14 + * Version: @(#)snd_wss.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define SOUND_WSS_H -extern device_t wss_device; +extern const device_t wss_device; #endif /*SOUND_WSS_H*/ diff --git a/src/sound/sound.c b/src/sound/sound.c index 3de7bd1..2ec03eb 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -8,7 +8,7 @@ * * Sound emulation core. * - * Version: @(#)sound.c 1.0.1 2018/02/14 + * Version: @(#)sound.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -63,9 +63,9 @@ typedef struct { - const char *name; - const char *internal_name; - device_t *device; + const char *name; + const char *internal_name; + const device_t *device; } SOUND_CARD; typedef struct { @@ -97,7 +97,7 @@ static int cd_buf_update = CD_BUFLEN / SOUNDBUFLEN; static volatile int cdaudioon = 0; -static SOUND_CARD sound_cards[] = +static const SOUND_CARD sound_cards[] = { { "None", "none", NULL }, { "[ISA] Adlib", "adlib", &adlib_device }, @@ -135,7 +135,7 @@ char *sound_card_getname(int card) return (char *)sound_cards[card].name; } -device_t *sound_card_getdevice(int card) +const device_t *sound_card_getdevice(int card) { return sound_cards[card].device; } diff --git a/src/sound/sound.h b/src/sound/sound.h index 582ae39..d3137b4 100644 --- a/src/sound/sound.h +++ b/src/sound/sound.h @@ -8,7 +8,7 @@ * * Definitions for the Sound Emulation core. * - * Version: @(#)sound.h 1.0.1 2018/02/14 + * Version: @(#)sound.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -65,7 +65,7 @@ extern void sound_add_process_handler(void (*get_buffer)(int32_t *buffer, \ extern int sound_card_available(int card); extern char *sound_card_getname(int card); #ifdef EMU_DEVICE_H -extern device_t *sound_card_getdevice(int card); +extern const device_t *sound_card_getdevice(int card); #endif extern int sound_card_has_config(int card); extern char *sound_card_get_internal_name(int card); diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index f2946fc..f1f4576 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -8,7 +8,7 @@ * * ATI 18800 emulation (VGA Edge-16) * - * Version: @(#)vid_ati18800.c 1.0.2 2018/02/22 + * Version: @(#)vid_ati18800.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -179,7 +179,7 @@ static uint8_t ati18800_in(uint16_t addr, void *p) return temp; } -static void *ati18800_init(device_t *info) +static void *ati18800_init(const device_t *info) { ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); memset(ati18800, 0, sizeof(ati18800_t)); @@ -258,7 +258,7 @@ static void ati18800_add_status_info(char *s, int max_len, void *p) svga_add_status_info(s, max_len, &ati18800->svga); } -device_t ati18800_wonder_device = +const device_t ati18800_wonder_device = { "ATI-18800", DEVICE_ISA, ATI18800_WONDER, @@ -272,7 +272,7 @@ device_t ati18800_wonder_device = NULL }; -device_t ati18800_vga88_device = +const device_t ati18800_vga88_device = { "ATI-18800-1", DEVICE_ISA, ATI18800_VGA88, @@ -286,7 +286,7 @@ device_t ati18800_vga88_device = NULL }; -device_t ati18800_device = +const device_t ati18800_device = { "ATI-18800-5", DEVICE_ISA, ATI18800_EDGE16, diff --git a/src/video/vid_ati18800.h b/src/video/vid_ati18800.h index 0655fce..c822217 100644 --- a/src/video/vid_ati18800.h +++ b/src/video/vid_ati18800.h @@ -8,7 +8,7 @@ * * Definitions for the ATI18800 driver. * - * Version: @(#)vid_ati18800.h 1.0.1 2018/02/14 + * Version: @(#)vid_ati18800.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,9 +40,9 @@ # define VIDEO_ATI18800_H -extern device_t ati18800_wonder_device; -extern device_t ati18800_vga88_device; -extern device_t ati18800_device; +extern const device_t ati18800_wonder_device; +extern const device_t ati18800_vga88_device; +extern const device_t ati18800_device; #endif /*VIDEO_ATI18800_H*/ diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 9300849..af7d1eb 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -8,7 +8,7 @@ * * ATI 28800 emulation (VGA Charger and Korean VGA) * - * Version: @(#)vid_ati28800.c 1.0.5 2018/03/12 + * Version: @(#)vid_ati28800.c 1.0.6 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -83,13 +83,15 @@ typedef struct ati28800_t } ati28800_t; +int ksc5601_mode_enabled; + + static uint8_t port_03dd_val; static uint16_t get_korean_font_kind; static int in_get_korean_font_kind_set; static int get_korean_font_enabled; static int get_korean_font_index; static uint16_t get_korean_font_base; -int ksc5601_mode_enabled; static void ati28800_out(uint16_t addr, uint8_t val, void *p) @@ -363,7 +365,7 @@ static void ati28800_recalctimings(svga_t *svga) } static void * -ati28800_init(device_t *info) +ati28800_init(const device_t *info) { ati28800_t *ati; @@ -373,7 +375,7 @@ ati28800_init(device_t *info) ati->memory = device_get_config_int("memory"); switch(info->local) { - case GFX_VGAWONDERXL: + case VID_VGAWONDERXL: rom_init_interleaved(&ati->bios_rom, BIOS_VGAXL_EVEN_PATH, BIOS_VGAXL_ODD_PATH, @@ -382,7 +384,7 @@ ati28800_init(device_t *info) break; #if defined(DEV_BRANCH) && defined(USE_XL24) - case GFX_VGAWONDERXL24: + case VID_VGAWONDERXL24: rom_init_interleaved(&ati->bios_rom, BIOS_XL24_EVEN_PATH, BIOS_XL24_ODD_PATH, @@ -430,7 +432,7 @@ void ati28800k_recalctimings(svga_t *svga) } void * -ati28800k_init(device_t *info) +ati28800k_init(const device_t *info) { ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); memset(ati28800, 0, sizeof(ati28800_t)); @@ -472,16 +474,18 @@ ati28800_available(void) static int -ati28800k_available() +ati28800k_available(void) { - return((rom_present(BIOS_ATIKOR_PATH) && rom_present(FONT_ATIKOR_PATH))); + return((rom_present(BIOS_ATIKOR_PATH) && + rom_present(FONT_ATIKOR_PATH))); } static int compaq_ati28800_available(void) { - return((rom_present(BIOS_VGAXL_EVEN_PATH) && rom_present(BIOS_VGAXL_ODD_PATH))); + return((rom_present(BIOS_VGAXL_EVEN_PATH) && + rom_present(BIOS_VGAXL_ODD_PATH))); } @@ -489,7 +493,8 @@ compaq_ati28800_available(void) static int ati28800_wonderxl24_available(void) { - return((rom_present(BIOS_XL24_EVEN_PATH) && rom_present(BIOS_XL24_ODD_PATH))); + return((rom_present(BIOS_XL24_EVEN_PATH) && + rom_present(BIOS_XL24_ODD_PATH))); } #endif @@ -541,7 +546,7 @@ static void ati28800_add_status_info(char *s, int max_len, void *priv) } -static device_config_t ati28800_config[] = +static const device_config_t ati28800_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 512, @@ -566,7 +571,7 @@ static device_config_t ati28800_config[] = }; #if defined(DEV_BRANCH) && defined(USE_XL24) -static device_config_t ati28800_wonderxl_config[] = +static const device_config_t ati28800_wonderxl_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 512, @@ -591,56 +596,52 @@ static device_config_t ati28800_wonderxl_config[] = }; #endif -device_t ati28800_device = -{ - "ATI-28800", - DEVICE_ISA, - 0, - ati28800_init, ati28800_close, NULL, - ati28800_available, - ati28800_speed_changed, - ati28800_force_redraw, - ati28800_add_status_info, - ati28800_config +const device_t ati28800_device = { + "ATI-28800", + DEVICE_ISA, + 0, + ati28800_init, ati28800_close, NULL, + ati28800_available, + ati28800_speed_changed, + ati28800_force_redraw, + ati28800_add_status_info, + ati28800_config }; -device_t ati28800k_device = -{ - "ATI Korean VGA", - DEVICE_ISA, - 0, - ati28800k_init, ati28800_close, NULL, - ati28800k_available, - ati28800_speed_changed, - ati28800_force_redraw, - ati28800k_add_status_info, - ati28800_config +const device_t ati28800k_device = { + "ATI Korean VGA", + DEVICE_ISA, + VID_ATIKOREANVGA, + ati28800k_init, ati28800_close, NULL, + ati28800k_available, + ati28800_speed_changed, + ati28800_force_redraw, + ati28800k_add_status_info, + ati28800_config }; -device_t compaq_ati28800_device = -{ - "Compaq ATI-28800", - DEVICE_ISA, - GFX_VGAWONDERXL, - ati28800_init, ati28800_close, NULL, - compaq_ati28800_available, - ati28800_speed_changed, - ati28800_force_redraw, - ati28800_add_status_info, - ati28800_config +const device_t compaq_ati28800_device = { + "Compaq ATI-28800", + DEVICE_ISA, + VID_VGAWONDERXL, + ati28800_init, ati28800_close, NULL, + compaq_ati28800_available, + ati28800_speed_changed, + ati28800_force_redraw, + ati28800_add_status_info, + ati28800_config }; #if defined(DEV_BRANCH) && defined(USE_XL24) -device_t ati28800_wonderxl24_device = -{ - "ATI-28800 (VGA Wonder XL24)", - DEVICE_ISA, - GFX_VGAWONDERXL24, - ati28800_init, ati28800_close, NULL, - ati28800_wonderxl24_available, - ati28800_speed_changed, - ati28800_force_redraw, - ati28800_add_status_info, - ati28800_wonderxl_config +const device_t ati28800_wonderxl24_device = { + "ATI-28800 (VGA Wonder XL24)", + DEVICE_ISA, + VID_VGAWONDERXL24, + ati28800_init, ati28800_close, NULL, + ati28800_wonderxl24_available, + ati28800_speed_changed, + ati28800_force_redraw, + ati28800_add_status_info, + ati28800_wonderxl_config }; #endif diff --git a/src/video/vid_ati28800.h b/src/video/vid_ati28800.h index d02cdfd..4cd8dca 100644 --- a/src/video/vid_ati28800.h +++ b/src/video/vid_ati28800.h @@ -8,7 +8,7 @@ * * Definitions for the ATI28800 driver. * - * Version: @(#)vid_ati28800.h 1.0.2 2018/03/04 + * Version: @(#)vid_ati28800.h 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,11 +40,11 @@ # define VIDEO_ATI28800_H -extern device_t ati28800_device; -extern device_t ati28800k_device; -extern device_t compaq_ati28800_device; +extern const device_t ati28800_device; +extern const device_t ati28800k_device; +extern const device_t compaq_ati28800_device; #if defined(DEV_BRANCH) && defined(USE_XL24) -extern device_t ati28800_wonderxl24_device; +extern const device_t ati28800_wonderxl24_device; #endif diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 8a5accd..cc26c97 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -8,7 +8,7 @@ * * ATi Mach64 graphics card emulation. * - * Version: @(#)vid_ati_mach64.c 1.0.5 2018/03/12 + * Version: @(#)vid_ati_mach64.c 1.0.6 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -3403,7 +3403,7 @@ void mach64_pci_write(int func, int addr, uint8_t val, void *p) } } -static void *mach64_common_init(device_t *info) +static void *mach64_common_init(const device_t *info) { mach64_t *mach64 = malloc(sizeof(mach64_t)); memset(mach64, 0, sizeof(mach64_t)); @@ -3449,7 +3449,7 @@ static void *mach64_common_init(device_t *info) return mach64; } -static void *mach64gx_init(device_t *info) +static void *mach64gx_init(const device_t *info) { mach64_t *mach64 = mach64_common_init(info); @@ -3474,7 +3474,7 @@ static void *mach64gx_init(device_t *info) return mach64; } -static void *mach64vt2_init(device_t *info) +static void *mach64vt2_init(const device_t *info) { mach64_t *mach64 = mach64_common_init(info); svga_t *svga = &mach64->svga; @@ -3587,7 +3587,7 @@ void mach64_add_status_info(char *s, int max_len, void *p) mach64->blitter_time = 0; } -static device_config_t mach64gx_config[] = +static const device_config_t mach64gx_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 4, @@ -3611,7 +3611,7 @@ static device_config_t mach64gx_config[] = } }; -static device_config_t mach64vt2_config[] = +static const device_config_t mach64vt2_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 4, @@ -3632,7 +3632,7 @@ static device_config_t mach64vt2_config[] = } }; -device_t mach64gx_isa_device = +const device_t mach64gx_isa_device = { "ATI Mach64GX ISA", DEVICE_AT | DEVICE_ISA, @@ -3645,7 +3645,7 @@ device_t mach64gx_isa_device = mach64gx_config }; -device_t mach64gx_vlb_device = +const device_t mach64gx_vlb_device = { "ATI Mach64GX VLB", DEVICE_VLB, @@ -3658,7 +3658,7 @@ device_t mach64gx_vlb_device = mach64gx_config }; -device_t mach64gx_pci_device = +const device_t mach64gx_pci_device = { "ATI Mach64GX PCI", DEVICE_PCI, @@ -3671,7 +3671,7 @@ device_t mach64gx_pci_device = mach64gx_config }; -device_t mach64vt2_device = +const device_t mach64vt2_device = { "ATI Mach64VT2", DEVICE_PCI, diff --git a/src/video/vid_ati_mach64.h b/src/video/vid_ati_mach64.h index 408819d..9459aa8 100644 --- a/src/video/vid_ati_mach64.h +++ b/src/video/vid_ati_mach64.h @@ -8,7 +8,7 @@ * * Definitions for the ATi Mach64 driver. * - * Version: @(#)vid_ati_mach64.h 1.0.1 2018/02/14 + * Version: @(#)vid_ati_mach64.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,10 +40,10 @@ # define VIDEO_ATI_MACH64_H -extern device_t mach64gx_isa_device; -extern device_t mach64gx_vlb_device; -extern device_t mach64gx_pci_device; -extern device_t mach64vt2_device; +extern const device_t mach64gx_isa_device; +extern const device_t mach64gx_vlb_device; +extern const device_t mach64gx_pci_device; +extern const device_t mach64vt2_device; #endif /*VIDEO_ATI_MACH64_H*/ diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index 46579a5..486e291 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -8,7 +8,7 @@ * * Emulation of the old and new IBM CGA graphics cards. * - * Version: @(#)vid_cga.c 1.0.1 2018/02/14 + * Version: @(#)vid_cga.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -488,7 +488,7 @@ void cga_init(cga_t *cga) cga->composite = 0; } -void *cga_standalone_init(device_t *info) +void *cga_standalone_init(const device_t *info) { int display_type; cga_t *cga = malloc(sizeof(cga_t)); @@ -530,7 +530,7 @@ void cga_speed_changed(void *p) cga_recalctimings(cga); } -device_config_t cga_config[] = +const device_config_t cga_config[] = { { "display_type", "Display type", CONFIG_SELECTION, "", CGA_RGB, @@ -591,7 +591,7 @@ device_config_t cga_config[] = } }; -device_t cga_device = +const device_t cga_device = { "CGA", DEVICE_ISA, 0, diff --git a/src/video/vid_cga.h b/src/video/vid_cga.h index 0c22f1b..8fa8db1 100644 --- a/src/video/vid_cga.h +++ b/src/video/vid_cga.h @@ -8,7 +8,7 @@ * * Definitions for the CGA driver. * - * Version: @(#)vid_cga.h 1.0.1 2018/02/14 + * Version: @(#)vid_cga.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -85,8 +85,8 @@ uint8_t cga_read(uint32_t addr, void *p); void cga_recalctimings(cga_t *cga); void cga_poll(void *p); -extern device_config_t cga_config[]; -extern device_t cga_device; +extern const device_config_t cga_config[]; +extern const device_t cga_device; #endif /*VIDEO_CGA_H*/ diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 61cab79..d2e67c1 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -9,7 +9,7 @@ * Emulation of select Cirrus Logic cards (CL-GD 5428, * CL-GD 5429, 5430, 5434 and 5436 are supported). * - * Version: @(#)vid_cl54xx.c 1.0.7 2018/03/08 + * Version: @(#)vid_cl54xx.c 1.0.8 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -2267,8 +2267,8 @@ cl_pci_write(int func, int addr, uint8_t val, void *p) } -static void -*gd54xx_init(device_t *info) +static void * +gd54xx_init(const device_t *info) { gd54xx_t *gd54xx = malloc(sizeof(gd54xx_t)); svga_t *svga = &gd54xx->svga; @@ -2450,7 +2450,7 @@ gd54xx_add_status_info(char *s, int max_len, void *p) } -static device_config_t gd5428_config[] = +static const device_config_t gd5428_config[] = { { .name = "memory", @@ -2477,7 +2477,7 @@ static device_config_t gd5428_config[] = } }; -static device_config_t gd5434_config[] = +static const device_config_t gd5434_config[] = { { .name = "memory", @@ -2505,7 +2505,7 @@ static device_config_t gd5434_config[] = }; -device_t gd5428_isa_device = +const device_t gd5428_isa_device = { "Cirrus Logic GD5428 (ISA)", DEVICE_AT | DEVICE_ISA, @@ -2520,7 +2520,7 @@ device_t gd5428_isa_device = gd5428_config }; -device_t gd5428_vlb_device = +const device_t gd5428_vlb_device = { "Cirrus Logic GD5428 (VLB)", DEVICE_VLB, @@ -2535,7 +2535,7 @@ device_t gd5428_vlb_device = gd5428_config }; -device_t gd5429_isa_device = +const device_t gd5429_isa_device = { "Cirrus Logic GD5429 (ISA)", DEVICE_AT | DEVICE_ISA, @@ -2550,7 +2550,7 @@ device_t gd5429_isa_device = gd5428_config }; -device_t gd5429_vlb_device = +const device_t gd5429_vlb_device = { "Cirrus Logic GD5429 (VLB)", DEVICE_VLB, @@ -2565,7 +2565,7 @@ device_t gd5429_vlb_device = gd5428_config }; -device_t gd5430_vlb_device = +const device_t gd5430_vlb_device = { "Cirrus Logic GD5430 (VLB)", DEVICE_VLB, @@ -2580,7 +2580,7 @@ device_t gd5430_vlb_device = gd5428_config }; -device_t gd5430_pci_device = +const device_t gd5430_pci_device = { "Cirrus Logic GD5430 (PCI)", DEVICE_PCI, @@ -2595,7 +2595,7 @@ device_t gd5430_pci_device = gd5428_config }; -device_t gd5434_isa_device = +const device_t gd5434_isa_device = { "Cirrus Logic GD5434 (ISA)", DEVICE_AT | DEVICE_ISA, @@ -2610,7 +2610,7 @@ device_t gd5434_isa_device = gd5434_config }; -device_t gd5434_vlb_device = +const device_t gd5434_vlb_device = { "Cirrus Logic GD5434 (VLB)", DEVICE_VLB, @@ -2625,7 +2625,7 @@ device_t gd5434_vlb_device = gd5434_config }; -device_t gd5434_pci_device = +const device_t gd5434_pci_device = { "Cirrus Logic GD5434 (PCI)", DEVICE_PCI, @@ -2640,7 +2640,7 @@ device_t gd5434_pci_device = gd5434_config }; -device_t gd5436_pci_device = +const device_t gd5436_pci_device = { "Cirrus Logic GD5436 (PCI)", DEVICE_PCI, diff --git a/src/video/vid_cl54xx.h b/src/video/vid_cl54xx.h index 97f795f..c02432f 100644 --- a/src/video/vid_cl54xx.h +++ b/src/video/vid_cl54xx.h @@ -8,7 +8,7 @@ * * Definitions for the CLGD5428 driver. * - * Version: @(#)vid_cl54xx.h 1.0.3 2018/03/04 + * Version: @(#)vid_cl54xx.h 1.0.4 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,16 +40,16 @@ # define VIDEO_CL54XX_H -extern device_t gd5428_isa_device; -extern device_t gd5428_vlb_device; -extern device_t gd5429_isa_device; -extern device_t gd5429_vlb_device; -extern device_t gd5430_vlb_device; -extern device_t gd5430_pci_device; -extern device_t gd5434_isa_device; -extern device_t gd5434_vlb_device; -extern device_t gd5434_pci_device; -extern device_t gd5436_pci_device; +extern const device_t gd5428_isa_device; +extern const device_t gd5428_vlb_device; +extern const device_t gd5429_isa_device; +extern const device_t gd5429_vlb_device; +extern const device_t gd5430_vlb_device; +extern const device_t gd5430_pci_device; +extern const device_t gd5434_isa_device; +extern const device_t gd5434_vlb_device; +extern const device_t gd5434_pci_device; +extern const device_t gd5436_pci_device; #endif /*VIDEO_CL54XX_H*/ diff --git a/src/video/vid_colorplus.c b/src/video/vid_colorplus.c index e8fe87c..27746a6 100644 --- a/src/video/vid_colorplus.c +++ b/src/video/vid_colorplus.c @@ -8,7 +8,7 @@ * * Plantronics ColorPlus emulation. * - * Version: @(#)vid_colorplus.c 1.0.1 2018/02/14 + * Version: @(#)vid_colorplus.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -405,7 +405,7 @@ void colorplus_init(colorplus_t *colorplus) cga_init(&colorplus->cga); } -void *colorplus_standalone_init(device_t *info) +void *colorplus_standalone_init(const device_t *info) { int display_type; @@ -446,7 +446,7 @@ void colorplus_speed_changed(void *p) cga_recalctimings(&colorplus->cga); } -static device_config_t colorplus_config[] = +static const device_config_t colorplus_config[] = { { "display_type", "Display type", CONFIG_SELECTION, "", CGA_RGB, @@ -484,7 +484,7 @@ static device_config_t colorplus_config[] = } }; -device_t colorplus_device = +const device_t colorplus_device = { "Colorplus", DEVICE_ISA, 0, diff --git a/src/video/vid_colorplus.h b/src/video/vid_colorplus.h index af09bbf..393c3d3 100644 --- a/src/video/vid_colorplus.h +++ b/src/video/vid_colorplus.h @@ -8,7 +8,7 @@ * * Definitions for the ColorPlus driver. * - * Version: @(#)vid_colorplus.h 1.0.1 2018/02/14 + * Version: @(#)vid_colorplus.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -54,7 +54,7 @@ uint8_t colorplus_read(uint32_t addr, void *p); void colorplus_recalctimings(colorplus_t *colorplus); void colorplus_poll(void *p); -extern device_t colorplus_device; +extern const device_t colorplus_device; #endif /*VIDEO_COLORPLUS_H*/ diff --git a/src/video/vid_compaq_cga.c b/src/video/vid_compaq_cga.c index b280be5..cba7f84 100644 --- a/src/video/vid_compaq_cga.c +++ b/src/video/vid_compaq_cga.c @@ -8,7 +8,7 @@ * * Implementation of CGA used by Compaq PC's. * - * Version: @(#)vid_cga_compaq.c 1.0.1 2018/02/14 + * Version: @(#)vid_cga_compaq.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -397,7 +397,7 @@ void compaq_cga_poll(void *p) } -void *compaq_cga_init(device_t *info) +void *compaq_cga_init(const device_t *info) { int display_type; int c; @@ -469,9 +469,9 @@ void compaq_cga_speed_changed(void *p) } } -extern device_config_t cga_config[]; +extern const device_config_t cga_config[]; -device_t compaq_cga_device = +const device_t compaq_cga_device = { "Compaq CGA", DEVICE_ISA, 0, @@ -485,7 +485,7 @@ device_t compaq_cga_device = cga_config }; -device_t compaq_cga_2_device = +const device_t compaq_cga_2_device = { "Compaq CGA 2", DEVICE_ISA, 1, diff --git a/src/video/vid_compaq_cga.h b/src/video/vid_compaq_cga.h index dc53454..f6ee906 100644 --- a/src/video/vid_compaq_cga.h +++ b/src/video/vid_compaq_cga.h @@ -8,7 +8,7 @@ * * Definitions for the Compaq CGA driver. * - * Version: @(#)vid_cga_compaq.h 1.0.1 2018/02/14 + * Version: @(#)vid_cga_compaq.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,8 +40,8 @@ #ifdef EMU_DEVICE_H -extern device_t compaq_cga_device; -extern device_t compaq_cga_2_device; +extern const device_t compaq_cga_device; +extern const device_t compaq_cga_2_device; #endif diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 7cdb862..241dc68 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -9,7 +9,7 @@ * Emulation of the EGA, Chips & Technologies SuperEGA, and * AX JEGA graphics cards. * - * Version: @(#)vid_ega.c 1.0.3 2018/03/08 + * Version: @(#)vid_ega.c 1.0.4 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1009,7 +1009,7 @@ void ega_init(ega_t *ega, int monitor_type, int is_mono) } -static void *ega_standalone_init(device_t *info) +static void *ega_standalone_init(const device_t *info) { ega_t *ega = malloc(sizeof(ega_t)); int monitor_type; @@ -1154,7 +1154,7 @@ static void LoadFontxFile(wchar_t *fname) fclose(mfile); } -void *jega_standalone_init(device_t *info) +void *jega_standalone_init(const device_t *info) { ega_t *ega = (ega_t *)ega_standalone_init(info); @@ -1203,7 +1203,7 @@ static void ega_speed_changed(void *p) } -static device_config_t ega_config[] = +static const device_config_t ega_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 256, @@ -1264,7 +1264,7 @@ static device_config_t ega_config[] = }; -device_t ega_device = +const device_t ega_device = { "EGA", DEVICE_ISA, @@ -1277,7 +1277,7 @@ device_t ega_device = ega_config }; -device_t cpqega_device = +const device_t cpqega_device = { "Compaq EGA", DEVICE_ISA, @@ -1290,7 +1290,7 @@ device_t cpqega_device = ega_config }; -device_t sega_device = +const device_t sega_device = { "SuperEGA", DEVICE_ISA, @@ -1304,7 +1304,7 @@ device_t sega_device = }; #ifdef JEGA -device_t jega_device = +const device_t jega_device = { "AX JEGA", DEVICE_ISA, diff --git a/src/video/vid_ega.h b/src/video/vid_ega.h index 5c5872f..bc1d414 100644 --- a/src/video/vid_ega.h +++ b/src/video/vid_ega.h @@ -8,7 +8,7 @@ * * Definitions for the IBM EGA driver. * - * Version: @(#)vid_ega.h 1.0.1 2018/02/14 + * Version: @(#)vid_ega.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -133,13 +133,13 @@ typedef struct ega_t { #ifdef EMU_DEVICE_H -extern device_t ega_device; -extern device_t cpqega_device; -extern device_t sega_device; +extern const device_t ega_device; +extern const device_t cpqega_device; +extern const device_t sega_device; #endif #ifdef JEGA -extern uint8_t jfont_sbcs_19[SBCS19_LEN]; /* 256 * 19( * 8) */ -extern uint8_t jfont_dbcs_16[DBCS16_LEN]; /* 65536 * 16 * 2 (* 8) */ +extern const uint8_t jfont_sbcs_19[SBCS19_LEN]; /* 256 * 19( * 8) */ +extern const uint8_t jfont_dbcs_16[DBCS16_LEN]; /* 65536 * 16 * 2 (* 8) */ #endif extern int update_overscan; diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 168afe0..90d161e 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -8,7 +8,7 @@ * * Emulation of the Tseng Labs ET4000. * - * Version: @(#)vid_et4000.c 1.0.3 2018/03/04 + * Version: @(#)vid_et4000.c 1.0.4 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -181,7 +181,7 @@ void et4000_recalctimings(svga_t *svga) } } -void *et4000_init(device_t *info) +void *et4000_init(const device_t *info) { et4000_t *et4000 = malloc(sizeof(et4000_t)); memset(et4000, 0, sizeof(et4000_t)); @@ -234,7 +234,7 @@ void et4000_add_status_info(char *s, int max_len, void *p) svga_add_status_info(s, max_len, &et4000->svga); } -device_t et4000_device = +const device_t et4000_device = { "Tseng Labs ET4000AX", DEVICE_ISA, 0, diff --git a/src/video/vid_et4000.h b/src/video/vid_et4000.h index dda0564..52fadd9 100644 --- a/src/video/vid_et4000.h +++ b/src/video/vid_et4000.h @@ -8,7 +8,7 @@ * * Definitions for the ET4000 driver. * - * Version: @(#)vid_et4000.h 1.0.1 2018/02/14 + * Version: @(#)vid_et4000.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define VIDEO_ET4000_H -extern device_t et4000_device; +extern const device_t et4000_device; #endif /*VIDEO_ET4000_H*/ diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 73c2f07..a5efc84 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -10,7 +10,7 @@ * * Known bugs: Accelerator doesn't work in planar modes * - * Version: @(#)vid_et4000w32.c 1.0.3 2018/03/08 + * Version: @(#)vid_et4000w32.c 1.0.4 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1210,7 +1210,7 @@ void et4000w32p_pci_write(int func, int addr, uint8_t val, void *p) } } -void *et4000w32p_init(device_t *info) +void *et4000w32p_init(const device_t *info) { int vram_size; et4000w32p_t *et4000 = malloc(sizeof(et4000w32p_t)); @@ -1329,7 +1329,7 @@ void et4000w32p_add_status_info(char *s, int max_len, void *p) et4000->blitter_time = 0; } -static device_config_t et4000w32p_config[] = +static const device_config_t et4000w32p_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 2, @@ -1350,7 +1350,7 @@ static device_config_t et4000w32p_config[] = } }; -device_t et4000w32p_cardex_vlb_device = +const device_t et4000w32p_cardex_vlb_device = { "Tseng Labs ET4000/w32p VLB (Cardex)", DEVICE_VLB, ET4000W32_CARDEX, @@ -1362,7 +1362,7 @@ device_t et4000w32p_cardex_vlb_device = et4000w32p_config }; -device_t et4000w32p_cardex_pci_device = +const device_t et4000w32p_cardex_pci_device = { "Tseng Labs ET4000/w32p PCI (Cardex)", DEVICE_PCI, ET4000W32_CARDEX, @@ -1375,7 +1375,7 @@ device_t et4000w32p_cardex_pci_device = }; #if defined(DEV_BRANCH) && defined(USE_STEALTH32) -device_t et4000w32p_vlb_device = +const device_t et4000w32p_vlb_device = { "Tseng Labs ET4000/w32p VLB (Diamond)", DEVICE_VLB, ET4000W32_DIAMOND, @@ -1387,7 +1387,7 @@ device_t et4000w32p_vlb_device = et4000w32p_config }; -device_t et4000w32p_pci_device = +const device_t et4000w32p_pci_device = { "Tseng Labs ET4000/w32p PCI (Diamond)", DEVICE_PCI, ET4000W32_DIAMOND, diff --git a/src/video/vid_et4000w32.h b/src/video/vid_et4000w32.h index 135cbcf..1703680 100644 --- a/src/video/vid_et4000w32.h +++ b/src/video/vid_et4000w32.h @@ -8,7 +8,7 @@ * * Definitions for the ET4000w32 driver. * - * Version: @(#)vid_et4000w32.h 1.0.1 2018/02/14 + * Version: @(#)vid_et4000w32.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -41,12 +41,12 @@ #if defined(DEV_BRANCH) && defined(USE_STEALTH32) -extern device_t et4000w32p_vlb_device; -extern device_t et4000w32p_pci_device; +extern const device_t et4000w32p_vlb_device; +extern const device_t et4000w32p_pci_device; #endif -extern device_t et4000w32p_cardex_vlb_device; -extern device_t et4000w32p_cardex_pci_device; +extern const device_t et4000w32p_cardex_vlb_device; +extern const device_t et4000w32p_cardex_pci_device; #endif /*VIDEO_ET4000W32_H*/ diff --git a/src/video/vid_genius.c b/src/video/vid_genius.c index 3e747c8..abcd9d0 100644 --- a/src/video/vid_genius.c +++ b/src/video/vid_genius.c @@ -63,7 +63,7 @@ * reducing the height of characters so they fit in an 8x12 cell * if necessary. * - * Version: @(#)vid_genius.c 1.0.2 2018/02/22 + * Version: @(#)vid_genius.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -594,7 +594,7 @@ void genius_poll(void *p) } } -void *genius_init(device_t *info) +void *genius_init(const device_t *info) { int c; genius_t *genius = malloc(sizeof(genius_t)); @@ -662,7 +662,7 @@ void genius_speed_changed(void *p) genius_recalctimings(genius); } -device_t genius_device = +const device_t genius_device = { "Genius VHR", DEVICE_ISA, 0, diff --git a/src/video/vid_genius.h b/src/video/vid_genius.h index cdd945e..433185d 100644 --- a/src/video/vid_genius.h +++ b/src/video/vid_genius.h @@ -8,7 +8,7 @@ * * Definitions for the GeniusVHR driver. * - * Version: @(#)vid_genius.h 1.0.1 2018/02/14 + * Version: @(#)vid_genius.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define VIDEO_GENIUS_H -extern device_t genius_device; +extern const device_t genius_device; #endif /*VIDEO_GENIUS_H*/ diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index a441fdc..d94bf8a 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -8,7 +8,7 @@ * * Hercules emulation. * - * Version: @(#)vid_hercules.c 1.0.1 2018/02/14 + * Version: @(#)vid_hercules.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -351,7 +351,7 @@ void hercules_poll(void *p) } -void *hercules_init(device_t *info) +void *hercules_init(const device_t *info) { int c; hercules_t *hercules = malloc(sizeof(hercules_t)); @@ -411,7 +411,7 @@ void hercules_speed_changed(void *p) hercules_recalctimings(hercules); } -static device_config_t hercules_config[] = +static const device_config_t hercules_config[] = { { "rgb_type", "Display type", CONFIG_SELECTION, "", 0, @@ -439,7 +439,7 @@ static device_config_t hercules_config[] = }; -device_t hercules_device = +const device_t hercules_device = { "Hercules", DEVICE_ISA, 0, diff --git a/src/video/vid_hercules.h b/src/video/vid_hercules.h index 596a0c8..fb27711 100644 --- a/src/video/vid_hercules.h +++ b/src/video/vid_hercules.h @@ -8,7 +8,7 @@ * * Definitions for the Hercules driver. * - * Version: @(#)vid_hercules.h 1.0.1 2018/02/14 + * Version: @(#)vid_hercules.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define VIDEO_HERCULES_H -extern device_t hercules_device; +extern const device_t hercules_device; #endif /*VIDEO_HERCULES_H*/ diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index 0f217dc..323d1a8 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -8,7 +8,7 @@ * * Hercules InColor emulation. * - * Version: @(#)vid_hercules_plus.c 1.0.2 2018/03/08 + * Version: @(#)vid_hercules_plus.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -698,7 +698,7 @@ void herculesplus_poll(void *p) } } -void *herculesplus_init(device_t *info) +void *herculesplus_init(const device_t *info) { int c; herculesplus_t *herculesplus = malloc(sizeof(herculesplus_t)); @@ -749,7 +749,7 @@ void herculesplus_speed_changed(void *p) herculesplus_recalctimings(herculesplus); } -device_t herculesplus_device = +const device_t herculesplus_device = { "Hercules Plus", DEVICE_ISA, 0, diff --git a/src/video/vid_herculesplus.h b/src/video/vid_herculesplus.h index 7a907a8..62c5b23 100644 --- a/src/video/vid_herculesplus.h +++ b/src/video/vid_herculesplus.h @@ -8,7 +8,7 @@ * * Definitions for the HerculesPlus driver. * - * Version: @(#)vid_hercules_plus.h 1.0.1 2018/02/14 + * Version: @(#)vid_hercules_plus.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define VIDEO_HERCULES_PLUS_H -extern device_t herculesplus_device; +extern const device_t herculesplus_device; #endif /*VIDEO_HERCULES_PLUS_H*/ diff --git a/src/video/vid_incolor.c b/src/video/vid_incolor.c index b6e6b93..84184bb 100644 --- a/src/video/vid_incolor.c +++ b/src/video/vid_incolor.c @@ -8,7 +8,7 @@ * * Hercules InColor emulation. * - * Version: @(#)vid_incolor.c 1.0.2 2018/03/08 + * Version: @(#)vid_incolor.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1045,7 +1045,7 @@ void incolor_poll(void *p) } } -void *incolor_init(device_t *info) +void *incolor_init(const device_t *info) { int c; incolor_t *incolor = malloc(sizeof(incolor_t)); @@ -1093,7 +1093,7 @@ void incolor_speed_changed(void *p) incolor_recalctimings(incolor); } -device_t incolor_device = +const device_t incolor_device = { "Hercules InColor", DEVICE_ISA, 0, diff --git a/src/video/vid_incolor.h b/src/video/vid_incolor.h index 3d6b1bc..1791a7e 100644 --- a/src/video/vid_incolor.h +++ b/src/video/vid_incolor.h @@ -8,7 +8,7 @@ * * Definitions for the InColor driver. * - * Version: @(#)vid_incolor.h 1.0.1 2018/02/14 + * Version: @(#)vid_incolor.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define VIDEO_INCOLOR_H -extern device_t incolor_device; +extern const device_t incolor_device; #endif /*VIDEO_INCOLOR_H*/ diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index 107bcd1..82364b4 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -8,7 +8,7 @@ * * MDA emulation. * - * Version: @(#)vid_mda.c 1.0.1 2018/02/14 + * Version: @(#)vid_mda.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -300,7 +300,7 @@ void mda_poll(void *p) } -void *mda_init(device_t *info) +void *mda_init(const device_t *info) { int c; mda_t *mda = malloc(sizeof(mda_t)); @@ -360,7 +360,7 @@ void mda_speed_changed(void *p) mda_recalctimings(mda); } -static device_config_t mda_config[] = +static const device_config_t mda_config[] = { { "rgb_type", "Display type", CONFIG_SELECTION, "", 0, @@ -388,7 +388,7 @@ static device_config_t mda_config[] = }; -device_t mda_device = +const device_t mda_device = { "MDA", DEVICE_ISA, 0, diff --git a/src/video/vid_mda.h b/src/video/vid_mda.h index 266e366..0cebab9 100644 --- a/src/video/vid_mda.h +++ b/src/video/vid_mda.h @@ -8,7 +8,7 @@ * * Definitions for the MDA driver. * - * Version: @(#)vid_mda.h 1.0.1 2018/02/14 + * Version: @(#)vid_mda.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define VIDEO_MDA_H -extern device_t mda_device; +extern const device_t mda_device; #endif /*VIDEO_MDA_H*/ diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index 3a03bc1..02e19dc 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -8,7 +8,7 @@ * * Oak OTI037C/67/077 emulation. * - * Version: @(#)vid_oak_oti.c 1.0.5 2018/03/05 + * Version: @(#)vid_oak_oti.c 1.0.6 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -242,7 +242,7 @@ oti_recalctimings(svga_t *svga) static void * -oti_init(device_t *info) +oti_init(const device_t *info) { oti_t *oti = malloc(sizeof(oti_t)); wchar_t *romfn = NULL; @@ -340,7 +340,7 @@ oti067_available(void) } -static device_config_t oti067_config[] = +static const device_config_t oti067_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 512, @@ -369,7 +369,7 @@ oti077_available(void) } -static device_config_t oti077_config[] = +static const device_config_t oti077_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 1024, @@ -393,7 +393,7 @@ static device_config_t oti077_config[] = } }; -device_t oti037c_device = +const device_t oti037c_device = { "Oak OTI-037C", DEVICE_ISA, @@ -406,7 +406,7 @@ device_t oti037c_device = oti067_config }; -device_t oti067_device = +const device_t oti067_device = { "Oak OTI-067", DEVICE_ISA, @@ -419,7 +419,7 @@ device_t oti067_device = oti067_config }; -device_t oti077_device = +const device_t oti077_device = { "Oak OTI-077", DEVICE_ISA, diff --git a/src/video/vid_oak_oti.h b/src/video/vid_oak_oti.h index 535875d..4ac106e 100644 --- a/src/video/vid_oak_oti.h +++ b/src/video/vid_oak_oti.h @@ -8,7 +8,7 @@ * * Definitions for the OAK067 driver. * - * Version: @(#)vid_oti067.h 1.0.2 2018/03/04 + * Version: @(#)vid_oti067.h 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,10 +40,10 @@ # define VIDEO_OTI067_H -extern device_t oti037c_device; -extern device_t oti067_device; -extern device_t oti067_acer386_device; -extern device_t oti077_device; +extern const device_t oti037c_device; +extern const device_t oti067_device; +extern const device_t oti067_acer386_device; +extern const device_t oti077_device; #endif /*VIDEO_OTI067_H*/ diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 6dfaae6..6c79450 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -13,7 +13,7 @@ * NOTE: The MegaPC video device should be moved to the MegaPC * machine file. * - * Version: @(#)vid_paradise.c 1.0.2 2018/02/22 + * Version: @(#)vid_paradise.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -302,7 +302,7 @@ static uint16_t paradise_readw(uint32_t addr, void *p) return svga_readw_linear(addr, ¶dise->svga); } -void *paradise_pvga1a_init(device_t *info, uint32_t memsize) +void *paradise_pvga1a_init(const device_t *info, uint32_t memsize) { paradise_t *paradise = malloc(sizeof(paradise_t)); svga_t *svga = ¶dise->svga; @@ -335,7 +335,7 @@ void *paradise_pvga1a_init(device_t *info, uint32_t memsize) return paradise; } -void *paradise_wd90c11_init(device_t *info) +void *paradise_wd90c11_init(const device_t *info) { paradise_t *paradise = malloc(sizeof(paradise_t)); svga_t *svga = ¶dise->svga; @@ -370,7 +370,7 @@ void *paradise_wd90c11_init(device_t *info) return paradise; } -void *paradise_wd90c30_init(device_t *info, uint32_t memsize) +void *paradise_wd90c30_init(const device_t *info, uint32_t memsize) { paradise_t *paradise = malloc(sizeof(paradise_t)); svga_t *svga = ¶dise->svga; @@ -405,7 +405,7 @@ void *paradise_wd90c30_init(device_t *info, uint32_t memsize) return paradise; } -static void *paradise_pvga1a_pc2086_init(device_t *info) +static void *paradise_pvga1a_pc2086_init(const device_t *info) { paradise_t *paradise = paradise_pvga1a_init(info, 1 << 18); @@ -414,7 +414,7 @@ static void *paradise_pvga1a_pc2086_init(device_t *info) return paradise; } -static void *paradise_pvga1a_pc3086_init(device_t *info) +static void *paradise_pvga1a_pc3086_init(const device_t *info) { paradise_t *paradise = paradise_pvga1a_init(info, 1 << 18); @@ -424,7 +424,7 @@ static void *paradise_pvga1a_pc3086_init(device_t *info) return paradise; } -static void *paradise_pvga1a_standalone_init(device_t *info) +static void *paradise_pvga1a_standalone_init(const device_t *info) { paradise_t *paradise; uint32_t memory = 512; @@ -445,7 +445,7 @@ static int paradise_pvga1a_standalone_available(void) return rom_present(L"roms/video/paradise/pvga1a/bios.bin"); } -static void *paradise_wd90c11_megapc_init(device_t *info) +static void *paradise_wd90c11_megapc_init(const device_t *info) { paradise_t *paradise = paradise_wd90c11_init(info); @@ -458,7 +458,7 @@ static void *paradise_wd90c11_megapc_init(device_t *info) return paradise; } -static void *paradise_wd90c11_standalone_init(device_t *info) +static void *paradise_wd90c11_standalone_init(const device_t *info) { paradise_t *paradise = paradise_wd90c11_init(info); @@ -473,7 +473,7 @@ static int paradise_wd90c11_standalone_available(void) return rom_present(L"roms/video/wd/wd90c11/wd90c11.vbi"); } -static void *paradise_wd90c30_standalone_init(device_t *info) +static void *paradise_wd90c30_standalone_init(const device_t *info) { paradise_t *paradise; uint32_t memory = 512; @@ -525,7 +525,7 @@ void paradise_add_status_info(char *s, int max_len, void *p) } -device_t paradise_pvga1a_pc2086_device = +const device_t paradise_pvga1a_pc2086_device = { "Paradise PVGA1A (Amstrad PC2086)", 0, @@ -538,7 +538,7 @@ device_t paradise_pvga1a_pc2086_device = paradise_force_redraw, paradise_add_status_info }; -device_t paradise_pvga1a_pc3086_device = +const device_t paradise_pvga1a_pc3086_device = { "Paradise PVGA1A (Amstrad PC3086)", 0, @@ -552,7 +552,7 @@ device_t paradise_pvga1a_pc3086_device = paradise_add_status_info }; -static device_config_t paradise_pvga1a_config[] = +static const device_config_t paradise_pvga1a_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 512, @@ -576,7 +576,7 @@ static device_config_t paradise_pvga1a_config[] = } }; -device_t paradise_pvga1a_device = +const device_t paradise_pvga1a_device = { "Paradise PVGA1A", DEVICE_ISA, @@ -590,7 +590,7 @@ device_t paradise_pvga1a_device = paradise_add_status_info, paradise_pvga1a_config }; -device_t paradise_wd90c11_megapc_device = +const device_t paradise_wd90c11_megapc_device = { "Paradise WD90C11 (Amstrad MegaPC)", 0, @@ -603,7 +603,7 @@ device_t paradise_wd90c11_megapc_device = paradise_force_redraw, paradise_add_status_info }; -device_t paradise_wd90c11_device = +const device_t paradise_wd90c11_device = { "Paradise WD90C11-LR", DEVICE_ISA, @@ -617,7 +617,7 @@ device_t paradise_wd90c11_device = paradise_add_status_info }; -static device_config_t paradise_wd90c30_config[] = +static const device_config_t paradise_wd90c30_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 1024, @@ -638,7 +638,7 @@ static device_config_t paradise_wd90c30_config[] = } }; -device_t paradise_wd90c30_device = +const device_t paradise_wd90c30_device = { "Paradise WD90C30-LR", DEVICE_ISA, diff --git a/src/video/vid_paradise.h b/src/video/vid_paradise.h index 9716ee8..44aa4c1 100644 --- a/src/video/vid_paradise.h +++ b/src/video/vid_paradise.h @@ -8,7 +8,7 @@ * * Definitions for the Paradise driver. * - * Version: @(#)vid_paradise.h 1.0.1 2018/02/14 + * Version: @(#)vid_paradise.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,12 +40,12 @@ # define VIDEO_PARADISE_H -extern device_t paradise_pvga1a_pc2086_device; -extern device_t paradise_pvga1a_pc3086_device; -extern device_t paradise_pvga1a_device; -extern device_t paradise_wd90c11_megapc_device; -extern device_t paradise_wd90c11_device; -extern device_t paradise_wd90c30_device; +extern const device_t paradise_pvga1a_pc2086_device; +extern const device_t paradise_pvga1a_pc3086_device; +extern const device_t paradise_pvga1a_device; +extern const device_t paradise_wd90c11_megapc_device; +extern const device_t paradise_wd90c11_device; +extern const device_t paradise_wd90c30_device; #endif /*VIDEO_PARADISE_H*/ diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 374ad61..3d5b96f 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -10,7 +10,7 @@ * * NOTE: ROM images need more/better organization per chipset. * - * Version: @(#)vid_s3.c 1.0.4 2018/03/08 + * Version: @(#)vid_s3.c 1.0.5 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -2187,7 +2187,7 @@ static int vram_sizes[] = 3 /*8 MB*/ }; -static void *s3_init(device_t *info, wchar_t *bios_fn, int chip) +static void *s3_init(const device_t *info, wchar_t *bios_fn, int chip) { s3_t *s3 = malloc(sizeof(s3_t)); svga_t *svga = &s3->svga; @@ -2281,7 +2281,7 @@ static void *s3_init(device_t *info, wchar_t *bios_fn, int chip) return s3; } -void *s3_vision864_init(device_t *info, wchar_t *bios_fn) +void *s3_vision864_init(const device_t *info, wchar_t *bios_fn) { s3_t *s3 = s3_init(info, bios_fn, S3_VISION864); @@ -2296,13 +2296,13 @@ void *s3_vision864_init(device_t *info, wchar_t *bios_fn) } -static void *s3_bahamas64_init(device_t *info) +static void *s3_bahamas64_init(const device_t *info) { s3_t *s3 = s3_vision864_init(info, L"roms/video/s3/s3/bahamas64.bin"); return s3; } -static void *s3_phoenix_vision864_init(device_t *info) +static void *s3_phoenix_vision864_init(const device_t *info) { s3_t *s3 = s3_vision864_init(info, L"roms/video/s3/s3/86c864p.bin"); return s3; @@ -2318,7 +2318,7 @@ static int s3_phoenix_vision864_available(void) return rom_present(L"roms/video/s3/s3/86c864p.bin"); } -static void *s3_phoenix_trio32_init(device_t *info) +static void *s3_phoenix_trio32_init(const device_t *info) { s3_t *s3 = s3_init(info, L"roms/video/s3/s3/86c732p.bin", S3_TRIO32); @@ -2338,7 +2338,7 @@ static int s3_phoenix_trio32_available(void) return rom_present(L"roms/video/s3/s3/86c732p.bin"); } -static void *s3_trio64_init(device_t *info, wchar_t *bios_fn) +static void *s3_trio64_init(const device_t *info, wchar_t *bios_fn) { s3_t *s3 = s3_init(info, bios_fn, S3_TRIO64); @@ -2352,13 +2352,13 @@ static void *s3_trio64_init(device_t *info, wchar_t *bios_fn) return s3; } -static void *s3_9fx_init(device_t *info) +static void *s3_9fx_init(const device_t *info) { s3_t *s3 = s3_trio64_init(info, L"roms/video/s3/s3/s3_764.bin"); return s3; } -static void *s3_phoenix_trio64_init(device_t *info) +static void *s3_phoenix_trio64_init(const device_t *info) { s3_t *s3 = s3_trio64_init(info, L"roms/video/s3/s3/86c764x1.bin"); if (device_get_config_int("memory") == 1) @@ -2366,7 +2366,7 @@ static void *s3_phoenix_trio64_init(device_t *info) return s3; } -static void *s3_phoenix_trio64_onboard_init(device_t *info) +static void *s3_phoenix_trio64_onboard_init(const device_t *info) { s3_t *s3 = s3_trio64_init(info, NULL); if (device_get_config_int("memory") == 1) @@ -2374,7 +2374,7 @@ static void *s3_phoenix_trio64_onboard_init(device_t *info) return s3; } -static void *s3_diamond_stealth64_init(device_t *info) +static void *s3_diamond_stealth64_init(const device_t *info) { s3_t *s3 = s3_trio64_init(info, L"roms/video/s3/s3/stealt64.bin"); if (device_get_config_int("memory") == 1) @@ -2442,7 +2442,7 @@ static void s3_add_status_info(char *s, int max_len, void *p) s3->blitter_time = 0; } -static device_config_t s3_bahamas64_config[] = +static const device_config_t s3_bahamas64_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 4, @@ -2467,7 +2467,7 @@ static device_config_t s3_bahamas64_config[] = } }; -static device_config_t s3_9fx_config[] = +static const device_config_t s3_9fx_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 2, @@ -2503,7 +2503,7 @@ static device_config_t s3_9fx_config[] = } }; -static device_config_t s3_phoenix_trio32_config[] = +static const device_config_t s3_phoenix_trio32_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 2, @@ -2527,7 +2527,7 @@ static device_config_t s3_phoenix_trio32_config[] = } }; -static device_config_t s3_phoenix_trio64_onboard_config[] = +static const device_config_t s3_phoenix_trio64_onboard_config[] = { { "memory", "Video memory size", CONFIG_SELECTION, "", 4, @@ -2551,7 +2551,7 @@ static device_config_t s3_phoenix_trio64_onboard_config[] = } }; -static device_config_t s3_phoenix_trio64_config[] = +static const device_config_t s3_phoenix_trio64_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 4, @@ -2575,7 +2575,7 @@ static device_config_t s3_phoenix_trio64_config[] = } }; -device_t s3_bahamas64_vlb_device = +const device_t s3_bahamas64_vlb_device = { "Paradise Bahamas 64 (S3 Vision864) VLB", DEVICE_VLB, @@ -2590,7 +2590,7 @@ device_t s3_bahamas64_vlb_device = s3_bahamas64_config }; -device_t s3_bahamas64_pci_device = +const device_t s3_bahamas64_pci_device = { "Paradise Bahamas 64 (S3 Vision864) PCI", DEVICE_PCI, @@ -2605,7 +2605,7 @@ device_t s3_bahamas64_pci_device = s3_bahamas64_config }; -device_t s3_9fx_vlb_device = +const device_t s3_9fx_vlb_device = { "Number 9 9FX (S3 Trio64) VLB", DEVICE_VLB, @@ -2620,7 +2620,7 @@ device_t s3_9fx_vlb_device = s3_9fx_config }; -device_t s3_9fx_pci_device = +const device_t s3_9fx_pci_device = { "Number 9 9FX (S3 Trio64) PCI", DEVICE_PCI, @@ -2635,7 +2635,7 @@ device_t s3_9fx_pci_device = s3_9fx_config }; -device_t s3_phoenix_trio32_vlb_device = +const device_t s3_phoenix_trio32_vlb_device = { "Phoenix S3 Trio32 VLB", DEVICE_VLB, @@ -2650,7 +2650,7 @@ device_t s3_phoenix_trio32_vlb_device = s3_phoenix_trio32_config }; -device_t s3_phoenix_trio32_pci_device = +const device_t s3_phoenix_trio32_pci_device = { "Phoenix S3 Trio32 PCI", DEVICE_PCI, @@ -2665,7 +2665,7 @@ device_t s3_phoenix_trio32_pci_device = s3_phoenix_trio32_config }; -device_t s3_phoenix_trio64_vlb_device = +const device_t s3_phoenix_trio64_vlb_device = { "Phoenix S3 Trio64 VLB", DEVICE_VLB, @@ -2680,7 +2680,7 @@ device_t s3_phoenix_trio64_vlb_device = s3_phoenix_trio64_config }; -device_t s3_phoenix_trio64_onboard_pci_device = +const device_t s3_phoenix_trio64_onboard_pci_device = { "Phoenix S3 Trio64 On-Board PCI", DEVICE_PCI, @@ -2695,7 +2695,7 @@ device_t s3_phoenix_trio64_onboard_pci_device = s3_phoenix_trio64_onboard_config }; -device_t s3_phoenix_trio64_pci_device = +const device_t s3_phoenix_trio64_pci_device = { "Phoenix S3 Trio64 PCI", DEVICE_PCI, @@ -2710,7 +2710,7 @@ device_t s3_phoenix_trio64_pci_device = s3_phoenix_trio64_config }; -device_t s3_phoenix_vision864_vlb_device = +const device_t s3_phoenix_vision864_vlb_device = { "Phoenix S3 Vision864 VLB", DEVICE_VLB, @@ -2725,7 +2725,7 @@ device_t s3_phoenix_vision864_vlb_device = s3_bahamas64_config }; -device_t s3_phoenix_vision864_pci_device = +const device_t s3_phoenix_vision864_pci_device = { "Phoenix S3 Vision864 PCI", DEVICE_PCI, @@ -2740,7 +2740,7 @@ device_t s3_phoenix_vision864_pci_device = s3_bahamas64_config }; -device_t s3_diamond_stealth64_vlb_device = +const device_t s3_diamond_stealth64_vlb_device = { "S3 Trio64 (Diamond Stealth64 DRAM) VLB", DEVICE_PCI, @@ -2755,7 +2755,7 @@ device_t s3_diamond_stealth64_vlb_device = s3_phoenix_trio64_config }; -device_t s3_diamond_stealth64_pci_device = +const device_t s3_diamond_stealth64_pci_device = { "S3 Trio64 (Diamond Stealth64 DRAM) PCI", DEVICE_PCI, diff --git a/src/video/vid_s3.h b/src/video/vid_s3.h index 9238338..329b24b 100644 --- a/src/video/vid_s3.h +++ b/src/video/vid_s3.h @@ -9,7 +9,7 @@ * Emulation of the S3 Trio32, S3 Trio64, and S3 Vision864 * graphics cards. * - * Version: @(#)vid_s3.h 1.0.1 2018/02/14 + * Version: @(#)vid_s3.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -41,21 +41,21 @@ # define VIDEO_S3_H -device_t s3_bahamas64_vlb_device; -device_t s3_bahamas64_pci_device; -device_t s3_9fx_vlb_device; -device_t s3_9fx_pci_device; -device_t s3_phoenix_trio32_vlb_device; -device_t s3_phoenix_trio32_pci_device; -device_t s3_phoenix_trio64_vlb_device; -device_t s3_phoenix_trio64_onboard_pci_device; -device_t s3_phoenix_trio64_pci_device; -device_t s3_phoenix_vision864_pci_device; -device_t s3_phoenix_vision864_vlb_device; -device_t s3_diamond_stealth64_pci_device; -device_t s3_diamond_stealth64_vlb_device; +extern const device_t s3_bahamas64_vlb_device; +extern const device_t s3_bahamas64_pci_device; +extern const device_t s3_9fx_vlb_device; +extern const device_t s3_9fx_pci_device; +extern const device_t s3_phoenix_trio32_vlb_device; +extern const device_t s3_phoenix_trio32_pci_device; +extern const device_t s3_phoenix_trio64_vlb_device; +extern const device_t s3_phoenix_trio64_onboard_pci_device; +extern const device_t s3_phoenix_trio64_pci_device; +extern const device_t s3_phoenix_vision864_pci_device; +extern const device_t s3_phoenix_vision864_vlb_device; +extern const device_t s3_diamond_stealth64_pci_device; +extern const device_t s3_diamond_stealth64_vlb_device; #if 0 -device_t s3_miro_vision964_device; +extern const device_t s3_miro_vision964_device; #endif diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index d7a66b0..481ce4a 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -8,7 +8,7 @@ * * S3 ViRGE emulation. * - * Version: @(#)vid_s3_virge.c 1.0.3 2018/03/08 + * Version: @(#)vid_s3_virge.c 1.0.5 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -477,7 +477,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) case 2: case 3: svga->bpp = 15; break; case 4: case 5: svga->bpp = 16; break; case 7: svga->bpp = 24; break; - case 13: svga->bpp = ((gfxcard == GFX_VIRGEVX_VLB) || (gfxcard == GFX_VIRGEVX_PCI)) ? 24 : 32; break; + case 13: svga->bpp = ((vid_card == VID_VIRGEVX_VLB) || (vid_card == VID_VIRGEVX_PCI)) ? 24 : 32; break; default: svga->bpp = 8; break; } break; @@ -592,7 +592,7 @@ static void s3_virge_recalctimings(svga_t *svga) } } - if ((gfxcard != GFX_VIRGEVX_VLB) && (gfxcard != GFX_VIRGEVX_PCI)) + if ((vid_card != VID_VIRGEVX_VLB) && (vid_card != VID_VIRGEVX_PCI)) { if ((svga->bpp == 15) || (svga->bpp == 16)) { @@ -656,7 +656,7 @@ static void s3_virge_recalctimings(svga_t *svga) if (((svga->miscout >> 2) & 3) == 3) { int n = svga->seqregs[0x12] & 0x1f; - int r = (svga->seqregs[0x12] >> 5) & ((virge->is_375 || ((gfxcard == GFX_VIRGEVX_VLB) || (gfxcard == GFX_VIRGEVX_PCI))) ? 7 : 3); + int r = (svga->seqregs[0x12] >> 5) & ((virge->is_375 || ((vid_card == VID_VIRGEVX_VLB) || (vid_card == VID_VIRGEVX_PCI))) ? 7 : 3); int m = svga->seqregs[0x13] & 0x7f; double freq = (((double)m + 2) / (((double)n + 2) * (double)(1 << r))) * 14318184.0; @@ -3793,7 +3793,7 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) } } -static void *s3_virge_init(device_t *info) +static void *s3_virge_init(const device_t *info) { virge_t *virge = malloc(sizeof(virge_t)); memset(virge, 0, sizeof(virge_t)); @@ -3893,7 +3893,7 @@ static void *s3_virge_init(device_t *info) return virge; } -static void *s3_virge_988_init(device_t *info) +static void *s3_virge_988_init(const device_t *info) { virge_t *virge = malloc(sizeof(virge_t)); memset(virge, 0, sizeof(virge_t)); @@ -3992,7 +3992,7 @@ static void *s3_virge_988_init(device_t *info) return virge; } -static void *s3_virge_375_init(device_t *info, wchar_t *romfn) +static void *s3_virge_375_init(const device_t *info, wchar_t *romfn) { virge_t *virge = malloc(sizeof(virge_t)); memset(virge, 0, sizeof(virge_t)); @@ -4092,12 +4092,12 @@ static void *s3_virge_375_init(device_t *info, wchar_t *romfn) return virge; } -static void *s3_virge_375_1_init(device_t *info) +static void *s3_virge_375_1_init(const device_t *info) { return s3_virge_375_init(info, L"roms/video/s3/s3virge/86c375_1.bin"); } -static void *s3_virge_375_4_init(device_t *info) +static void *s3_virge_375_4_init(const device_t *info) { return s3_virge_375_init(info, L"roms/video/s3/s3virge/86c375_4.bin"); } @@ -4180,7 +4180,7 @@ static void s3_virge_add_status_info(char *s, int max_len, void *p) reg_writes = 0; } -static device_config_t s3_virge_config[] = +static const device_config_t s3_virge_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 4, @@ -4207,7 +4207,7 @@ static device_config_t s3_virge_config[] = } }; -device_t s3_virge_vlb_device = +const device_t s3_virge_vlb_device = { "Diamond Stealth 3D 2000 (S3 ViRGE) VLB", DEVICE_VLB, @@ -4222,7 +4222,7 @@ device_t s3_virge_vlb_device = s3_virge_config }; -device_t s3_virge_pci_device = +const device_t s3_virge_pci_device = { "Diamond Stealth 3D 2000 (S3 ViRGE) PCI", DEVICE_PCI, @@ -4237,7 +4237,7 @@ device_t s3_virge_pci_device = s3_virge_config }; -device_t s3_virge_988_vlb_device = +const device_t s3_virge_988_vlb_device = { "Diamond Stealth 3D 3000 (S3 ViRGE/VX) VLB", DEVICE_VLB, @@ -4252,7 +4252,7 @@ device_t s3_virge_988_vlb_device = s3_virge_config }; -device_t s3_virge_988_pci_device = +const device_t s3_virge_988_pci_device = { "Diamond Stealth 3D 3000 (S3 ViRGE/VX) PCI", DEVICE_PCI, @@ -4267,7 +4267,7 @@ device_t s3_virge_988_pci_device = s3_virge_config }; -device_t s3_virge_375_vlb_device = +const device_t s3_virge_375_vlb_device = { "S3 ViRGE/DX VLB", DEVICE_VLB, @@ -4282,7 +4282,7 @@ device_t s3_virge_375_vlb_device = s3_virge_config }; -device_t s3_virge_375_pci_device = +const device_t s3_virge_375_pci_device = { "S3 ViRGE/DX PCI", DEVICE_PCI, @@ -4297,7 +4297,7 @@ device_t s3_virge_375_pci_device = s3_virge_config }; -device_t s3_virge_375_4_vlb_device = +const device_t s3_virge_375_4_vlb_device = { "S3 ViRGE/DX (VBE 2.0) VLB", DEVICE_VLB, @@ -4312,7 +4312,7 @@ device_t s3_virge_375_4_vlb_device = s3_virge_config }; -device_t s3_virge_375_4_pci_device = +const device_t s3_virge_375_4_pci_device = { "S3 ViRGE/DX (VBE 2.0) PCI", DEVICE_PCI, diff --git a/src/video/vid_s3_virge.h b/src/video/vid_s3_virge.h index 6b74753..d8554bc 100644 --- a/src/video/vid_s3_virge.h +++ b/src/video/vid_s3_virge.h @@ -8,7 +8,7 @@ * * Definitions for the S3 Virge driver. * - * Version: @(#)vid_s3_virge.h 1.0.1 2018/02/14 + * Version: @(#)vid_s3_virge.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,14 +40,14 @@ # define VIDEO_S3_VIRGE_H -extern device_t s3_virge_vlb_device; -extern device_t s3_virge_pci_device; -extern device_t s3_virge_988_vlb_device; -extern device_t s3_virge_988_pci_device; -extern device_t s3_virge_375_vlb_device; -extern device_t s3_virge_375_pci_device; -extern device_t s3_virge_375_4_vlb_device; -extern device_t s3_virge_375_4_pci_device; +extern const device_t s3_virge_vlb_device; +extern const device_t s3_virge_pci_device; +extern const device_t s3_virge_988_vlb_device; +extern const device_t s3_virge_988_pci_device; +extern const device_t s3_virge_375_vlb_device; +extern const device_t s3_virge_375_pci_device; +extern const device_t s3_virge_375_4_vlb_device; +extern const device_t s3_virge_375_4_pci_device; #endif /*VIDEO_S3_VIRGE_H*/ diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 6cde700..a32e2cd 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -8,7 +8,7 @@ * * Define all known video cards. * - * Version: @(#)vid_table.c 1.0.8 2018/03/12 + * Version: @(#)vid_table.c 1.0.9 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -90,7 +90,7 @@ enum { typedef struct { const char *name; const char *internal_name; - device_t *device; + const device_t *device; int legacy_id; int flags; video_timings_t timing; @@ -99,87 +99,87 @@ typedef struct { static VIDEO_CARD video_cards[] = { - {"None", "none", NULL, GFX_NONE, VIDEO_FLAG_TYPE_SPECIAL, {0, 0, 0, 0, 0, 0, 0}}, - {"Internal", "internal", NULL, GFX_INTERNAL, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_isa", &mach64gx_isa_device, GFX_MACH64GX_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, - {"[ISA] ATI Korean VGA (ATI-28800-5)", "ati28800k", &ati28800k_device, GFX_ATIKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, - {"[ISA] ATI VGA-88 (ATI-18800-1)", "ati18800v", &ati18800_vga88_device, GFX_VGA88, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] ATI VGA Charger (ATI-28800-5)", "ati28800", &ati28800_device, GFX_VGACHARGER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, - {"[ISA] ATI VGA Edge-16 (ATI-18800-5)", "ati18800", &ati18800_device, GFX_VGAEDGE16, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] ATI VGA Wonder (ATI-18800)", "ati18800w", &ati18800_wonder_device, GFX_VGAWONDER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"None", "none", NULL, VID_NONE, VIDEO_FLAG_TYPE_SPECIAL, {0, 0, 0, 0, 0, 0, 0}}, + {"Internal", "internal", NULL, VID_INTERNAL, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_isa", &mach64gx_isa_device, VID_MACH64GX_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, + {"[ISA] ATI Korean VGA (ATI-28800-5)", "ati28800k", &ati28800k_device, VID_ATIKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, + {"[ISA] ATI VGA-88 (ATI-18800-1)", "ati18800v", &ati18800_vga88_device, VID_VGA88, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] ATI VGA Charger (ATI-28800-5)", "ati28800", &ati28800_device, VID_VGACHARGER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, + {"[ISA] ATI VGA Edge-16 (ATI-18800-5)", "ati18800", &ati18800_device, VID_VGAEDGE16, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] ATI VGA Wonder (ATI-18800)", "ati18800w", &ati18800_wonder_device, VID_VGAWONDER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, #if defined(DEV_BRANCH) && defined(USE_XL24) - {"[ISA] ATI VGA Wonder XL24 (ATI-28800-6)", "ati28800w", &ati28800_wonderxl24_device, GFX_VGAWONDERXL24, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, + {"[ISA] ATI VGA Wonder XL24 (ATI-28800-6)", "ati28800w", &ati28800_wonderxl24_device, VID_VGAWONDERXL24, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, #endif - {"[ISA] CGA", "cga", &cga_device, GFX_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] Chips & Technologies SuperEGA", "superega", &sega_device, GFX_SUPER_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] Cirrus Logic GD5428", "cl_gd5428_isa", &gd5428_isa_device, GFX_CL_GD5428_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, - {"[ISA] Cirrus Logic GD5429", "cl_gd5429_isa", &gd5429_isa_device, GFX_CL_GD5429_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, - {"[ISA] Cirrus Logic GD5434", "cl_gd5434_isa", &gd5434_isa_device, GFX_CL_GD5434_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, - {"[ISA] Compaq ATI VGA Wonder XL (ATI-28800-5)", "compaq_ati28800", &compaq_ati28800_device, GFX_VGAWONDERXL, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, - {"[ISA] Compaq CGA", "compaq_cga", &compaq_cga_device, GFX_COMPAQ_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] Compaq CGA 2", "compaq_cga_2", &compaq_cga_2_device, GFX_COMPAQ_CGA_2, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] Compaq EGA", "compaq_ega", &cpqega_device, GFX_COMPAQ_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] EGA", "ega", &ega_device, GFX_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] Hercules", "hercules", &hercules_device, GFX_HERCULES, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] Hercules Plus", "hercules_plus", &herculesplus_device, GFX_HERCULESPLUS, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] MDA", "mda", &mda_device, GFX_MDA, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] MDSI Genius", "genius", &genius_device, GFX_GENIUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] OAK OTI-037C", "oti037c", &oti037c_device, GFX_OTI037C, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, - {"[ISA] OAK OTI-067", "oti067", &oti067_device, GFX_OTI067, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, - {"[ISA] OAK OTI-077", "oti077", &oti077_device, GFX_OTI077, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, - {"[ISA] Paradise PVGA1A", "pvga1a", ¶dise_pvga1a_device, GFX_PVGA1A, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] Paradise WD90C11-LR", "wd90c11", ¶dise_wd90c11_device, GFX_WD90C11, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] Paradise WD90C30-LR", "wd90c30", ¶dise_wd90c30_device, GFX_WD90C30, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, - {"[ISA] Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] CGA", "cga", &cga_device, VID_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] Chips & Technologies SuperEGA", "superega", &sega_device, VID_SUPER_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] Cirrus Logic GD5428", "cl_gd5428_isa", &gd5428_isa_device, VID_CL_GD5428_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, + {"[ISA] Cirrus Logic GD5429", "cl_gd5429_isa", &gd5429_isa_device, VID_CL_GD5429_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, + {"[ISA] Cirrus Logic GD5434", "cl_gd5434_isa", &gd5434_isa_device, VID_CL_GD5434_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, + {"[ISA] Compaq ATI VGA Wonder XL (ATI-28800-5)", "compaq_ati28800", &compaq_ati28800_device, VID_VGAWONDERXL, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, + {"[ISA] Compaq CGA", "compaq_cga", &compaq_cga_device, VID_COMPAQ_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] Compaq CGA 2", "compaq_cga_2", &compaq_cga_2_device, VID_COMPAQ_CGA_2, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] Compaq EGA", "compaq_ega", &cpqega_device, VID_COMPAQ_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] EGA", "ega", &ega_device, VID_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] Hercules", "hercules", &hercules_device, VID_HERCULES, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] Hercules Plus", "hercules_plus", &herculesplus_device, VID_HERCULESPLUS, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] Hercules InColor", "incolor", &incolor_device, VID_INCOLOR, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] MDA", "mda", &mda_device, VID_MDA, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] MDSI Genius", "genius", &genius_device, VID_GENIUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] OAK OTI-037C", "oti037c", &oti037c_device, VID_OTI037C, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, + {"[ISA] OAK OTI-067", "oti067", &oti067_device, VID_OTI067, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, + {"[ISA] OAK OTI-077", "oti077", &oti077_device, VID_OTI077, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, + {"[ISA] Paradise PVGA1A", "pvga1a", ¶dise_pvga1a_device, VID_PVGA1A, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] Paradise WD90C11-LR", "wd90c11", ¶dise_wd90c11_device, VID_WD90C11, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] Paradise WD90C30-LR", "wd90c30", ¶dise_wd90c30_device, VID_WD90C30, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, + {"[ISA] Plantronics ColorPlus", "plantronics", &colorplus_device, VID_COLORPLUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, #if defined(DEV_BRANCH) && defined(USE_TI) - {"[ISA] TI CF62011 SVGA", "ti_cf62011", &ti_cf62011_device, GFX_TICF62011, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] TI CF62011 SVGA", "ti_cf62011", &ti_cf62011_device, VID_TICF62011, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, #endif - {"[ISA] Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, - {"[ISA] Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, - {"[ISA] VGA", "vga", &vga_device, GFX_VGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[ISA] Wyse 700", "wy700", &wy700_device, GFX_WY700, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[PCI] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_pci", &mach64gx_pci_device, GFX_MACH64GX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, - {"[PCI] ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, - {"[PCI] Cardex Tseng ET4000/w32p", "et4000w32p_pci", &et4000w32p_cardex_pci_device, GFX_ET4000W32_CARDEX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, - {"[PCI] Cirrus Logic GD5430", "cl_gd5430_pci", &gd5430_pci_device, GFX_CL_GD5430_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"[PCI] Cirrus Logic GD5434", "cl_gd5434_pci", &gd5434_pci_device, GFX_CL_GD5434_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"[PCI] Cirrus Logic GD5436", "cl_gd5436_pci", &gd5436_pci_device, GFX_CL_GD5436_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"[ISA] Trident TVGA8900D", "tvga8900d", &tvga8900d_device, VID_TVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, + {"[ISA] Tseng ET4000AX", "et4000ax", &et4000_device, VID_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, + {"[ISA] VGA", "vga", &vga_device, VID_VGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[ISA] Wyse 700", "wy700", &wy700_device, VID_WY700, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"[PCI] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_pci", &mach64gx_pci_device, VID_MACH64GX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, + {"[PCI] ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, VID_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, + {"[PCI] Cardex Tseng ET4000/w32p", "et4000w32p_pci", &et4000w32p_cardex_pci_device, VID_ET4000W32_CARDEX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, + {"[PCI] Cirrus Logic GD5430", "cl_gd5430_pci", &gd5430_pci_device, VID_CL_GD5430_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"[PCI] Cirrus Logic GD5434", "cl_gd5434_pci", &gd5434_pci_device, VID_CL_GD5434_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"[PCI] Cirrus Logic GD5436", "cl_gd5436_pci", &gd5436_pci_device, VID_CL_GD5436_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, #if defined(DEV_BRANCH) && defined(USE_STEALTH32) - {"[PCI] Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32_pci", &et4000w32p_pci_device, GFX_ET4000W32_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, + {"[PCI] Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32_pci", &et4000w32p_pci_device, VID_ET4000W32_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, #endif - {"[PCI] Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000_pci", &s3_virge_pci_device, GFX_VIRGE_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, - {"[PCI] Diamond Stealth 3D 3000 (S3 ViRGE/VX)", "stealth3d_3000_pci", &s3_virge_988_pci_device, GFX_VIRGEVX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}}, - {"[PCI] Diamond Stealth 64 DRAM (S3 Trio64)", "stealth64d_pci", &s3_diamond_stealth64_pci_device, GFX_STEALTH64_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}}, - {"[PCI] Number Nine 9FX (S3 Trio64)", "n9_9fx_pci", &s3_9fx_pci_device, GFX_N9_9FX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, - {"[PCI] Paradise Bahamas 64 (S3 Vision864)", "bahamas64_pci", &s3_bahamas64_pci_device, GFX_BAHAMAS64_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, - {"[PCI] Phoenix S3 Vision864", "px_vision864_pci", &s3_phoenix_vision864_pci_device, GFX_PHOENIX_VISION864_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, - {"[PCI] Phoenix S3 Trio32", "px_trio32_pci", &s3_phoenix_trio32_pci_device, GFX_PHOENIX_TRIO32_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, - {"[PCI] Phoenix S3 Trio64", "px_trio64_pci", &s3_phoenix_trio64_pci_device, GFX_PHOENIX_TRIO64_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, - {"[PCI] S3 ViRGE/DX", "virge375_pci", &s3_virge_375_pci_device, GFX_VIRGEDX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, - {"[PCI] S3 ViRGE/DX (VBE 2.0)", "virge375_vbe20_pci", &s3_virge_375_4_pci_device, GFX_VIRGEDX4_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, - {"[PCI] Trident TGUI9440", "tgui9440_pci", &tgui9440_pci_device, GFX_TGUI9440_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, - {"[VLB] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_vlb", &mach64gx_vlb_device, GFX_MACH64GX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, - {"[VLB] Cardex Tseng ET4000/w32p", "et4000w32p_vlb", &et4000w32p_cardex_vlb_device, GFX_ET4000W32_CARDEX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, - {"[VLB] Cirrus Logic GD5429", "cl_gd5429_vlb", &gd5429_vlb_device, GFX_CL_GD5429_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"[VLB] Cirrus Logic GD5434", "cl_gd5434_vlb", &gd5434_vlb_device, GFX_CL_GD5434_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"[VLB] Diamond SpeedStar PRO (CL GD5428)", "cl_gd5428_vlb", &gd5428_vlb_device, GFX_CL_GD5428_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"[VLB] Diamond SpeedStar PRO SE (CL GD5430)", "cl_gd5430_vlb", &gd5430_vlb_device, GFX_CL_GD5430_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"[PCI] Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000_pci", &s3_virge_pci_device, VID_VIRGE_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, + {"[PCI] Diamond Stealth 3D 3000 (S3 ViRGE/VX)", "stealth3d_3000_pci", &s3_virge_988_pci_device, VID_VIRGEVX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}}, + {"[PCI] Diamond Stealth 64 DRAM (S3 Trio64)", "stealth64d_pci", &s3_diamond_stealth64_pci_device, VID_STEALTH64_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}}, + {"[PCI] Number Nine 9FX (S3 Trio64)", "n9_9fx_pci", &s3_9fx_pci_device, VID_N9_9FX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, + {"[PCI] Paradise Bahamas 64 (S3 Vision864)", "bahamas64_pci", &s3_bahamas64_pci_device, VID_BAHAMAS64_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, + {"[PCI] Phoenix S3 Vision864", "px_vision864_pci", &s3_phoenix_vision864_pci_device, VID_PHOENIX_VISION864_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, + {"[PCI] Phoenix S3 Trio32", "px_trio32_pci", &s3_phoenix_trio32_pci_device, VID_PHOENIX_TRIO32_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, + {"[PCI] Phoenix S3 Trio64", "px_trio64_pci", &s3_phoenix_trio64_pci_device, VID_PHOENIX_TRIO64_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, + {"[PCI] S3 ViRGE/DX", "virge375_pci", &s3_virge_375_pci_device, VID_VIRGEDX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, + {"[PCI] S3 ViRGE/DX (VBE 2.0)", "virge375_vbe20_pci", &s3_virge_375_4_pci_device, VID_VIRGEDX4_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, + {"[PCI] Trident TGUI9440", "tgui9440_pci", &tgui9440_pci_device, VID_TGUI9440_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, + {"[VLB] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_vlb", &mach64gx_vlb_device, VID_MACH64GX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, + {"[VLB] Cardex Tseng ET4000/w32p", "et4000w32p_vlb", &et4000w32p_cardex_vlb_device, VID_ET4000W32_CARDEX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, + {"[VLB] Cirrus Logic GD5429", "cl_gd5429_vlb", &gd5429_vlb_device, VID_CL_GD5429_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"[VLB] Cirrus Logic GD5434", "cl_gd5434_vlb", &gd5434_vlb_device, VID_CL_GD5434_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"[VLB] Diamond SpeedStar PRO (CL GD5428)", "cl_gd5428_vlb", &gd5428_vlb_device, VID_CL_GD5428_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"[VLB] Diamond SpeedStar PRO SE (CL GD5430)", "cl_gd5430_vlb", &gd5430_vlb_device, VID_CL_GD5430_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, #if defined(DEV_BRANCH) && defined(USE_STEALTH32) - {"[VLB] Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32_vlb", &et4000w32p_vlb_device, GFX_ET4000W32_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, + {"[VLB] Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32_vlb", &et4000w32p_vlb_device, VID_ET4000W32_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, #endif - {"[VLB] Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000_vlb", &s3_virge_vlb_device, GFX_VIRGE_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, - {"[VLB] Diamond Stealth 3D 3000 (S3 ViRGE/VX)", "stealth3d_3000_vlb", &s3_virge_988_vlb_device, GFX_VIRGEVX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}}, - {"[VLB] Diamond Stealth 64 DRAM (S3 Trio64)", "stealth64d_vlb", &s3_diamond_stealth64_vlb_device, GFX_STEALTH64_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}}, - {"[VLB] Number Nine 9FX (S3 Trio64)", "n9_9fx_vlb", &s3_9fx_vlb_device, GFX_N9_9FX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, - {"[VLB] Paradise Bahamas 64 (S3 Vision864)", "bahamas64_vlb", &s3_bahamas64_vlb_device, GFX_BAHAMAS64_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, - {"[VLB] Phoenix S3 Vision864", "px_vision864_vlb", &s3_phoenix_vision864_vlb_device, GFX_PHOENIX_VISION864_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, - {"[VLB] Phoenix S3 Trio32", "px_trio32_vlb", &s3_phoenix_trio32_vlb_device, GFX_PHOENIX_TRIO32_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, - {"[VLB] Phoenix S3 Trio64", "px_trio64_vlb", &s3_phoenix_trio64_vlb_device, GFX_PHOENIX_TRIO64_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, - {"[VLB] S3 ViRGE/DX", "virge375_vlb", &s3_virge_375_vlb_device, GFX_VIRGEDX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, - {"[VLB] S3 ViRGE/DX (VBE 2.0)", "virge375_vbe20_vlb", &s3_virge_375_4_vlb_device, GFX_VIRGEDX4_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, - {"[VLB] Trident TGUI9400CXi", "tgui9400cxi_vlb", &tgui9400cxi_device, GFX_TGUI9400CXI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, - {"[VLB] Trident TGUI9440", "tgui9440_vlb", &tgui9440_vlb_device, GFX_TGUI9440_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, + {"[VLB] Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000_vlb", &s3_virge_vlb_device, VID_VIRGE_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, + {"[VLB] Diamond Stealth 3D 3000 (S3 ViRGE/VX)", "stealth3d_3000_vlb", &s3_virge_988_vlb_device, VID_VIRGEVX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}}, + {"[VLB] Diamond Stealth 64 DRAM (S3 Trio64)", "stealth64d_vlb", &s3_diamond_stealth64_vlb_device, VID_STEALTH64_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 4, 26, 26, 42}}, + {"[VLB] Number Nine 9FX (S3 Trio64)", "n9_9fx_vlb", &s3_9fx_vlb_device, VID_N9_9FX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, + {"[VLB] Paradise Bahamas 64 (S3 Vision864)", "bahamas64_vlb", &s3_bahamas64_vlb_device, VID_BAHAMAS64_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, + {"[VLB] Phoenix S3 Vision864", "px_vision864_vlb", &s3_phoenix_vision864_vlb_device, VID_PHOENIX_VISION864_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, + {"[VLB] Phoenix S3 Trio32", "px_trio32_vlb", &s3_phoenix_trio32_vlb_device, VID_PHOENIX_TRIO32_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, + {"[VLB] Phoenix S3 Trio64", "px_trio64_vlb", &s3_phoenix_trio64_vlb_device, VID_PHOENIX_TRIO64_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, + {"[VLB] S3 ViRGE/DX", "virge375_vlb", &s3_virge_375_vlb_device, VID_VIRGEDX_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, + {"[VLB] S3 ViRGE/DX (VBE 2.0)", "virge375_vbe20_vlb", &s3_virge_375_4_vlb_device, VID_VIRGEDX4_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, + {"[VLB] Trident TGUI9400CXi", "tgui9400cxi_vlb", &tgui9400cxi_device, VID_TGUI9400CXI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, + {"[VLB] Trident TGUI9440", "tgui9440_vlb", &tgui9440_vlb_device, VID_TGUI9440_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, {"", "", NULL, -1, 0, {0, 0, 0, 0, 0, 0, 0}} }; @@ -191,9 +191,9 @@ video_detect(void) /* Make sure we have a usable video card. */ c = 0; - for (i=0; i * Miran Grca, @@ -792,7 +792,7 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p) } } -static void *tgui_init(device_t *info, wchar_t *bios_fn, int type) +static void *tgui_init(const device_t *info, wchar_t *bios_fn, int type) { tgui_t *tgui = malloc(sizeof(tgui_t)); memset(tgui, 0, sizeof(tgui_t)); @@ -830,12 +830,12 @@ static void *tgui_init(device_t *info, wchar_t *bios_fn, int type) return tgui; } -static void *tgui9400cxi_init(device_t *info) +static void *tgui9400cxi_init(const device_t *info) { return tgui_init(info, L"roms/video/trident/tgui9440/9400cxi.vbi", TGUI_9400CXI); } -static void *tgui9440_init(device_t *info) +static void *tgui9440_init(const device_t *info) { return tgui_init(info, L"roms/video/trident/tgui9440/9440.vbi", TGUI_9440); } @@ -1766,7 +1766,7 @@ void tgui_add_status_info(char *s, int max_len, void *p) tgui->blitter_time = 0; } -static device_config_t tgui9440_config[] = +static const device_config_t tgui9440_config[] = { { .name = "memory", @@ -1793,7 +1793,7 @@ static device_config_t tgui9440_config[] = } }; -device_t tgui9400cxi_device = +const device_t tgui9400cxi_device = { "Trident TGUI 9400CXi", DEVICE_VLB, @@ -1808,7 +1808,7 @@ device_t tgui9400cxi_device = tgui9440_config }; -device_t tgui9440_vlb_device = +const device_t tgui9440_vlb_device = { "Trident TGUI 9440 VLB", DEVICE_VLB, @@ -1823,7 +1823,7 @@ device_t tgui9440_vlb_device = tgui9440_config }; -device_t tgui9440_pci_device = +const device_t tgui9440_pci_device = { "Trident TGUI 9440 PCI", DEVICE_PCI, diff --git a/src/video/vid_tgui9440.h b/src/video/vid_tgui9440.h index 8a0375c..ddb4223 100644 --- a/src/video/vid_tgui9440.h +++ b/src/video/vid_tgui9440.h @@ -8,7 +8,7 @@ * * Definitions for the TGUI9440 driver. * - * Version: @(#)vid_tgui9440.h 1.0.1 2018/02/14 + * Version: @(#)vid_tgui9440.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,9 +40,9 @@ # define VIDEO_TGUI9440_H -extern device_t tgui9400cxi_device; -extern device_t tgui9440_vlb_device; -extern device_t tgui9440_pci_device; +extern const device_t tgui9400cxi_device; +extern const device_t tgui9440_vlb_device; +extern const device_t tgui9440_pci_device; #endif /*VIDEO_TGUI9440_H*/ diff --git a/src/video/vid_ti_cf62011.c b/src/video/vid_ti_cf62011.c index 380f0df..a294068 100644 --- a/src/video/vid_ti_cf62011.c +++ b/src/video/vid_ti_cf62011.c @@ -42,7 +42,7 @@ * which are the same as the XGA. It supports up to 1MB of VRAM, * but we lock it down to 512K. The PS/1 2122 had 256K. * - * Version: @(#)vid_ti_cf62011.c 1.0.1 2018/02/14 + * Version: @(#)vid_ti_cf62011.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -257,7 +257,7 @@ vid_close(void *priv) static void * -vid_init(device_t *info) +vid_init(const device_t *info) { tivga_t *ti; @@ -289,7 +289,7 @@ vid_init(device_t *info) #if defined(DEV_BRANCH) && defined(USE_TI) -static device_config_t vid_config[] = +static const device_config_t vid_config[] = { { "vram_size", "Memory Size", CONFIG_SELECTION, "", 256, @@ -314,7 +314,7 @@ static device_config_t vid_config[] = }; -device_t ti_cf62011_device = { +const device_t ti_cf62011_device = { "TI CF62011 SVGA", 0, 0, @@ -328,7 +328,7 @@ device_t ti_cf62011_device = { #endif -device_t ibm_ps1_2121_device = { +const device_t ibm_ps1_2121_device = { "IBM PS/1 Model 2121 SVGA", 0, 512, diff --git a/src/video/vid_ti_cf62011.h b/src/video/vid_ti_cf62011.h index 46e006f..00081e5 100644 --- a/src/video/vid_ti_cf62011.h +++ b/src/video/vid_ti_cf62011.h @@ -8,7 +8,7 @@ * * Definitions for the CF62011 driver. * - * Version: @(#)vid_ti_cf62011.h 1.0.1 2018/02/14 + * Version: @(#)vid_ti_cf62011.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -41,9 +41,9 @@ #if defined(DEV_BRANCH) && defined(USE_TI) -extern device_t ti_cf62011_device; +extern const device_t ti_cf62011_device; #endif -extern device_t ibm_ps1_2121_device; +extern const device_t ibm_ps1_2121_device; #endif /*VIDEO_TI_CF62011_H*/ diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index af8439f..40c49f3 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -8,7 +8,7 @@ * * Trident TVGA (8900D) emulation. * - * Version: @(#)vid_tvga.c 1.0.3 2018/03/04 + * Version: @(#)vid_tvga.c 1.0.4 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -313,7 +313,7 @@ void tvga_recalctimings(svga_t *svga) } -static void *tvga8900d_init(device_t *info) +static void *tvga8900d_init(const device_t *info) { tvga_t *tvga = malloc(sizeof(tvga_t)); memset(tvga, 0, sizeof(tvga_t)); @@ -369,7 +369,7 @@ void tvga_add_status_info(char *s, int max_len, void *p) svga_add_status_info(s, max_len, &tvga->svga); } -static device_config_t tvga_config[] = +static const device_config_t tvga_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 1024, @@ -394,7 +394,7 @@ static device_config_t tvga_config[] = } }; -device_t tvga8900d_device = +const device_t tvga8900d_device = { "Trident TVGA 8900D", DEVICE_ISA, diff --git a/src/video/vid_tvga.h b/src/video/vid_tvga.h index 40d10a3..012f3b2 100644 --- a/src/video/vid_tvga.h +++ b/src/video/vid_tvga.h @@ -8,7 +8,7 @@ * * Definitions for the TVGA driver. * - * Version: @(#)vid_tvga.h 1.0.1 2018/02/14 + * Version: @(#)vid_tvga.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define VIDEO_TVGA_H -extern device_t tvga8900d_device; +extern const device_t tvga8900d_device; #endif /*VIDEO_TVGA_H*/ diff --git a/src/video/vid_vga.c b/src/video/vid_vga.c index 7f4db05..c916c23 100644 --- a/src/video/vid_vga.c +++ b/src/video/vid_vga.c @@ -8,7 +8,7 @@ * * IBM VGA emulation. * - * Version: @(#)vid_vga.c 1.0.2 2018/02/22 + * Version: @(#)vid_vga.c 1.0.3 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -117,7 +117,7 @@ uint8_t vga_in(uint16_t addr, void *p) } -static void *vga_init(device_t *info) +static void *vga_init(const device_t *info) { vga_t *vga = malloc(sizeof(vga_t)); memset(vga, 0, sizeof(vga_t)); @@ -140,7 +140,7 @@ static void *vga_init(device_t *info) #ifdef DEV_BRANCH -static void *trigem_unk_init(device_t *info) +static void *trigem_unk_init(const device_t *info) { vga_t *vga = malloc(sizeof(vga_t)); memset(vga, 0, sizeof(vga_t)); @@ -167,7 +167,7 @@ static void *trigem_unk_init(device_t *info) #endif /*PS/1 uses a standard VGA controller, but with no option ROM*/ -void *ps1vga_init(device_t *info) +void *ps1vga_init(const device_t *info) { vga_t *vga = malloc(sizeof(vga_t)); memset(vga, 0, sizeof(vga_t)); @@ -221,7 +221,7 @@ void vga_add_status_info(char *s, int max_len, void *p) svga_add_status_info(s, max_len, &vga->svga); } -device_t vga_device = +const device_t vga_device = { "VGA", DEVICE_ISA, @@ -235,7 +235,7 @@ device_t vga_device = vga_add_status_info }; #ifdef DEV_BRANCH -device_t trigem_unk_device = +const device_t trigem_unk_device = { "VGA", DEVICE_ISA, @@ -249,7 +249,7 @@ device_t trigem_unk_device = vga_add_status_info }; #endif -device_t ps1vga_device = +const device_t ps1vga_device = { "PS/1 VGA", 0, diff --git a/src/video/vid_vga.h b/src/video/vid_vga.h index d7d1170..c1bec92 100644 --- a/src/video/vid_vga.h +++ b/src/video/vid_vga.h @@ -8,7 +8,7 @@ * * Definitions for the VGA driver. * - * Version: @(#)vid_vga.h 1.0.1 2018/02/14 + * Version: @(#)vid_vga.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,9 +40,9 @@ # define VIDEO_VGA_H -extern device_t vga_device; -extern device_t trigem_unk_device; -extern device_t ps1vga_device; +extern const device_t vga_device; +extern const device_t trigem_unk_device; +extern const device_t ps1vga_device; #endif /*VIDEO_VGA_H*/ diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 3afa243..c037ca1 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -8,7 +8,7 @@ * * Emulation of the 3DFX Voodoo Graphics controller. * - * Version: @(#)vid_voodoo.c 1.0.3 2018/02/26 + * Version: @(#)vid_voodoo.c 1.0.5 2018/03/17 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -91,7 +91,7 @@ enum VOODOO_2 = 2 }; -static uint32_t texture_offset[LOD_MAX+3] = +static const uint32_t texture_offset[LOD_MAX+3] = { 0, 256*256, @@ -167,7 +167,16 @@ typedef struct uint32_t val; } fifo_entry_t; -static rgba8_t rgb332[0x100], ai44[0x100], rgb565[0x10000], argb1555[0x10000], argb4444[0x10000], ai88[0x10000]; +/* + * To conserve space in the .bss segment, these + * are allocated on the heap at card activation. + */ +static rgba8_t *rgb332, + *ai44, + *rgb565, + *argb1555, + *argb4444, + *ai88; typedef struct voodoo_params_t { @@ -7778,13 +7787,20 @@ void *voodoo_card_init() return voodoo; } -void *voodoo_init(struct _device_ *dev) +void *voodoo_init(const device_t *info) { voodoo_set_t *voodoo_set = malloc(sizeof(voodoo_set_t)); uint32_t tmuConfig = 1; int type; memset(voodoo_set, 0, sizeof(voodoo_set_t)); + rgb332 = (rgba8_t *)malloc(sizeof(rgba8_t)*0x100); + ai44 = (rgba8_t *)malloc(sizeof(rgba8_t)*0x100); + rgb565 = (rgba8_t *)malloc(sizeof(rgba8_t)*0x10000); + argb1555 = (rgba8_t *)malloc(sizeof(rgba8_t)*0x10000); + argb4444 = (rgba8_t *)malloc(sizeof(rgba8_t)*0x10000); + ai88 = (rgba8_t *)malloc(sizeof(rgba8_t)*0x10000); + type = device_get_config_int("type"); voodoo_set->nr_cards = device_get_config_int("sli") ? 2 : 1; @@ -7891,10 +7907,17 @@ void voodoo_close(void *p) voodoo_card_close(voodoo_set->voodoos[1]); voodoo_card_close(voodoo_set->voodoos[0]); + free(rgb332); + free(ai44); + free(rgb565); + free(argb1555); + free(argb4444); + free(ai88); + free(voodoo_set); } -static device_config_t voodoo_config[] = +static const device_config_t voodoo_config[] = { { .name = "type", @@ -8011,7 +8034,7 @@ static device_config_t voodoo_config[] = } }; -device_t voodoo_device = +const device_t voodoo_device = { "3DFX Voodoo Graphics", DEVICE_PCI, diff --git a/src/video/vid_voodoo.h b/src/video/vid_voodoo.h index 51f63d8..2590782 100644 --- a/src/video/vid_voodoo.h +++ b/src/video/vid_voodoo.h @@ -8,7 +8,7 @@ * * Definitions for the Voodoo driver. * - * Version: @(#)vid_voodoo.h 1.0.1 2018/02/14 + * Version: @(#)vid_voodoo.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define VIDEO_VOODOO_H -extern device_t voodoo_device; +extern const device_t voodoo_device; #endif /*VIDEO_VOODOO_H*/ diff --git a/src/video/vid_wy700.c b/src/video/vid_wy700.c index 4e7f7b8..757a0b9 100644 --- a/src/video/vid_wy700.c +++ b/src/video/vid_wy700.c @@ -53,7 +53,7 @@ * What doesn't work, is untested or not well understood: * - Cursor detach (commands 4 and 5) * - * Version: @(#)vid_wy700.c 1.0.1 2018/02/14 + * Version: @(#)vid_wy700.c 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -917,7 +917,7 @@ void wy700_poll(void *p) } -void *wy700_init(device_t *info) +void *wy700_init(const device_t *info) { int c; wy700_t *wy700 = malloc(sizeof(wy700_t)); @@ -1025,7 +1025,7 @@ void wy700_speed_changed(void *p) wy700_recalctimings(wy700); } -device_t wy700_device = +const device_t wy700_device = { "Wyse 700", DEVICE_ISA, 0, diff --git a/src/video/vid_wy700.h b/src/video/vid_wy700.h index 277cf38..40f022e 100644 --- a/src/video/vid_wy700.h +++ b/src/video/vid_wy700.h @@ -8,7 +8,7 @@ * * Definitions for the WY700 driver. * - * Version: @(#)vid_wy700.h 1.0.1 2018/02/14 + * Version: @(#)vid_wy700.h 1.0.2 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ # define VIDEO_WY700_H -extern device_t wy700_device; +extern const device_t wy700_device; #endif /*VIDEO_WY700_H*/ diff --git a/src/video/video.c b/src/video/video.c index 3ec9a7c..60406a7 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -40,7 +40,7 @@ * W = 3 bus clocks * L = 4 bus clocks * - * Version: @(#)video.c 1.0.4 2018/03/05 + * Version: @(#)video.c 1.0.5 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -93,6 +93,7 @@ enum { }; +int vid_present[VID_MAX]; bitmap_t *screen = NULL, *buffer = NULL, *buffer32 = NULL; @@ -134,7 +135,6 @@ int video_timing[6][4] = { { VIDEO_BUS, 4, 5, 10 }, { VIDEO_BUS, 3, 3, 4 } }; -static int video_force_resize; PALETTE cgapal = { {0,0,0}, {0,42,0}, {42,0,0}, {42,21,0}, {0,0,0}, {0,42,42}, {42,0,42}, {42,42,42}, @@ -212,6 +212,7 @@ static struct { event_t *blit_complete; event_t *buffer_not_in_use; } blit_data; +static int video_force_resize; static void (*blit_func)(int x, int y, int y1, int y2, int w, int h); @@ -378,12 +379,13 @@ static video_timings_t timing_endeavor = {VIDEO_BUS, 3, 2, 4,25,25,40}; void video_update_timing(void) { - video_timings_t *timing; - int new_gfxcard; + const video_timings_t *timing; + int new_card; if (video_speed == -1) { - new_gfxcard = 0; + new_card = 0; + /* FIXME: should be in machines[] table. */ switch(romset) { case ROM_IBMPCJR: case ROM_TANDY: @@ -433,8 +435,8 @@ video_update_timing(void) timing = &timing_endeavor; break; default: - new_gfxcard = video_old_to_new(gfxcard); - timing = video_card_gettiming(new_gfxcard); + new_card = video_old_to_new(vid_card); + timing = video_card_gettiming(new_card); break; } diff --git a/src/video/video.h b/src/video/video.h index bd0b22f..ef3f6c7 100644 --- a/src/video/video.h +++ b/src/video/video.h @@ -8,7 +8,7 @@ * * Definitions for the video controller module. * - * Version: @(#)video.h 1.0.5 2018/03/04 + * Version: @(#)video.h 1.0.6 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -48,89 +48,89 @@ enum { - GFX_NONE = 0, - GFX_INTERNAL, - GFX_CGA, - GFX_COMPAQ_CGA, /* Compaq CGA */ - GFX_COMPAQ_CGA_2, /* Compaq CGA 2 */ - GFX_COLORPLUS, /* Plantronics ColorPlus */ - GFX_WY700, /* Wyse 700 */ - GFX_MDA, - GFX_GENIUS, /* MDSI Genius */ - GFX_HERCULES, - GFX_HERCULESPLUS, - GFX_INCOLOR, /* Hercules InColor */ - GFX_EGA, /* Using IBM EGA BIOS */ - GFX_COMPAQ_EGA, /* Compaq EGA */ - GFX_SUPER_EGA, /* Using Chips & Technologies SuperEGA BIOS */ - GFX_VGA, /* IBM VGA */ - GFX_TVGA, /* Using Trident TVGA8900D BIOS */ - GFX_ET4000, /* Tseng ET4000 */ - GFX_ET4000W32_CARDEX_VLB, /* Tseng ET4000/W32p (Cardex) VLB */ - GFX_ET4000W32_CARDEX_PCI, /* Tseng ET4000/W32p (Cardex) PCI */ + VID_NONE = 0, + VID_INTERNAL, + VID_CGA, + VID_COMPAQ_CGA, /* Compaq CGA */ + VID_COMPAQ_CGA_2, /* Compaq CGA 2 */ + VID_COLORPLUS, /* Plantronics ColorPlus */ + VID_WY700, /* Wyse 700 */ + VID_MDA, + VID_GENIUS, /* MDSI Genius */ + VID_HERCULES, + VID_HERCULESPLUS, + VID_INCOLOR, /* Hercules InColor */ + VID_EGA, /* Using IBM EGA BIOS */ + VID_COMPAQ_EGA, /* Compaq EGA */ + VID_SUPER_EGA, /* Using Chips & Technologies SuperEGA BIOS */ + VID_VGA, /* IBM VGA */ + VID_TVGA, /* Using Trident TVGA8900D BIOS */ + VID_ET4000, /* Tseng ET4000 */ + VID_ET4000W32_CARDEX_VLB, /* Tseng ET4000/W32p (Cardex) VLB */ + VID_ET4000W32_CARDEX_PCI, /* Tseng ET4000/W32p (Cardex) PCI */ #if defined(DEV_BRANCH) && defined(USE_STEALTH32) - GFX_ET4000W32_VLB, /* Tseng ET4000/W32p (Diamond Stealth 32) VLB */ - GFX_ET4000W32_PCI, /* Tseng ET4000/W32p (Diamond Stealth 32) PCI */ + VID_ET4000W32_VLB, /* Tseng ET4000/W32p (Diamond Stealth 32) VLB */ + VID_ET4000W32_PCI, /* Tseng ET4000/W32p (Diamond Stealth 32) PCI */ #endif - GFX_BAHAMAS64_VLB, /* S3 Vision864 (Paradise Bahamas 64) VLB */ - GFX_BAHAMAS64_PCI, /* S3 Vision864 (Paradise Bahamas 64) PCI */ - GFX_N9_9FX_VLB, /* S3 764/Trio64 (Number Nine 9FX) VLB */ - GFX_N9_9FX_PCI, /* S3 764/Trio64 (Number Nine 9FX) PCI */ - GFX_TGUI9400CXI, /* Trident TGUI9400CXi VLB */ - GFX_TGUI9440_VLB, /* Trident TGUI9440AGi VLB */ - GFX_TGUI9440_PCI, /* Trident TGUI9440AGi PCI */ - GFX_ATIKOREANVGA, /* ATI Korean VGA (28800-5) */ - GFX_VGA88, /* ATI VGA-88 (18800-1) */ - GFX_VGAEDGE16, /* ATI VGA Edge-16 (18800-1) */ - GFX_VGACHARGER, /* ATI VGA Charger (28800-5) */ - GFX_VGAWONDER, /* Compaq ATI VGA Wonder (18800) */ - GFX_VGAWONDERXL, /* Compaq ATI VGA Wonder XL (28800-5) */ + VID_BAHAMAS64_VLB, /* S3 Vision864 (Paradise Bahamas 64) VLB */ + VID_BAHAMAS64_PCI, /* S3 Vision864 (Paradise Bahamas 64) PCI */ + VID_N9_9FX_VLB, /* S3 764/Trio64 (Number Nine 9FX) VLB */ + VID_N9_9FX_PCI, /* S3 764/Trio64 (Number Nine 9FX) PCI */ + VID_TGUI9400CXI, /* Trident TGUI9400CXi VLB */ + VID_TGUI9440_VLB, /* Trident TGUI9440AGi VLB */ + VID_TGUI9440_PCI, /* Trident TGUI9440AGi PCI */ + VID_ATIKOREANVGA, /* ATI Korean VGA (28800-5) */ + VID_VGA88, /* ATI VGA-88 (18800-1) */ + VID_VGAEDGE16, /* ATI VGA Edge-16 (18800-1) */ + VID_VGACHARGER, /* ATI VGA Charger (28800-5) */ + VID_VGAWONDER, /* Compaq ATI VGA Wonder (18800) */ + VID_VGAWONDERXL, /* Compaq ATI VGA Wonder XL (28800-5) */ #if defined(DEV_BRANCH) && defined(USE_XL24) - GFX_VGAWONDERXL24, /* Compaq ATI VGA Wonder XL24 (28800-6) */ + VID_VGAWONDERXL24, /* Compaq ATI VGA Wonder XL24 (28800-6) */ #endif - GFX_MACH64GX_ISA, /* ATI Graphics Pro Turbo (Mach64) ISA */ - GFX_MACH64GX_VLB, /* ATI Graphics Pro Turbo (Mach64) VLB */ - GFX_MACH64GX_PCI, /* ATI Graphics Pro Turbo (Mach64) PCI */ - GFX_MACH64VT2, /* ATI Mach64 VT2 */ - GFX_CL_GD5424_ISA, /* Cirrus Logic GD5424 ISA */ - GFX_CL_GD5424_VLB, /* Cirrus Logic GD5424 VLB */ - GFX_CL_GD5428_ISA, /* Cirrus Logic GD5428 ISA */ - GFX_CL_GD5428_VLB, /* Diamond SpeedStar PRO (Cirrus Logic GD5428) VLB */ - GFX_CL_GD5429_ISA, /* Cirrus Logic GD5429 ISA */ - GFX_CL_GD5429_VLB, /* Cirrus Logic GD5429 VLB */ - GFX_CL_GD5430_VLB, /* Diamond SpeedStar PRO SE (Cirrus Logic GD5430) PCI */ - GFX_CL_GD5430_PCI, /* Cirrus Logic GD5430 PCI */ - GFX_CL_GD5434_ISA, /* Cirrus Logic GD5434 ISA */ - GFX_CL_GD5434_VLB, /* Cirrus Logic GD5434 VLB */ - GFX_CL_GD5434_PCI, /* Cirrus Logic GD5434 PCI */ - GFX_CL_GD5436_PCI, /* Cirrus Logic CL-GD 5436 PCI */ - GFX_OTI037C, /* Oak OTI-037C */ - GFX_OTI067, /* Oak OTI-067 */ - GFX_OTI077, /* Oak OTI-077 */ - GFX_PVGA1A, /* Paradise PVGA1A Standalone */ - GFX_WD90C11, /* Paradise WD90C11-LR Standalone */ - GFX_WD90C30, /* Paradise WD90C30-LR Standalone */ - GFX_PHOENIX_TRIO32_VLB, /* S3 732/Trio32 (Phoenix) VLB */ - GFX_PHOENIX_TRIO32_PCI, /* S3 732/Trio32 (Phoenix) PCI */ - GFX_PHOENIX_TRIO64_VLB, /* S3 764/Trio64 (Phoenix) VLB */ - GFX_PHOENIX_TRIO64_PCI, /* S3 764/Trio64 (Phoenix) PCI */ - GFX_VIRGE_VLB, /* S3 Virge VLB */ - GFX_VIRGE_PCI, /* S3 Virge PCI */ - GFX_VIRGEDX_VLB, /* S3 Virge/DX VLB */ - GFX_VIRGEDX_PCI, /* S3 Virge/DX PCI */ - GFX_VIRGEDX4_VLB, /* S3 Virge/DX (VBE 2.0) VLB */ - GFX_VIRGEDX4_PCI, /* S3 Virge/DX (VBE 2.0) PCI */ - GFX_VIRGEVX_VLB, /* S3 Virge/VX VLB */ - GFX_VIRGEVX_PCI, /* S3 Virge/VX PCI */ - GFX_STEALTH64_VLB, /* S3 Vision864 (Diamond Stealth 64) VLB */ - GFX_STEALTH64_PCI, /* S3 Vision864 (Diamond Stealth 64) PCI */ - GFX_PHOENIX_VISION864_VLB, /* S3 Vision864 (Phoenix) VLB */ - GFX_PHOENIX_VISION864_PCI, /* S3 Vision864 (Phoenix) PCI */ + VID_MACH64GX_ISA, /* ATI Graphics Pro Turbo (Mach64) ISA */ + VID_MACH64GX_VLB, /* ATI Graphics Pro Turbo (Mach64) VLB */ + VID_MACH64GX_PCI, /* ATI Graphics Pro Turbo (Mach64) PCI */ + VID_MACH64VT2, /* ATI Mach64 VT2 */ + VID_CL_GD5424_ISA, /* Cirrus Logic GD5424 ISA */ + VID_CL_GD5424_VLB, /* Cirrus Logic GD5424 VLB */ + VID_CL_GD5428_ISA, /* Cirrus Logic GD5428 ISA */ + VID_CL_GD5428_VLB, /* Diamond SpeedStar PRO (Cirrus Logic GD5428) VLB */ + VID_CL_GD5429_ISA, /* Cirrus Logic GD5429 ISA */ + VID_CL_GD5429_VLB, /* Cirrus Logic GD5429 VLB */ + VID_CL_GD5430_VLB, /* Diamond SpeedStar PRO SE (Cirrus Logic GD5430) PCI */ + VID_CL_GD5430_PCI, /* Cirrus Logic GD5430 PCI */ + VID_CL_GD5434_ISA, /* Cirrus Logic GD5434 ISA */ + VID_CL_GD5434_VLB, /* Cirrus Logic GD5434 VLB */ + VID_CL_GD5434_PCI, /* Cirrus Logic GD5434 PCI */ + VID_CL_GD5436_PCI, /* Cirrus Logic CL-GD 5436 PCI */ + VID_OTI037C, /* Oak OTI-037C */ + VID_OTI067, /* Oak OTI-067 */ + VID_OTI077, /* Oak OTI-077 */ + VID_PVGA1A, /* Paradise PVGA1A Standalone */ + VID_WD90C11, /* Paradise WD90C11-LR Standalone */ + VID_WD90C30, /* Paradise WD90C30-LR Standalone */ + VID_PHOENIX_TRIO32_VLB, /* S3 732/Trio32 (Phoenix) VLB */ + VID_PHOENIX_TRIO32_PCI, /* S3 732/Trio32 (Phoenix) PCI */ + VID_PHOENIX_TRIO64_VLB, /* S3 764/Trio64 (Phoenix) VLB */ + VID_PHOENIX_TRIO64_PCI, /* S3 764/Trio64 (Phoenix) PCI */ + VID_VIRGE_VLB, /* S3 Virge VLB */ + VID_VIRGE_PCI, /* S3 Virge PCI */ + VID_VIRGEDX_VLB, /* S3 Virge/DX VLB */ + VID_VIRGEDX_PCI, /* S3 Virge/DX PCI */ + VID_VIRGEDX4_VLB, /* S3 Virge/DX (VBE 2.0) VLB */ + VID_VIRGEDX4_PCI, /* S3 Virge/DX (VBE 2.0) PCI */ + VID_VIRGEVX_VLB, /* S3 Virge/VX VLB */ + VID_VIRGEVX_PCI, /* S3 Virge/VX PCI */ + VID_STEALTH64_VLB, /* S3 Vision864 (Diamond Stealth 64) VLB */ + VID_STEALTH64_PCI, /* S3 Vision864 (Diamond Stealth 64) PCI */ + VID_PHOENIX_VISION864_VLB, /* S3 Vision864 (Phoenix) VLB */ + VID_PHOENIX_VISION864_PCI, /* S3 Vision864 (Phoenix) PCI */ #if defined(DEV_BRANCH) && defined(USE_TI) - GFX_TICF62011, /* TI CF62011 */ + VID_TICF62011, /* TI CF62011 */ #endif - GFX_MAX + VID_MAX }; enum { @@ -166,7 +166,7 @@ typedef struct { typedef rgb_t PALETTE[256]; -extern int gfx_present[GFX_MAX]; +extern int vid_present[VID_MAX]; extern int egareads, egawrites; extern int changeframecount; @@ -223,10 +223,10 @@ extern int video_card_available(int card); extern int video_detect(void); extern char *video_card_getname(int card); #ifdef EMU_DEVICE_H -extern device_t *video_card_getdevice(int card); +extern const device_t *video_card_getdevice(int card); #endif extern int video_card_has_config(int card); -extern video_timings_t *video_card_gettiming(int card); +extern const video_timings_t *video_card_gettiming(int card); extern int video_card_getid(char *s); extern int video_old_to_new(int card); extern int video_new_to_old(int card); diff --git a/src/vnc_keymap.c b/src/vnc_keymap.c index cc1dbc1..3d685e3 100644 --- a/src/vnc_keymap.c +++ b/src/vnc_keymap.c @@ -22,7 +22,7 @@ * NOTE: The values are as defined in the Microsoft document named * "Keyboard Scan Code Specification", v1.3a of 2000/03/16. * - * Version: @(#)vnc_keymap.c 1.0.1 2018/02/14 + * Version: @(#)vnc_keymap.c 1.0.2 2018/03/16 * * Author: Fred N. van Kempen, * Based on raw code by RichardG, @@ -70,7 +70,7 @@ #include "vnc.h" -static int keysyms_00[] = { +static const int keysyms_00[] = { 0x0000, /* 0x00 */ 0x0000, 0x0000, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index c1bb7e6..2d51af5 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -688,7 +688,7 @@ clobber: clean @echo Cleaning executables.. @-rm -f *.d 2>NUL @-rm -f *.exe 2>NUL -ifneq ($(PROFILER), y) +ifeq ($(PROFILER), y) @-rm -f *.map 2>NUL endif @-rm -f win/*.manifest 2>NUL diff --git a/src/win/win_devconf.c b/src/win/win_devconf.c index e84c6ff..f066ad6 100644 --- a/src/win/win_devconf.c +++ b/src/win/win_devconf.c @@ -8,7 +8,7 @@ * * Imlementation of the Device Configuration dialog. * - * Version: @(#)win_devconf.c 1.0.4 2018/03/10 + * Version: @(#)win_devconf.c 1.0.5 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -72,7 +72,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) int num; int changed; int cid; - device_config_t *config; + const device_config_t *config; char s[80]; wchar_t ws[512]; LPTSTR lptsTemp; @@ -87,7 +87,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) while (config->type != -1) { - device_config_selection_t *selection = config->selection; + const device_config_selection_t *selection = config->selection; h = GetDlgItem(hdlg, id); switch (config->type) @@ -204,7 +204,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) while (config->type != -1) { - device_config_selection_t *selection = config->selection; + const device_config_selection_t *selection = config->selection; h = GetDlgItem(hdlg, id); switch (config->type) @@ -316,7 +316,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) while (config->type != -1) { - device_config_selection_t *selection = config->selection; + const device_config_selection_t *selection = config->selection; h = GetDlgItem(hdlg, id); switch (config->type) @@ -396,7 +396,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) else { int id = IDC_CONFIG_BASE; - device_config_t *config = config_device->config; + const device_config_t *config = config_device->config; while (config->type != -1) { @@ -478,7 +478,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) uint8_t deviceconfig_open(HWND hwnd, device_t *device) { - device_config_t *config = device->config; + const device_config_t *config = device->config; uint16_t *data_block = malloc(16384); uint16_t *data; DLGTEMPLATE *dlg = (DLGTEMPLATE *)data_block; diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 129aae8..c98ef4b 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Implementation of the Settings dialog. * - * Version: @(#)win_settings.c 1.0.10 2018/03/12 + * Version: @(#)win_settings.c 1.0.11 2018/03/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -81,7 +81,7 @@ static int temp_dynarec; #endif /* Video category */ -static int temp_gfxcard, temp_video_speed, temp_voodoo; +static int temp_vid_card, temp_video_speed, temp_voodoo; /* Input devices category */ static int temp_mouse, temp_joystick; @@ -92,7 +92,7 @@ static int temp_float; /* Network category */ static int temp_net_type, temp_net_card; -static char temp_pcap_dev[520]; +static char temp_host_dev[520]; /* Ports category */ static char temp_lpt_device_names[3][16]; @@ -171,7 +171,7 @@ settings_init(void) temp_sync = enable_sync; /* Video category */ - temp_gfxcard = gfxcard; + temp_vid_card = vid_card; temp_video_speed = video_speed; temp_voodoo = voodoo_enabled; @@ -191,8 +191,8 @@ settings_init(void) /* Network category */ temp_net_type = network_type; - memset(temp_pcap_dev, 0, sizeof(temp_pcap_dev)); - strcpy(temp_pcap_dev, network_pcap); + memset(temp_host_dev, 0, sizeof(temp_host_dev)); + strcpy(temp_host_dev, network_host); temp_net_card = network_card; /* Ports category */ @@ -286,7 +286,7 @@ settings_changed(void) i = i || (temp_sync != enable_sync); /* Video category */ - i = i || (gfxcard != temp_gfxcard); + i = i || (vid_card != temp_vid_card); i = i || (video_speed != temp_video_speed); i = i || (voodoo_enabled != temp_voodoo); @@ -306,7 +306,7 @@ settings_changed(void) /* Network category */ i = i || (network_type != temp_net_type); - i = i || strcmp(temp_pcap_dev, network_pcap); + i = i || strcmp(temp_host_dev, network_host); i = i || (network_card != temp_net_card); /* Ports category */ @@ -389,7 +389,7 @@ settings_save(void) enable_sync = temp_sync; /* Video category */ - gfxcard = temp_gfxcard; + vid_card = temp_vid_card; video_speed = temp_video_speed; voodoo_enabled = temp_voodoo; @@ -409,8 +409,8 @@ settings_save(void) /* Network category */ network_type = temp_net_type; - memset(network_pcap, '\0', sizeof(network_pcap)); - strcpy(network_pcap, temp_pcap_dev); + memset(network_host, '\0', sizeof(network_host)); + strcpy(network_host, temp_host_dev); network_card = temp_net_card; /* Ports category */ @@ -774,7 +774,7 @@ machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) } if (machines[temp_machine].flags & MACHINE_VIDEO) { - gfxcard = GFX_INTERNAL; + vid_card = VID_INTERNAL; } free(stransi); free(lptsTemp); @@ -810,12 +810,12 @@ static void recalc_vid_list(HWND hdlg) if (!s[0]) break; - if (video_card_available(c) && gfx_present[video_new_to_old(c)] && + if (video_card_available(c) && vid_present[video_new_to_old(c)] && device_is_valid(video_card_getdevice(c), machines[temp_machine].flags)) { mbstowcs(szText, s, strlen(s) + 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); - if (video_new_to_old(c) == temp_gfxcard) + if (video_new_to_old(c) == temp_vid_card) { SendMessage(h, CB_SETCURSEL, d, 0); @@ -829,7 +829,7 @@ static void recalc_vid_list(HWND hdlg) } if (!found_card) SendMessage(h, CB_SETCURSEL, 0, 0); - EnableWindow(h, machines[temp_machine].fixed_gfxcard ? FALSE : TRUE); + EnableWindow(h, machines[temp_machine].fixed_vidcard ? FALSE : TRUE); h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); EnableWindow(h, (machines[temp_machine].flags & MACHINE_PCI) ? TRUE : FALSE); @@ -903,7 +903,7 @@ video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); wcstombs(stransi, lptsTemp, 512); gfx = video_card_getid(stransi); - temp_gfxcard = video_new_to_old(gfx); + temp_vid_card = video_new_to_old(gfx); h = GetDlgItem(hdlg, IDC_CONFIGURE_VID); if (video_card_has_config(gfx)) @@ -953,7 +953,7 @@ video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); wcstombs(stransi, lptsTemp, 512); - temp_gfxcard = video_new_to_old(video_card_getid(stransi)); + temp_vid_card = video_new_to_old(video_card_getid(stransi)); h = GetDlgItem(hdlg, IDC_COMBO_VIDEO_SPEED); temp_video_speed = SendMessage(h, CB_GETCURSEL, 0, 0) - 1; @@ -973,7 +973,7 @@ video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) static int mouse_valid(int num, int m) { - device_t *dev; + const device_t *dev; if ((num == MOUSE_TYPE_INTERNAL) && !(machines[m].flags & MACHINE_MOUSE)) return(0); @@ -1177,7 +1177,7 @@ sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) int c = 0; int d = 0; LPTSTR lptsTemp; - device_t *sound_dev/*, *midi_dev*/; + const device_t *sound_dev/*, *midi_dev*/; char *s; switch (message) @@ -1599,7 +1599,7 @@ peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) int c = 0; int d = 0; LPTSTR lptsTemp; - device_t *scsi_dev; + const device_t *scsi_dev; switch (message) { @@ -1794,7 +1794,7 @@ static void network_recalc_combos(HWND hdlg) EnableWindow(h, TRUE); } else if ((temp_net_type == NET_TYPE_PCAP) && - (network_dev_to_id(temp_pcap_dev) > 0)) + (network_dev_to_id(temp_host_dev) > 0)) { EnableWindow(h, TRUE); } @@ -1811,7 +1811,7 @@ static void network_recalc_combos(HWND hdlg) } else if (network_card_has_config(temp_net_card) && (temp_net_type == NET_TYPE_PCAP) && - (network_dev_to_id(temp_pcap_dev) > 0)) + (network_dev_to_id(temp_host_dev) > 0)) { EnableWindow(h, TRUE); } @@ -1862,7 +1862,7 @@ network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) mbstowcs(lptsTemp, network_devs[c].description, strlen(network_devs[c].description) + 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } - SendMessage(h, CB_SETCURSEL, network_dev_to_id(temp_pcap_dev), 0); + SendMessage(h, CB_SETCURSEL, network_dev_to_id(temp_host_dev), 0); /*NIC config*/ h = GetDlgItem(hdlg, IDC_COMBO_NET); @@ -1927,8 +1927,8 @@ network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) } h = GetDlgItem(hdlg, IDC_COMBO_PCAP); - memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); - strcpy(temp_pcap_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); + memset(temp_host_dev, '\0', sizeof(temp_host_dev)); + strcpy(temp_host_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); network_recalc_combos(hdlg); break; @@ -1964,8 +1964,8 @@ network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0); h = GetDlgItem(hdlg, IDC_COMBO_PCAP); - memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); - strcpy(temp_pcap_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); + memset(temp_host_dev, '\0', sizeof(temp_host_dev)); + strcpy(temp_host_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); h = GetDlgItem(hdlg, IDC_COMBO_NET); temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)];