From 9ae91cdae64216c20c3faccdd0059e0fd52d36c2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 16 Mar 2018 19:09:26 +0100 Subject: [PATCH 01/39] (D)word reads from IDE channels with no device attached now always return FFFF(FFFF), fixes the last IDE-related crashes. --- src/disk/hdc_ide.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index d07532abd..e80e287b0 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.35 2018/03/16 + * Version: @(#)hdc_ide.c 1.0.36 2018/03/16 * * Authors: Sarah Walker, * Miran Grca, @@ -1612,6 +1612,20 @@ uint32_t ide_read_data(int ide_board, int length) IDE *ide = &ide_drives[cur_ide[ide_board]]; uint32_t temp; + if (!ide->buffer) { + switch (length) + { + case 1: + return 0xff; + case 2: + return 0xffff; + case 4: + return 0xffffffff; + default: + return 0; + } + } + uint8_t *idebufferb = (uint8_t *) ide->buffer; uint16_t *idebufferw = ide->buffer; uint32_t *idebufferl = (uint32_t *) ide->buffer; From f8f889b72c659b2c2a5a668075effd552dba8511 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 16 Mar 2018 22:46:05 +0100 Subject: [PATCH 02/39] Fixed a minor issue in hdc_ide.c; Fixed SCSI DMA command termination in the CD-ROM and Iomega ZIP code. --- src/cdrom/cdrom.c | 16 +++++++++++----- src/disk/hdc_ide.c | 8 ++------ src/disk/zip.c | 16 +++++++++++----- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 502821ab6..389efeed9 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.35 2018/03/15 + * Version: @(#)cdrom.c 1.0.36 2018/03/16 * * Author: Miran Grca, * @@ -2766,14 +2766,17 @@ int cdrom_read_from_dma(uint8_t id) ret = cdrom_phase_data_out(id); - if (ret) { + if (ret || (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)) { cdrom_buf_free(id); cdrom[id].packet_status = CDROM_PHASE_COMPLETE; cdrom[id].status = READY_STAT; cdrom[id].phase = 3; ui_sb_update_icon(SB_CDROM | id, 0); cdrom_irq_raise(id); - return 1; + if (ret) + return 1; + else + return 0; } else return 0; } @@ -2819,14 +2822,17 @@ int cdrom_write_to_dma(uint8_t id) } else ret = cdrom_write_to_ide_dma(cdrom_drives[id].ide_channel); - if (ret) { + if (ret || (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)) { cdrom_buf_free(id); cdrom[id].packet_status = CDROM_PHASE_COMPLETE; cdrom[id].status = READY_STAT; cdrom[id].phase = 3; ui_sb_update_icon(SB_CDROM | id, 0); cdrom_irq_raise(id); - return 1; + if (ret) + return 1; + else + return 0; } else return 0; } diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index e80e287b0..5dda6f166 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.36 2018/03/16 + * Version: @(#)hdc_ide.c 1.0.37 2018/03/16 * * Authors: Sarah Walker, * Miran Grca, @@ -861,7 +861,6 @@ 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 = NULL; /* Important, makes sure malloc does not reuse an existing pointer from elsewhere. */ ide_drives[hdd[d].ide_channel].sector_buffer = (uint8_t *) malloc(256*512); if (++c >= (IDE_NUM+XTIDE_NUM)) break; } @@ -869,7 +868,6 @@ void ide_reset(void) { 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 = NULL; /* Important, makes sure malloc does not reuse an existing pointer from elsewhere. */ ide_drives[hdd[d].xtide_channel | 8].sector_buffer = (uint8_t *) malloc(256*512); if (++c >= (IDE_NUM+XTIDE_NUM)) break; } @@ -883,10 +881,8 @@ void ide_reset(void) 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 = NULL; /* Important, makes sure malloc does not reuse an existing pointer from elsewhere. */ + if (ide_drives[d].type != IDE_NONE) ide_drives[d].buffer = (uint16_t *) malloc(65536 * sizeof(uint16_t)); - } ide_set_signature(&ide_drives[d]); diff --git a/src/disk/zip.c b/src/disk/zip.c index e6b2689de..5e2e71dfb 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -9,7 +9,7 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.c 1.0.9 2018/03/15 + * Version: @(#)zip.c 1.0.10 2018/03/16 * * Author: Miran Grca, * @@ -2267,14 +2267,17 @@ int zip_read_from_dma(uint8_t id) ret = zip_phase_data_out(id); - if (ret) { + if (ret || (zip_drives[id].bus_type == ZIP_BUS_SCSI)) { zip_buf_free(id); zip[id].packet_status = ZIP_PHASE_COMPLETE; zip[id].status = READY_STAT; zip[id].phase = 3; ui_sb_update_icon(SB_ZIP | id, 0); zip_irq_raise(id); - return 1; + if (ret) + return 1; + else + return 0; } else return 0; } @@ -2322,14 +2325,17 @@ int zip_write_to_dma(uint8_t id) } else ret = zip_write_to_ide_dma(zip_drives[id].ide_channel); - if (ret) { + if (ret || (zip_drives[id].bus_type == ZIP_BUS_SCSI)) { zip_buf_free(id); zip[id].packet_status = ZIP_PHASE_COMPLETE; zip[id].status = READY_STAT; zip[id].phase = 3; ui_sb_update_icon(SB_ZIP | id, 0); zip_irq_raise(id); - return 1; + if (ret) + return 1; + else + return 0; } else return 0; } From a59dc8e43681b5a8aee139e0cfe90769e5b25ed2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 17 Mar 2018 20:32:20 +0100 Subject: [PATCH 03/39] CD-ROM code clean-ups, also reduces memory usage by a further about 2 MB. --- src/86box.h | 4 +- src/cdrom/cdrom.c | 825 ++++++++++++++++++++++++-------------- src/cdrom/cdrom.h | 55 ++- src/cdrom/cdrom_image.cc | 129 +++--- src/config.c | 4 +- src/disk/hdc.c | 12 +- src/disk/hdc_ide.c | 182 ++++----- src/disk/zip.c | 25 +- src/disk/zip.h | 3 +- src/pc.c | 26 +- src/scsi/scsi_device.c | 10 +- src/win/win_cdrom.c | 10 +- src/win/win_cdrom_ioctl.c | 189 +++++---- 13 files changed, 869 insertions(+), 605 deletions(-) diff --git a/src/86box.h b/src/86box.h index c1cb9369c..19ffc1e30 100644 --- a/src/86box.h +++ b/src/86box.h @@ -8,7 +8,7 @@ * * Main include file for the application. * - * Version: @(#)86box.h 1.0.18 2018/03/13 + * Version: @(#)86box.h 1.0.19 2018/03/17 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -52,7 +52,7 @@ #endif #define MIN(a, b) ((a) < (b) ? (a) : (b)) - +#define ABS(x) ((x) > 0 ? (x) : -(x)) #ifdef __cplusplus extern "C" { diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 389efeed9..20a066365 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -50,7 +50,7 @@ #define ABRT_ERR 0x04 /* Command aborted */ #define MCR_ERR 0x08 /* Media change request */ -cdrom_t cdrom[CDROM_NUM]; +cdrom_t *cdrom[CDROM_NUM]; cdrom_image_t cdrom_image[CDROM_NUM]; cdrom_ioctl_t cdrom_ioctl[CDROM_NUM]; cdrom_drive_t cdrom_drives[CDROM_NUM]; @@ -410,39 +410,59 @@ void build_scsi_cdrom_map() void cdrom_set_callback(uint8_t id) { if (cdrom_drives[id].bus_type != CDROM_BUS_SCSI) - ide_set_callback(cdrom_drives[id].ide_channel, cdrom[id].callback); + ide_set_callback(cdrom_drives[id].ide_channel, cdrom[id]->callback); } void cdrom_set_cdb_len(int id, int cdb_len) { - cdrom[id].cdb_len = cdb_len; + cdrom[id]->cdb_len = cdb_len; } void cdrom_reset_cdb_len(int id) { - cdrom[id].cdb_len = cdrom[id].cdb_len_setting ? 16 : 12; + cdrom[id]->cdb_len = cdrom[id]->cdb_len_setting ? 16 : 12; } void cdrom_set_signature(int id) { + cdrom_t *dev = cdrom[id]; + if (id >= CDROM_NUM) return; - cdrom[id].phase = 1; - cdrom[id].request_length = 0xEB14; + dev->phase = 1; + dev->request_length = 0xEB14; +} + +void cdrom_destroy_drives(void) +{ + int i; + + for (i = 0; i < CDROM_NUM; i++) { + if (cdrom[i]) { + free(cdrom[i]); + cdrom[i] = NULL; + } + } } void cdrom_init(int id, int cdb_len_setting) { + cdrom_t *dev; + if (id >= CDROM_NUM) return; - memset(&(cdrom[id]), 0, sizeof(cdrom_t)); - cdrom[id].requested_blocks = 1; + if (!cdrom[id]) + cdrom[id] = (cdrom_t *) malloc(sizeof(cdrom_t)); + pclog(NULL); /* Trigger segfault so we can backtrace. */ + dev = cdrom[id]; + memset(dev, 0, sizeof(cdrom_t)); + dev->requested_blocks = 1; if (cdb_len_setting <= 1) - cdrom[id].cdb_len_setting = cdb_len_setting; + dev->cdb_len_setting = cdb_len_setting; cdrom_reset_cdb_len(id); - cdrom[id].cd_status = CD_STATUS_EMPTY; - cdrom[id].sense[0] = 0xf0; - cdrom[id].sense[7] = 10; + dev->cd_status = CD_STATUS_EMPTY; + dev->sense[0] = 0xf0; + dev->sense[7] = 10; cdrom_drives[id].bus_mode = 0; if (cdrom_drives[id].bus_type >= CDROM_BUS_ATAPI_PIO_AND_DMA) cdrom_drives[id].bus_mode |= 2; @@ -452,12 +472,12 @@ void cdrom_init(int id, int cdb_len_setting) if (cdrom_drives[id].bus_type < CDROM_BUS_SCSI) cdrom_set_signature(id); cdrom_drives[id].max_blocks_at_once = 85; - cdrom[id].status = READY_STAT | DSC_STAT; - cdrom[id].pos = 0; - cdrom[id].packet_status = 0xff; - cdrom_sense_key = cdrom_asc = cdrom_ascq = cdrom[id].unit_attention = 0; - cdrom[id].cdb_len_setting = 0; - cdrom[id].cdb_len = 12; + dev->status = READY_STAT | DSC_STAT; + dev->pos = 0; + dev->packet_status = 0xff; + cdrom_sense_key = cdrom_asc = cdrom_ascq = dev->unit_attention = 0; + dev->cdb_len_setting = 0; + dev->cdb_len = 12; } int cdrom_supports_pio(int id) @@ -473,6 +493,8 @@ int cdrom_supports_dma(int id) /* Returns: 0 for none, 1 for PIO, 2 for DMA. */ int cdrom_current_mode(int id) { + cdrom_t *dev = cdrom[id]; + if (!cdrom_supports_pio(id) && !cdrom_supports_dma(id)) return 0; if (cdrom_supports_pio(id) && !cdrom_supports_dma(id)) { @@ -482,8 +504,8 @@ int cdrom_current_mode(int id) if (!cdrom_supports_pio(id) && cdrom_supports_dma(id)) return 2; if (cdrom_supports_pio(id) && cdrom_supports_dma(id)) { - cdrom_log("CD-ROM %i: Drive supports both, setting to %s\n", id, (cdrom[id].features & 1) ? "DMA" : "PIO", id); - return (cdrom[id].features & 1) ? 2 : 1; + cdrom_log("CD-ROM %i: Drive supports both, setting to %s\n", id, (dev->features & 1) ? "DMA" : "PIO", id); + return (dev->features & 1) ? 2 : 1; } return 0; @@ -492,7 +514,9 @@ int cdrom_current_mode(int id) /* Translates ATAPI status (ERR_STAT flag) to SCSI status. */ int cdrom_CDROM_PHASE_to_scsi(uint8_t id) { - if (cdrom[id].status & ERR_STAT) + cdrom_t *dev = cdrom[id]; + + if (dev->status & ERR_STAT) return SCSI_STATUS_CHECK_CONDITION; else return SCSI_STATUS_OK; @@ -501,8 +525,10 @@ int cdrom_CDROM_PHASE_to_scsi(uint8_t id) /* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */ int cdrom_atapi_phase_to_scsi(uint8_t id) { - if (cdrom[id].status & 8) { - switch (cdrom[id].phase & 3) { + cdrom_t *dev = cdrom[id]; + + if (dev->status & 8) { + switch (dev->phase & 3) { case 0: return 0; case 1: @@ -513,7 +539,7 @@ int cdrom_atapi_phase_to_scsi(uint8_t id) return 7; } } else { - if ((cdrom[id].phase & 3) == 3) + if ((dev->phase & 3) == 3) return 3; else return 4; @@ -645,6 +671,8 @@ uint8_t cdrom_mode_sense_read(uint8_t id, uint8_t page_control, uint8_t page, ui uint32_t cdrom_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t block_descriptor_len) { + cdrom_t *dev = cdrom[id]; + uint8_t page_control = (type >> 6) & 3; int i = 0; @@ -667,7 +695,7 @@ uint32_t cdrom_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, for (i = 0; i < 0x40; i++) { if ((type == GPMODE_ALL_PAGES) || (type == i)) { - if (cdrom_mode_sense_page_flags & (1LL << cdrom[id].current_page_code)) { + if (cdrom_mode_sense_page_flags & (1LL << dev->current_page_code)) { buf[pos++] = cdrom_mode_sense_read(id, page_control, i, 0); msplen = cdrom_mode_sense_read(id, page_control, i, 1); buf[pos++] = msplen; @@ -683,58 +711,169 @@ uint32_t cdrom_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, void cdrom_update_request_length(uint8_t id, int len, int block_len) { + cdrom_t *dev = cdrom[id]; uint32_t bt; - cdrom[id].max_transfer_len = cdrom[id].request_length; + + dev->max_transfer_len = dev->request_length; /* For media access commands, make sure the requested DRQ length matches the block length. */ - switch (cdrom[id].current_cdb[0]) { + switch (dev->current_cdb[0]) { case 0x08: case 0x28: case 0xa8: case 0xb9: case 0xbe: - if (cdrom[id].max_transfer_len < block_len) - cdrom[id].max_transfer_len = block_len; - bt = (cdrom[id].requested_blocks * block_len); + if (dev->max_transfer_len < block_len) + dev->max_transfer_len = block_len; + bt = (dev->requested_blocks * block_len); if (len > bt) len = bt; default: - cdrom[id].packet_len = len; + dev->packet_len = len; break; } /* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */ - if ((cdrom[id].max_transfer_len & 1) && (cdrom[id].max_transfer_len < len)) - cdrom[id].max_transfer_len &= 0xfffe; + if ((dev->max_transfer_len & 1) && (dev->max_transfer_len < len)) + dev->max_transfer_len &= 0xfffe; /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ - if (!cdrom[id].max_transfer_len) - cdrom[id].max_transfer_len = 65534; - if (len <= cdrom[id].max_transfer_len) - cdrom[id].max_transfer_len = len; + if (!dev->max_transfer_len) + dev->max_transfer_len = 65534; + if (len <= dev->max_transfer_len) + dev->max_transfer_len = len; return; } +static double cdrom_get_short_seek(uint8_t id) +{ + switch(cdrom_drives[id].speed) { + case 0: + fatal("CD-ROM %i: 0x speed\n", id); + return 0.0; + case 1: + return 240.0; + case 2: + return 160.0; + case 3: + return 150.0; + case 4: case 5: case 6: case 7: case 8: + case 9: case 10: case 11: + return 112.0; + case 12: case 13: case 14: case 15: + return 75.0; + case 16: case 17: case 18: case 19: + return 58.0; + case 20: case 21: case 22: case 23: + case 40: case 41: case 42: case 43: + case 44: case 45: case 46: case 47: + case 48: + return 50.0; + default: + /* 24-32, 52+ */ + return 45.0; + } +} + +static double cdrom_get_long_seek(uint8_t id) +{ + switch(cdrom_drives[id].speed) { + case 0: + fatal("CD-ROM %i: 0x speed\n", id); + return 0.0; + case 1: + return 1446.0; + case 2: + return 1000.0; + case 3: + return 900.0; + case 4: case 5: case 6: case 7: case 8: + case 9: case 10: case 11: + return 675.0; + case 12: case 13: case 14: case 15: + return 400.0; + case 16: case 17: case 18: case 19: + return 350.0; + case 20: case 21: case 22: case 23: + case 40: case 41: case 42: case 43: + case 44: case 45: case 46: case 47: + case 48: + return 300.0; + default: + /* 24-32, 52+ */ + return 270.0; + } +} + +#define MIN_SEEK 2000 +#define MAX_SEEK 333333 + +static double cdrom_seek_time(uint8_t id) +{ + cdrom_t *dev = cdrom[id]; + + uint32_t diff = dev->seek_diff; + double sd = (double) (MAX_SEEK - MIN_SEEK); + + if (diff < MIN_SEEK) + return 0.0; + if (diff > MAX_SEEK) + diff = MAX_SEEK; + + diff -= MIN_SEEK; + + return cdrom_get_short_seek(id) + ((cdrom_get_long_seek(id) * ((double) diff)) / sd); +} + +static double cdrom_bus_speed(uint8_t id) +{ + cdrom_t *dev = cdrom[id]; + + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { + dev->callback = -1LL; /* Speed depends on SCSI controller */ + return 0.0; + } else if (cdrom_drives[id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA) { + if (cdrom_current_mode(id) == 2) + return 66666666.666666666666666; /* 66 MB/s MDMA-2 speed */ + else + return 8333333.333333333333333; /* 8.3 MB/s PIO-2 speed */ + } else + return 3333333.333333333333333; /* 3.3 MB/s PIO-0 speed */ +} + static void cdrom_command_common(uint8_t id) { + cdrom_t *dev = cdrom[id]; + double bytes_per_second, period; double dusec; - cdrom[id].status = BUSY_STAT; - cdrom[id].phase = 1; - cdrom[id].pos = 0; - if (cdrom[id].packet_status == CDROM_PHASE_COMPLETE) { + dev->status = BUSY_STAT; + dev->phase = 1; + dev->pos = 0; + dev->callback = 0LL; + if (dev->packet_status == CDROM_PHASE_COMPLETE) { cdrom_phase_callback(id); - cdrom[id].callback = 0LL; + dev->callback = 0LL; } else { - switch(cdrom[id].current_cdb[0]) { + switch(dev->current_cdb[0]) { + case 0x0b: + case 0x2b: + /* Seek time is in ms. */ + period = cdrom_seek_time(id) * ((double) TIMER_USEC) * 1000.0; + dev->callback += ((int64_t) period); + cdrom_set_callback(id); + return; + case 0x08: + case 0x28: + case 0xa8: + /* Seek time is in ms. */ + period = cdrom_seek_time(id) * ((double) TIMER_USEC) * 1000.0; + dev->callback += ((int64_t) period); case 0x25: case 0x42: case 0x43: case 0x44: - case 0x08: - case 0x28: case 0x51: case 0x52: - case 0xa8: case 0xad: case 0xb8: case 0xb9: @@ -743,56 +882,61 @@ static void cdrom_command_common(uint8_t id) bytes_per_second *= (double) cdrom_drives[id].speed; break; default: - if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { - cdrom[id].callback = -1LL; /* Speed depends on SCSI controller */ + bytes_per_second = cdrom_bus_speed(id); + if (bytes_per_second == 0.0) { + dev->callback = -1LL; /* Speed depends on SCSI controller */ return; - } else if (cdrom_drives[id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA) { - if (cdrom_current_mode(id) == 2) - bytes_per_second = 66666666.666666666666666; /* 66 MB/s MDMA-2 speed */ - else - bytes_per_second = 8333333.333333333333333; /* 8.3 MB/s PIO-2 speed */ - } else - bytes_per_second = 3333333.333333333333333; /* 3.3 MB/s PIO-0 speed */ + } break; } period = 1000000.0 / bytes_per_second; dusec = (double) TIMER_USEC; - dusec = dusec * period * (double) (cdrom[id].packet_len); - cdrom[id].callback = ((int64_t) dusec); + dusec = dusec * period * (double) (dev->packet_len); + dev->callback += ((int64_t) dusec); } cdrom_set_callback(id); } static void cdrom_command_complete(uint8_t id) { - cdrom[id].packet_status = CDROM_PHASE_COMPLETE; + cdrom_t *dev = cdrom[id]; + + dev->packet_status = CDROM_PHASE_COMPLETE; cdrom_command_common(id); } static void cdrom_command_read(uint8_t id) { - cdrom[id].packet_status = CDROM_PHASE_DATA_IN; + cdrom_t *dev = cdrom[id]; + + dev->packet_status = CDROM_PHASE_DATA_IN; cdrom_command_common(id); - cdrom[id].total_read = 0; + dev->total_read = 0; } static void cdrom_command_read_dma(uint8_t id) { - cdrom[id].packet_status = CDROM_PHASE_DATA_IN_DMA; + cdrom_t *dev = cdrom[id]; + + dev->packet_status = CDROM_PHASE_DATA_IN_DMA; cdrom_command_common(id); - cdrom[id].total_read = 0; + dev->total_read = 0; } static void cdrom_command_write(uint8_t id) { - cdrom[id].packet_status = CDROM_PHASE_DATA_OUT; + cdrom_t *dev = cdrom[id]; + + dev->packet_status = CDROM_PHASE_DATA_OUT; cdrom_command_common(id); } static void cdrom_command_write_dma(uint8_t id) { - cdrom[id].packet_status = CDROM_PHASE_DATA_OUT_DMA; + cdrom_t *dev = cdrom[id]; + + dev->packet_status = CDROM_PHASE_DATA_OUT_DMA; cdrom_command_common(id); } @@ -803,8 +947,10 @@ static void cdrom_command_write_dma(uint8_t id) direction = Transfer direction (0 = read from host, 1 = write to host). */ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int alloc_len, int direction) { - cdrom_log("CD-ROM %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", id, cdrom[id].current_cdb[0], len, block_len, alloc_len, direction, cdrom[id].request_length); - cdrom[id].pos=0; + cdrom_t *dev = cdrom[id]; + + cdrom_log("CD-ROM %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); + dev->pos=0; if (alloc_len >= 0) { if (alloc_len < len) { len = alloc_len; @@ -812,14 +958,14 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al } if ((len == 0) || (cdrom_current_mode(id) == 0)) { if (cdrom_drives[id].bus_type != CDROM_BUS_SCSI) { - cdrom[id].packet_len = 0; + dev->packet_len = 0; } cdrom_command_complete(id); } else { if (cdrom_current_mode(id) == 2) { if (cdrom_drives[id].bus_type != CDROM_BUS_SCSI) { - cdrom[id].packet_len = alloc_len; + dev->packet_len = alloc_len; } if (direction == 0) @@ -836,12 +982,14 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al } } - cdrom_log("CD-ROM %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", id, cdrom[id].packet_status, cdrom[id].request_length, cdrom[id].packet_len, cdrom[id].pos, cdrom[id].phase); + cdrom_log("CD-ROM %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", id, dev->packet_status, dev->request_length, dev->packet_len, dev->pos, dev->phase); } static void cdrom_sense_clear(int id, int command) { - cdrom[id].previous_command = command; + cdrom_t *dev = cdrom[id]; + + dev->previous_command = command; cdrom_sense_key = cdrom_asc = cdrom_ascq = 0; } @@ -858,30 +1006,34 @@ static void cdrom_set_phase(uint8_t id, uint8_t phase) static void cdrom_cmd_error(uint8_t id) { + cdrom_t *dev = cdrom[id]; + cdrom_set_phase(id, SCSI_PHASE_STATUS); - cdrom[id].error = ((cdrom_sense_key & 0xf) << 4) | ABRT_ERR; - if (cdrom[id].unit_attention) - cdrom[id].error |= MCR_ERR; - cdrom[id].status = READY_STAT | ERR_STAT; - cdrom[id].phase = 3; - cdrom[id].pos = 0; - cdrom[id].packet_status = 0x80; - cdrom[id].callback = 50LL * CDROM_TIME; + dev->error = ((cdrom_sense_key & 0xf) << 4) | ABRT_ERR; + if (dev->unit_attention) + dev->error |= MCR_ERR; + dev->status = READY_STAT | ERR_STAT; + dev->phase = 3; + dev->pos = 0; + dev->packet_status = 0x80; + dev->callback = 50LL * CDROM_TIME; cdrom_set_callback(id); cdrom_log("CD-ROM %i: ERROR: %02X/%02X/%02X\n", id, cdrom_sense_key, cdrom_asc, cdrom_ascq); } static void cdrom_unit_attention(uint8_t id) { + cdrom_t *dev = cdrom[id]; + cdrom_set_phase(id, SCSI_PHASE_STATUS); - cdrom[id].error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; - if (cdrom[id].unit_attention) - cdrom[id].error |= MCR_ERR; - cdrom[id].status = READY_STAT | ERR_STAT; - cdrom[id].phase = 3; - cdrom[id].pos = 0; - cdrom[id].packet_status = 0x80; - cdrom[id].callback = 50LL * CDROM_TIME; + dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; + if (dev->unit_attention) + dev->error |= MCR_ERR; + dev->status = READY_STAT | ERR_STAT; + dev->phase = 3; + dev->pos = 0; + dev->packet_status = 0x80; + dev->callback = 50LL * CDROM_TIME; cdrom_set_callback(id); cdrom_log("CD-ROM %i: UNIT ATTENTION\n", id); } @@ -920,20 +1072,24 @@ static void cdrom_lba_out_of_range(uint8_t id) static void cdrom_invalid_field(uint8_t id) { + cdrom_t *dev = cdrom[id]; + cdrom_sense_key = SENSE_ILLEGAL_REQUEST; cdrom_asc = ASC_INV_FIELD_IN_CMD_PACKET; cdrom_ascq = 0; cdrom_cmd_error(id); - cdrom[id].status = 0x53; + dev->status = 0x53; } static void cdrom_invalid_field_pl(uint8_t id) { + cdrom_t *dev = cdrom[id]; + cdrom_sense_key = SENSE_ILLEGAL_REQUEST; cdrom_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; cdrom_ascq = 0; cdrom_cmd_error(id); - cdrom[id].status = 0x53; + dev->status = 0x53; } static void cdrom_illegal_mode(uint8_t id) @@ -1054,10 +1210,12 @@ void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks) } } -#define cdbufferb cdrom[id].buffer +#define cdbufferb dev->buffer int cdrom_read_data(uint8_t id, int msf, int type, int flags, uint32_t *len) { + cdrom_t *dev = cdrom[id]; + int ret = 0; int cdsize = 0; @@ -1069,36 +1227,36 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, uint32_t *len) if (cdrom_drives[id].handler->pass_through) { cdsize = cdrom_drives[id].handler->size(id); - ret = cdrom_pass_through(id, len, cdrom[id].current_cdb, cdbufferb + cdrom[id].data_pos); - cdrom[id].data_pos += *len; + ret = cdrom_pass_through(id, len, dev->current_cdb, cdbufferb + dev->data_pos); + dev->data_pos += *len; if (!ret) return 0; - if (cdrom[id].sector_pos > (cdsize - 1)) { + if (dev->sector_pos > (cdsize - 1)) { /* cdrom_log("CD-ROM %i: Trying to read beyond the end of disc\n", id); */ cdrom_lba_out_of_range(id); return 0; } - cdrom[id].old_len = *len; + dev->old_len = *len; } else { - if (cdrom[id].sector_pos > (cdrom_drives[id].handler->size(id) - 1)) { + if (dev->sector_pos > (cdrom_drives[id].handler->size(id) - 1)) { /* cdrom_log("CD-ROM %i: Trying to read beyond the end of disc\n", id); */ cdrom_lba_out_of_range(id); return 0; } - cdrom[id].old_len = 0; + dev->old_len = 0; *len = 0; - for (i = 0; i < cdrom[id].requested_blocks; i++) { - ret = cdrom_drives[id].handler->readsector_raw(id, cdbufferb + cdrom[id].data_pos, cdrom[id].sector_pos + i, msf, type, flags, &temp_len); + for (i = 0; i < dev->requested_blocks; i++) { + ret = cdrom_drives[id].handler->readsector_raw(id, cdbufferb + dev->data_pos, dev->sector_pos + i, msf, type, flags, &temp_len); - last_valid_data_pos = cdrom[id].data_pos; + last_valid_data_pos = dev->data_pos; - cdrom[id].data_pos += temp_len; - cdrom[id].old_len += temp_len; + dev->data_pos += temp_len; + dev->old_len += temp_len; *len += temp_len; @@ -1116,6 +1274,8 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, uint32_t *len) int cdrom_read_blocks(uint8_t id, uint32_t *len, int first_batch) { + cdrom_t *dev = cdrom[id]; + int ret = 0; int msf = 0; @@ -1123,41 +1283,41 @@ int cdrom_read_blocks(uint8_t id, uint32_t *len, int first_batch) int type = 0; int flags = 0; - if (cdrom[id].current_cdb[0] == 0xb9) + if (dev->current_cdb[0] == 0xb9) msf = 1; - if ((cdrom[id].current_cdb[0] == 0xb9) || (cdrom[id].current_cdb[0] == 0xbe)) { - type = (cdrom[id].current_cdb[1] >> 2) & 7; - flags = cdrom[id].current_cdb[9] | (((uint32_t) cdrom[id].current_cdb[10]) << 8); + if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) { + type = (dev->current_cdb[1] >> 2) & 7; + flags = dev->current_cdb[9] | (((uint32_t) dev->current_cdb[10]) << 8); } else { type = 8; flags = 0x10; } - cdrom[id].data_pos = 0; - - if (!cdrom[id].sector_len) { + dev->data_pos = 0; + + if (!dev->sector_len) { cdrom_command_complete(id); return -1; } - cdrom_log("Reading %i blocks starting from %i...\n", cdrom[id].requested_blocks, cdrom[id].sector_pos); + cdrom_log("Reading %i blocks starting from %i...\n", dev->requested_blocks, dev->sector_pos); - cdrom_update_cdb(cdrom[id].current_cdb, cdrom[id].sector_pos, cdrom[id].requested_blocks); + cdrom_update_cdb(dev->current_cdb, dev->sector_pos, dev->requested_blocks); ret = cdrom_read_data(id, msf, type, flags, len); cdrom_log("Read %i bytes of blocks...\n", *len); - if (!ret || ((cdrom[id].old_len != *len) && !first_batch)) { - if ((cdrom[id].old_len != *len) && !first_batch) + if (!ret || ((dev->old_len != *len) && !first_batch)) { + if ((dev->old_len != *len) && !first_batch) cdrom_illegal_mode(id); return 0; } - cdrom[id].sector_pos += cdrom[id].requested_blocks; - cdrom[id].sector_len -= cdrom[id].requested_blocks; + dev->sector_pos += dev->requested_blocks; + dev->sector_len -= dev->requested_blocks; return 1; } @@ -1273,7 +1433,9 @@ static int cdrom_read_dvd_structure(uint8_t id, int format, const uint8_t *packe void cdrom_insert(uint8_t id) { - cdrom[id].unit_attention = 1; + cdrom_t *dev = cdrom[id]; + + dev->unit_attention = 1; } /*SCSI Sense Initialization*/ @@ -1286,11 +1448,13 @@ void cdrom_sense_code_ok(uint8_t id) int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) { + cdrom_t *dev = cdrom[id]; + int ready = 0; if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { - if (((cdrom[id].request_length >> 5) & 7) != cdrom_drives[id].scsi_device_lun) { - cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", id, ((cdrom[id].request_length >> 5) & 7)); + if (((dev->request_length >> 5) & 7) != cdrom_drives[id].scsi_device_lun) { + cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", id, ((dev->request_length >> 5) & 7)); cdrom_invalid_lun(id); return 0; } @@ -1329,25 +1493,25 @@ skip_ready_check: /* If the drive is not ready, there is no reason to keep the UNIT ATTENTION condition present, as we only use it to mark disc changes. */ - if (!ready && cdrom[id].unit_attention) - cdrom[id].unit_attention = 0; + if (!ready && dev->unit_attention) + dev->unit_attention = 0; /* If the UNIT ATTENTION condition is set and the command does not allow execution under it, error out and report the condition. */ - if (cdrom[id].unit_attention == 1) { + if (dev->unit_attention == 1) { /* Only increment the unit attention phase if the command can not pass through it. */ if (!(cdrom_command_flags[cdb[0]] & ALLOW_UA)) { /* cdrom_log("CD-ROM %i: Unit attention now 2\n", id); */ - cdrom[id].unit_attention = 2; + dev->unit_attention = 2; cdrom_log("CD-ROM %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", id, cdb[0]); cdrom_unit_attention(id); return 0; } } - else if (cdrom[id].unit_attention == 2) { + else if (dev->unit_attention == 2) { if (cdb[0] != GPCMD_REQUEST_SENSE) { /* cdrom_log("CD-ROM %i: Unit attention now 0\n", id); */ - cdrom[id].unit_attention = 0; + dev->unit_attention = 0; } } @@ -1358,9 +1522,9 @@ skip_ready_check: /* Next it's time for NOT READY. */ if (!ready) - cdrom[id].media_status = MEC_MEDIA_REMOVAL; + dev->media_status = MEC_MEDIA_REMOVAL; else - cdrom[id].media_status = (cdrom[id].unit_attention) ? MEC_NEW_MEDIA : MEC_NO_CHANGE; + dev->media_status = (dev->unit_attention) ? MEC_NEW_MEDIA : MEC_NO_CHANGE; if ((cdrom_command_flags[cdb[0]] & CHECK_READY) && !ready) { cdrom_log("CD-ROM %i: Not ready (%02X)\n", id, cdb[0]); @@ -1375,46 +1539,58 @@ skip_ready_check: void cdrom_clear_callback(uint8_t channel) { + cdrom_t *dev; + uint8_t id = atapi_cdrom_drives[channel]; + dev = cdrom[id]; + if (id < CDROM_NUM) { - cdrom[id].callback = 0LL; + dev->callback = 0LL; cdrom_set_callback(id); } } static void cdrom_seek(uint8_t id, uint32_t pos) { + cdrom_t *dev = cdrom[id]; + /* cdrom_log("CD-ROM %i: Seek %08X\n", id, pos); */ - cdrom[id].seek_pos = pos; + dev->seek_pos = pos; if (cdrom_drives[id].handler->stop) cdrom_drives[id].handler->stop(id); } static void cdrom_rezero(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (cdrom_drives[id].handler->stop) cdrom_drives[id].handler->stop(id); - cdrom[id].sector_pos = cdrom[id].sector_len = 0; + dev->sector_pos = dev->sector_len = 0; cdrom_seek(id, 0); } void cdrom_reset(uint8_t id) { + cdrom_t *dev = cdrom[id]; + cdrom_rezero(id); - cdrom[id].status = 0; - cdrom[id].callback = 0LL; + dev->status = 0; + dev->callback = 0LL; cdrom_set_callback(id); - cdrom[id].packet_status = 0xff; - cdrom[id].unit_attention = 0; + dev->packet_status = 0xff; + dev->unit_attention = 0; } int cdrom_playing_completed(uint8_t id) { - cdrom[id].prev_status = cdrom[id].cd_status; - cdrom[id].cd_status = cdrom_drives[id].handler->status(id); - if (((cdrom[id].prev_status == CD_STATUS_PLAYING) || (cdrom[id].prev_status == CD_STATUS_PAUSED)) && ((cdrom[id].cd_status != CD_STATUS_PLAYING) && (cdrom[id].cd_status != CD_STATUS_PAUSED))) + cdrom_t *dev = cdrom[id]; + + dev->prev_status = dev->cd_status; + dev->cd_status = cdrom_drives[id].handler->status(id); + if (((dev->prev_status == CD_STATUS_PLAYING) || (dev->prev_status == CD_STATUS_PAUSED)) && ((dev->cd_status != CD_STATUS_PLAYING) && (dev->cd_status != CD_STATUS_PAUSED))) return 1; else return 0; @@ -1422,26 +1598,28 @@ int cdrom_playing_completed(uint8_t id) void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) { + cdrom_t *dev = cdrom[id]; + /*Will return 18 bytes of 0*/ if (alloc_length != 0) { memset(buffer, 0, alloc_length); - memcpy(buffer, cdrom[id].sense, alloc_length); + memcpy(buffer, dev->sense, alloc_length); } buffer[0] = 0x70; - if ((cdrom_sense_key > 0) && ((cdrom[id].cd_status < CD_STATUS_PLAYING) || (cdrom[id].cd_status == CD_STATUS_STOPPED)) && cdrom_playing_completed(id)) { + if ((cdrom_sense_key > 0) && ((dev->cd_status < CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_STOPPED)) && cdrom_playing_completed(id)) { buffer[2]=SENSE_ILLEGAL_REQUEST; buffer[12]=ASC_AUDIO_PLAY_OPERATION; buffer[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED; } - else if ((cdrom_sense_key == 0) && (cdrom[id].cd_status >= CD_STATUS_PLAYING) && (cdrom[id].cd_status != CD_STATUS_STOPPED)) { + else if ((cdrom_sense_key == 0) && (dev->cd_status >= CD_STATUS_PLAYING) && (dev->cd_status != CD_STATUS_STOPPED)) { buffer[2]=SENSE_ILLEGAL_REQUEST; buffer[12]=ASC_AUDIO_PLAY_OPERATION; - buffer[13]=(cdrom[id].cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; + buffer[13]=(dev->cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; } else { - if (cdrom[id].unit_attention && (cdrom_sense_key == 0)) { + if (dev->unit_attention && (cdrom_sense_key == 0)) { buffer[2]=SENSE_UNIT_ATTENTION; buffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; buffer[13]=0; @@ -1453,7 +1631,7 @@ void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) if (buffer[2] == SENSE_UNIT_ATTENTION) { /* If the last remaining sense is unit attention, clear that condition. */ - cdrom[id].unit_attention = 0; + dev->unit_attention = 0; } /* Clear the sense stuff as per the spec. */ @@ -1462,6 +1640,8 @@ void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length) { + cdrom_t *dev = cdrom[id]; + int ready = 0; if (cdrom_drives[id].handler->medium_changed(id)) @@ -1469,11 +1649,11 @@ void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_len ready = cdrom_drives[id].handler->ready(id); - if (!ready && cdrom[id].unit_attention) { + if (!ready && dev->unit_attention) { /* If the drive is not ready, there is no reason to keep the UNIT ATTENTION condition present, as we only use it to mark disc changes. */ - cdrom[id].unit_attention = 0; + dev->unit_attention = 0; } /* Do *NOT* advance the unit attention phase. */ @@ -1496,12 +1676,16 @@ void cdrom_set_buf_len(uint8_t id, int32_t *BufLen, uint32_t *src_len) void cdrom_buf_alloc(uint8_t id, uint32_t len) { + cdrom_t *dev = cdrom[id]; + cdrom_log("CD-ROM %i: Allocated buffer length: %i\n", id, len); cdbufferb = (uint8_t *) malloc(len); } void cdrom_buf_free(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (cdbufferb) { cdrom_log("CD-ROM %i: Freeing buffer...\n", id); free(cdbufferb); @@ -1535,16 +1719,18 @@ void cdrom_command(uint8_t id, uint8_t *cdb) uint32_t profiles[2] = { MMC_PROFILE_CD_ROM, MMC_PROFILE_DVD_ROM }; uint32_t i = 0; + cdrom_t *dev = cdrom[id]; + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { BufLen = &SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].BufferLength; - cdrom[id].status &= ~ERR_STAT; + dev->status &= ~ERR_STAT; } else { BufLen = &blen; - cdrom[id].error = 0; + dev->error = 0; } - cdrom[id].packet_len = 0; - cdrom[id].request_pos = 0; + dev->packet_len = 0; + dev->request_pos = 0; device_identify[7] = id + 0x30; @@ -1553,15 +1739,15 @@ void cdrom_command(uint8_t id, uint8_t *cdb) device_identify_ex[12] = EMU_VERSION[2]; device_identify_ex[13] = EMU_VERSION[3]; - cdrom[id].data_pos = 0; + dev->data_pos = 0; - memcpy(cdrom[id].current_cdb, cdb, cdrom[id].cdb_len); + memcpy(dev->current_cdb, cdb, dev->cdb_len); - cdrom[id].cd_status = cdrom_drives[id].handler->status(id); + dev->cd_status = cdrom_drives[id].handler->status(id); if (cdb[0] != 0) { - cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", id, cdb[0], cdrom_sense_key, cdrom_asc, cdrom_ascq, cdrom[id].unit_attention); - cdrom_log("CD-ROM %i: Request length: %04X\n", id, cdrom[id].request_length); + cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", id, cdb[0], cdrom_sense_key, cdrom_asc, cdrom_ascq, dev->unit_attention); + cdrom_log("CD-ROM %i: Request length: %04X\n", id, dev->request_length); cdrom_log("CD-ROM %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], @@ -1569,7 +1755,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } msf = cdb[1] & 2; - cdrom[id].sector_len = 0; + dev->sector_len = 0; cdrom_set_phase(id, SCSI_PHASE_STATUS); @@ -1586,7 +1772,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) case GPCMD_REZERO_UNIT: if (cdrom_drives[id].handler->stop) cdrom_drives[id].handler->stop(id); - cdrom[id].sector_pos = cdrom[id].sector_len = 0; + dev->sector_pos = dev->sector_len = 0; cdrom_seek(id, 0); cdrom_set_phase(id, SCSI_PHASE_STATUS); break; @@ -1623,7 +1809,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) break; case GPCMD_READ_TOC_PMA_ATIP: - cdrom[id].toctimes++; + dev->toctimes++; cdrom_set_phase(id, SCSI_PHASE_DATA_IN); @@ -1634,7 +1820,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdrom_buf_alloc(id, 65536); if (cdrom_drives[id].handler->pass_through) { - ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); + ret = cdrom_pass_through(id, &len, dev->current_cdb, cdbufferb); if (!ret) { cdrom_sense_key = cdrom_asc = cdrom_ascq = 0; goto cdrom_readtoc_fallback; @@ -1714,7 +1900,7 @@ cdrom_readtoc_fallback: return; case GPCMD_READ_CD_OLD: - cdrom[id].current_cdb[0] = 0xbe; /* IMPORTANT: Convert the command to new read CD for pass through purposes. */ + dev->current_cdb[0] = 0xbe; /* IMPORTANT: Convert the command to new read CD for pass through purposes. */ case GPCMD_READ_6: case GPCMD_READ_10: case GPCMD_READ_12: @@ -1725,59 +1911,62 @@ cdrom_readtoc_fallback: switch(cdb[0]) { case GPCMD_READ_6: - cdrom[id].sector_len = cdb[4]; - cdrom[id].sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + dev->sector_len = cdb[4]; + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); msf = 0; break; case GPCMD_READ_10: - cdrom[id].sector_len = (cdb[7] << 8) | cdb[8]; - cdrom[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", id, cdrom[id].sector_len, cdrom[id].sector_pos); + dev->sector_len = (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", id, dev->sector_len, dev->sector_pos); msf = 0; break; case GPCMD_READ_12: - cdrom[id].sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - cdrom[id].sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", id, cdrom[id].sector_len, cdrom[id].sector_pos); + dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", id, dev->sector_len, dev->sector_pos); msf = 0; break; case GPCMD_READ_CD_MSF: /* cdrom_log("CD-ROM %i: Read CD MSF: Start MSF %02X%02X%02X End MSF %02X%02X%02X Flags %02X\n", id, cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]); */ alloc_length = 2856; - cdrom[id].sector_len = MSFtoLBA(cdb[6], cdb[7], cdb[8]); - cdrom[id].sector_pos = MSFtoLBA(cdb[3], cdb[4], cdb[5]); + dev->sector_len = MSFtoLBA(cdb[6], cdb[7], cdb[8]); + dev->sector_pos = MSFtoLBA(cdb[3], cdb[4], cdb[5]); - cdrom[id].sector_len -= cdrom[id].sector_pos; - cdrom[id].sector_len++; + dev->sector_len -= dev->sector_pos; + dev->sector_len++; msf = 1; break; case GPCMD_READ_CD_OLD: case GPCMD_READ_CD: /* cdrom_log("CD-ROM %i: Read CD: Start LBA %02X%02X%02X%02X Length %02X%02X%02X Flags %02X\n", id, cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]); */ alloc_length = 2856; - cdrom[id].sector_len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; - cdrom[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + dev->sector_len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; msf = 0; break; } - if (!cdrom[id].sector_len) { + dev->seek_diff = ABS((int) (pos - dev->seek_pos)); + dev->seek_pos = dev->sector_pos; + + if (!dev->sector_len) { cdrom_set_phase(id, SCSI_PHASE_STATUS); /* cdrom_log("CD-ROM %i: All done - callback set\n", id); */ - cdrom[id].packet_status = CDROM_PHASE_COMPLETE; - cdrom[id].callback = 20LL * CDROM_TIME; + dev->packet_status = CDROM_PHASE_COMPLETE; + dev->callback = 20LL * CDROM_TIME; cdrom_set_callback(id); break; } - max_len = cdrom[id].sector_len; - cdrom[id].requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT + max_len = dev->sector_len; + dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT matter anyway, this step should be identical and only the way the read dat is transferred to the host should be different. */ - cdrom[id].packet_len = max_len * alloc_length; - cdrom_buf_alloc(id, cdrom[id].packet_len); + dev->packet_len = max_len * alloc_length; + cdrom_buf_alloc(id, dev->packet_len); ret = cdrom_read_blocks(id, &alloc_length, 1); if (ret <= 0) { @@ -1785,15 +1974,15 @@ cdrom_readtoc_fallback: return; } - cdrom[id].requested_blocks = max_len; - cdrom[id].packet_len = alloc_length; + dev->requested_blocks = max_len; + dev->packet_len = alloc_length; - cdrom_set_buf_len(id, BufLen, &cdrom[id].packet_len); + cdrom_set_buf_len(id, BufLen, &dev->packet_len); - cdrom_data_command_finish(id, alloc_length, alloc_length / cdrom[id].requested_blocks, alloc_length, 0); + cdrom_data_command_finish(id, alloc_length, alloc_length / dev->requested_blocks, alloc_length, 0); - cdrom[id].all_blocks_total = cdrom[id].block_total; - if (cdrom[id].packet_status != CDROM_PHASE_COMPLETE) + dev->all_blocks_total = dev->block_total; + if (dev->packet_status != CDROM_PHASE_COMPLETE) ui_sb_update_icon(SB_CDROM | id, 1); else ui_sb_update_icon(SB_CDROM | id, 0); @@ -1806,18 +1995,18 @@ cdrom_readtoc_fallback: cdrom_buf_alloc(id, 8); if (cdrom_drives[id].handler->pass_through) { - ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); + ret = cdrom_pass_through(id, &len, dev->current_cdb, cdbufferb); if (!ret) { cdrom_buf_free(id); return; } } else { - cdrom[id].sector_len = 1; - cdrom[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4]<<8) | cdb[5]; + dev->sector_len = 1; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4]<<8) | cdb[5]; if (msf) - real_pos = cdrom_lba_to_msf_accurate(cdrom[id].sector_pos); + real_pos = cdrom_lba_to_msf_accurate(dev->sector_pos); else - real_pos = cdrom[id].sector_pos; + real_pos = dev->sector_pos; cdbufferb[0] = 1; /*2048 bytes user data*/ cdbufferb[1] = cdbufferb[2] = cdbufferb[3] = 0; cdbufferb[4] = (real_pos >> 24); @@ -1852,9 +2041,9 @@ cdrom_readtoc_fallback: cdrom_buf_alloc(id, 65536); } - cdrom[id].current_page_code = cdb[2] & 0x3F; + dev->current_page_code = cdb[2] & 0x3F; - if (!(cdrom_mode_sense_page_flags & (1LL << cdrom[id].current_page_code))) { + if (!(cdrom_mode_sense_page_flags & (1LL << dev->current_page_code))) { cdrom_invalid_field(id); cdrom_buf_free(id); return; @@ -1903,10 +2092,10 @@ cdrom_readtoc_fallback: cdrom_set_buf_len(id, BufLen, &len); - cdrom[id].total_length = len; - cdrom[id].do_page_save = cdb[1] & 1; + dev->total_length = len; + dev->do_page_save = cdb[1] & 1; - cdrom[id].current_page_pos = 0; + dev->current_page_pos = 0; cdrom_data_command_finish(id, len, len, len, 1); return; @@ -2051,7 +2240,7 @@ cdrom_readtoc_fallback: if (gesn_cdb->class & (1 << GESN_MEDIA)) { gesn_event_header->notification_class |= GESN_MEDIA; - cdbufferb[4] = cdrom[id].media_status; /* Bits 7-4 = Reserved, Bits 4-1 = Media Status */ + cdbufferb[4] = dev->media_status; /* Bits 7-4 = Reserved, Bits 4-1 = Media Status */ cdbufferb[5] = 1; /* Power Status (1 = Active) */ cdbufferb[6] = 0; cdbufferb[7] = 0; @@ -2079,7 +2268,7 @@ cdrom_readtoc_fallback: cdrom_buf_alloc(id, 65536); if (cdrom_drives[id].handler->pass_through) { - ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); + ret = cdrom_pass_through(id, &len, dev->current_cdb, cdbufferb); if (!ret) { cdrom_buf_free(id); return; @@ -2122,7 +2311,7 @@ cdrom_readtoc_fallback: track |= (uint32_t) cdb[5]; if (cdrom_drives[id].handler->pass_through) { - ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); + ret = cdrom_pass_through(id, &len, dev->current_cdb, cdbufferb); if (!ret) { cdrom_buf_free(id); return; @@ -2200,7 +2389,7 @@ cdrom_readtoc_fallback: if (!cdrom_drives[id].handler->is_track_audio) break; - if ((cdrom_drives[id].host_drive < 1) || (cdrom[id].cd_status <= CD_STATUS_DATA_ONLY) || !cdrom_drives[id].handler->is_track_audio(id, pos, msf)) { + if ((cdrom_drives[id].host_drive < 1) || (dev->cd_status <= CD_STATUS_DATA_ONLY) || !cdrom_drives[id].handler->is_track_audio(id, pos, msf)) { cdrom_illegal_mode(id); break; } @@ -2227,12 +2416,12 @@ cdrom_readtoc_fallback: cdrom_log("CD-ROM %i: Getting page %i (%s)\n", id, cdb[3], msf ? "MSF" : "LBA"); if ((cdrom_drives[id].handler->pass_through) && (cdb[3] != 1)) { - ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); + ret = cdrom_pass_through(id, &len, dev->current_cdb, cdbufferb); if (!ret) { cdrom_buf_free(id); return; } - switch(cdrom[id].cd_status) { + switch(dev->cd_status) { case CD_STATUS_PLAYING: cdbufferb[1] = 0x11; break; @@ -2289,7 +2478,7 @@ cdrom_readtoc_fallback: cdbufferb[pos++] = cdb[3] & 3; /*Format code*/ if (cdb[3] == 1) { cdbufferb[1] = cdrom_drives[id].handler->getcurrentsubchannel(id, &cdbufferb[5], msf); - switch(cdrom[id].cd_status) { + switch(dev->cd_status) { case CD_STATUS_PLAYING: cdbufferb[1] = 0x11; break; @@ -2324,7 +2513,7 @@ cdrom_readtoc_fallback: cdrom_buf_alloc(id, alloc_length); if (cdrom_drives[id].handler->pass_through) { - ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); + ret = cdrom_pass_through(id, &len, dev->current_cdb, cdbufferb); if (!ret) { cdrom_buf_free(id); return; @@ -2526,6 +2715,7 @@ atapi_out: pos = (cdb[2] << 24) | (cdb[3]<<16) | (cdb[4]<<8) | cdb[5]; break; } + dev->seek_diff = ABS((int) (pos - dev->seek_pos)); cdrom_seek(id, pos); cdrom_command_complete(id); break; @@ -2535,7 +2725,7 @@ atapi_out: cdrom_buf_alloc(id, 8); - if (cdrom_read_capacity(id, cdrom[id].current_cdb, cdbufferb, &len) == 0) { + if (cdrom_read_capacity(id, dev->current_cdb, cdbufferb, &len) == 0) { cdrom_buf_free(id); return; } @@ -2562,7 +2752,7 @@ atapi_out: break; } - /* cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", cdrom[id].phase, cdrom[id].request_length); */ + /* cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", dev->phase, dev->request_length); */ if (cdrom_atapi_phase_to_scsi(id) == SCSI_PHASE_STATUS) cdrom_buf_free(id); @@ -2571,6 +2761,8 @@ atapi_out: /* The command second phase function, needed for Mode Select. */ uint8_t cdrom_phase_data_out(uint8_t id) { + cdrom_t *dev = cdrom[id]; + uint16_t block_desc_len; uint16_t pos; @@ -2583,20 +2775,20 @@ uint8_t cdrom_phase_data_out(uint8_t id) FILE *f; - switch(cdrom[id].current_cdb[0]) { + switch(dev->current_cdb[0]) { case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: f = nvr_fopen(L"modeselect.bin", L"wb"); - fwrite(cdbufferb, 1, cdrom[id].total_length, f); + fwrite(cdbufferb, 1, dev->total_length, f); fclose(f); - if (cdrom[id].current_cdb[0] == GPCMD_MODE_SELECT_10) + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) hdr_len = 8; else hdr_len = 4; if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { - if (cdrom[id].current_cdb[0] == GPCMD_MODE_SELECT_6) { + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { block_desc_len = cdbufferb[2]; block_desc_len <<= 8; block_desc_len |= cdbufferb[3]; @@ -2641,10 +2833,10 @@ uint8_t cdrom_phase_data_out(uint8_t id) val = cdrom_mode_sense_pages_default_scsi.pages[page][0] & 0x80; else val = cdrom_mode_sense_pages_default.pages[page][0] & 0x80; - if (cdrom[id].do_page_save && val) + if (dev->do_page_save && val) cdrom_mode_sense_save(id); - if (pos >= cdrom[id].total_length) + if (pos >= dev->total_length) break; } @@ -2661,6 +2853,8 @@ uint8_t cdrom_phase_data_out(uint8_t id) /* This is the general ATAPI PIO request function. */ void cdrom_pio_request(uint8_t id, uint8_t out) { + cdrom_t *dev = cdrom[id]; + int old_pos = 0; int ret = 0; @@ -2669,12 +2863,12 @@ void cdrom_pio_request(uint8_t id, uint8_t out) ide_irq_lower(&(ide_drives[cdrom_drives[id].ide_channel])); } - cdrom[id].status = BUSY_STAT; + dev->status = BUSY_STAT; - if (cdrom[id].pos >= cdrom[id].packet_len) { - cdrom_log("CD-ROM %i: %i bytes %s, command done\n", id, cdrom[id].pos, out ? "written" : "read"); + if (dev->pos >= dev->packet_len) { + cdrom_log("CD-ROM %i: %i bytes %s, command done\n", id, dev->pos, out ? "written" : "read"); - cdrom[id].pos = cdrom[id].request_pos = 0; + dev->pos = dev->request_pos = 0; if (out) { ret = cdrom_phase_data_out(id); /* If ret = 0 (phase 1 error), then we do not do anything else other than @@ -2686,23 +2880,23 @@ void cdrom_pio_request(uint8_t id, uint8_t out) cdrom_command_complete(id); cdrom_buf_free(id); } else { - cdrom_log("CD-ROM %i: %i bytes %s, %i bytes are still left\n", id, cdrom[id].pos, out ? "written" : "read", cdrom[id].packet_len - cdrom[id].pos); + cdrom_log("CD-ROM %i: %i bytes %s, %i bytes are still left\n", id, dev->pos, out ? "written" : "read", dev->packet_len - dev->pos); /* Make sure to keep pos, and reset request_pos to 0. */ /* Also make sure to not reset total_read. */ /* If less than (packet length) bytes are remaining, update packet length accordingly. */ - if ((cdrom[id].packet_len - cdrom[id].pos) < (cdrom[id].max_transfer_len)) - cdrom[id].max_transfer_len = cdrom[id].packet_len - cdrom[id].pos; - cdrom_log("CD-ROM %i: Packet length %i, request length %i\n", id, cdrom[id].packet_len, cdrom[id].max_transfer_len); + if ((dev->packet_len - dev->pos) < (dev->max_transfer_len)) + dev->max_transfer_len = dev->packet_len - dev->pos; + cdrom_log("CD-ROM %i: Packet length %i, request length %i\n", id, dev->packet_len, dev->max_transfer_len); - old_pos = cdrom[id].pos; - cdrom[id].packet_status = out ? CDROM_PHASE_DATA_OUT : CDROM_PHASE_DATA_IN; + old_pos = dev->pos; + dev->packet_status = out ? CDROM_PHASE_DATA_OUT : CDROM_PHASE_DATA_IN; cdrom_command_common(id); - cdrom[id].pos = old_pos; + dev->pos = old_pos; - cdrom[id].request_pos = 0; + dev->request_pos = 0; } } @@ -2710,13 +2904,17 @@ void cdrom_phase_callback(uint8_t id); int cdrom_read_from_ide_dma(uint8_t channel) { + cdrom_t *dev; + uint8_t id = atapi_cdrom_drives[channel]; if (id > CDROM_NUM) return 0; + dev = cdrom[id]; + if (ide_bus_master_write) { - if (ide_bus_master_write(channel >> 1, cdbufferb, cdrom[id].packet_len)) + if (ide_bus_master_write(channel >> 1, cdbufferb, dev->packet_len)) return 0; else return 1; @@ -2728,12 +2926,16 @@ int cdrom_read_from_ide_dma(uint8_t channel) int cdrom_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) { + cdrom_t *dev; + uint8_t id = scsi_cdrom_drives[scsi_id][scsi_lun]; int32_t *BufLen = &SCSIDevices[scsi_id][scsi_lun].BufferLength; if (id > CDROM_NUM) return 0; + dev = cdrom[id]; + cdrom_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, *BufLen); memcpy(cdbufferb, SCSIDevices[scsi_id][scsi_lun].CmdBuffer, *BufLen); return 1; @@ -2747,6 +2949,8 @@ void cdrom_irq_raise(uint8_t id) int cdrom_read_from_dma(uint8_t id) { + cdrom_t *dev = cdrom[id]; + int32_t *BufLen = &SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].BufferLength; int ret = 0; @@ -2762,15 +2966,15 @@ int cdrom_read_from_dma(uint8_t id) if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) cdrom_log("CD-ROM %i: SCSI Input data length: %i\n", id, *BufLen); else - cdrom_log("CD-ROM %i: ATAPI Input data length: %i\n", id, cdrom[id].packet_len); + cdrom_log("CD-ROM %i: ATAPI Input data length: %i\n", id, dev->packet_len); ret = cdrom_phase_data_out(id); if (ret || (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)) { cdrom_buf_free(id); - cdrom[id].packet_status = CDROM_PHASE_COMPLETE; - cdrom[id].status = READY_STAT; - cdrom[id].phase = 3; + dev->packet_status = CDROM_PHASE_COMPLETE; + dev->status = READY_STAT; + dev->phase = 3; ui_sb_update_icon(SB_CDROM | id, 0); cdrom_irq_raise(id); if (ret) @@ -2783,13 +2987,17 @@ int cdrom_read_from_dma(uint8_t id) int cdrom_write_to_ide_dma(uint8_t channel) { + cdrom_t *dev; + uint8_t id = atapi_cdrom_drives[channel]; if (id > CDROM_NUM) return 0; + dev = cdrom[id]; + if (ide_bus_master_read) { - if (ide_bus_master_read(channel >> 1, cdbufferb, cdrom[id].packet_len)) + if (ide_bus_master_read(channel >> 1, cdbufferb, dev->packet_len)) return 0; else return 1; @@ -2799,12 +3007,16 @@ int cdrom_write_to_ide_dma(uint8_t channel) int cdrom_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) { + cdrom_t *dev; + uint8_t id = scsi_cdrom_drives[scsi_id][scsi_lun]; int32_t *BufLen = &SCSIDevices[scsi_id][scsi_lun].BufferLength; if (id > CDROM_NUM) return 0; + dev = cdrom[id]; + cdrom_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, *BufLen); memcpy(SCSIDevices[scsi_id][scsi_lun].CmdBuffer, cdbufferb, *BufLen); cdrom_log("CD-ROM %i: Data from CD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdbufferb[0], cdbufferb[1], cdbufferb[2], cdbufferb[3], cdbufferb[4], cdbufferb[5], cdbufferb[6], cdbufferb[7]); @@ -2814,6 +3026,8 @@ int cdrom_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) int cdrom_write_to_dma(uint8_t id) { + cdrom_t *dev = cdrom[id]; + int ret = 0; if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { @@ -2824,9 +3038,9 @@ int cdrom_write_to_dma(uint8_t id) if (ret || (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)) { cdrom_buf_free(id); - cdrom[id].packet_status = CDROM_PHASE_COMPLETE; - cdrom[id].status = READY_STAT; - cdrom[id].phase = 3; + dev->packet_status = CDROM_PHASE_COMPLETE; + dev->status = READY_STAT; + dev->phase = 3; ui_sb_update_icon(SB_CDROM | id, 0); cdrom_irq_raise(id); if (ret) @@ -2840,31 +3054,33 @@ int cdrom_write_to_dma(uint8_t id) /* If the result is 1, issue an IRQ, otherwise not. */ void cdrom_phase_callback(uint8_t id) { - switch(cdrom[id].packet_status) { + cdrom_t *dev = cdrom[id]; + + switch(dev->packet_status) { case CDROM_PHASE_IDLE: cdrom_log("CD-ROM %i: CDROM_PHASE_IDLE\n", id); - cdrom[id].pos=0; - cdrom[id].phase = 1; - cdrom[id].status = READY_STAT | DRQ_STAT | (cdrom[id].status & ERR_STAT); + dev->pos=0; + dev->phase = 1; + dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); return; case CDROM_PHASE_COMMAND: cdrom_log("CD-ROM %i: CDROM_PHASE_COMMAND\n", id); - cdrom[id].status = BUSY_STAT | (cdrom[id].status &ERR_STAT); - memcpy(cdrom[id].atapi_cdb, cdbufferb, cdrom[id].cdb_len); - cdrom_command(id, cdrom[id].atapi_cdb); + dev->status = BUSY_STAT | (dev->status &ERR_STAT); + memcpy(dev->atapi_cdb, cdbufferb, dev->cdb_len); + cdrom_command(id, dev->atapi_cdb); return; case CDROM_PHASE_COMPLETE: cdrom_log("CD-ROM %i: CDROM_PHASE_COMPLETE\n", id); - cdrom[id].status = READY_STAT; - cdrom[id].phase = 3; - cdrom[id].packet_status = 0xFF; + dev->status = READY_STAT; + dev->phase = 3; + dev->packet_status = 0xFF; ui_sb_update_icon(SB_CDROM | id, 0); cdrom_irq_raise(id); return; case CDROM_PHASE_DATA_OUT: cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT\n", id); - cdrom[id].status = READY_STAT | DRQ_STAT | (cdrom[id].status & ERR_STAT); - cdrom[id].phase = 0; + dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); + dev->phase = 0; cdrom_irq_raise(id); return; case CDROM_PHASE_DATA_OUT_DMA: @@ -2873,8 +3089,8 @@ void cdrom_phase_callback(uint8_t id) return; case CDROM_PHASE_DATA_IN: cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN\n", id); - cdrom[id].status = READY_STAT | DRQ_STAT | (cdrom[id].status & ERR_STAT); - cdrom[id].phase = 2; + dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); + dev->phase = 2; cdrom_irq_raise(id); return; case CDROM_PHASE_DATA_IN_DMA: @@ -2883,8 +3099,8 @@ void cdrom_phase_callback(uint8_t id) return; case CDROM_PHASE_ERROR: cdrom_log("CD-ROM %i: CDROM_PHASE_ERROR\n", id); - cdrom[id].status = READY_STAT | ERR_STAT; - cdrom[id].phase = 3; + dev->status = READY_STAT | ERR_STAT; + dev->phase = 3; cdrom_irq_raise(id); ui_sb_update_icon(SB_CDROM | id, 0); return; @@ -2894,6 +3110,8 @@ void cdrom_phase_callback(uint8_t id) /* Reimplement as 8-bit due to reimplementation of IDE data read and write. */ uint32_t cdrom_read(uint8_t channel, int length) { + cdrom_t *dev; + uint16_t *cdbufferw; uint32_t *cdbufferl; @@ -2904,6 +3122,8 @@ uint32_t cdrom_read(uint8_t channel, int length) if (id > CDROM_NUM) return 0; + dev = cdrom[id]; + cdbufferw = (uint16_t *) cdbufferb; cdbufferl = (uint32_t *) cdbufferb; @@ -2915,34 +3135,34 @@ uint32_t cdrom_read(uint8_t channel, int length) (which is 1 sector = 2048 bytes). */ switch(length) { case 1: - temp = (cdrom[id].pos < cdrom[id].packet_len) ? cdbufferb[cdrom[id].pos] : 0; - cdrom[id].pos++; - cdrom[id].request_pos++; + temp = (dev->pos < dev->packet_len) ? cdbufferb[dev->pos] : 0; + dev->pos++; + dev->request_pos++; break; case 2: - temp = (cdrom[id].pos < cdrom[id].packet_len) ? cdbufferw[cdrom[id].pos >> 1] : 0; - cdrom[id].pos += 2; - cdrom[id].request_pos += 2; + temp = (dev->pos < dev->packet_len) ? cdbufferw[dev->pos >> 1] : 0; + dev->pos += 2; + dev->request_pos += 2; break; case 4: - temp = (cdrom[id].pos < cdrom[id].packet_len) ? cdbufferl[cdrom[id].pos >> 2] : 0; - cdrom[id].pos += 4; - cdrom[id].request_pos += 4; + temp = (dev->pos < dev->packet_len) ? cdbufferl[dev->pos >> 2] : 0; + dev->pos += 4; + dev->request_pos += 4; break; default: return 0; } - if (cdrom[id].packet_status == CDROM_PHASE_DATA_IN) { - if ((cdrom[id].request_pos >= cdrom[id].max_transfer_len) || (cdrom[id].pos >= cdrom[id].packet_len)) { + if (dev->packet_status == CDROM_PHASE_DATA_IN) { + if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { /* Time for a DRQ. */ // cdrom_log("CD-ROM %i: Issuing read callback\n", id); cdrom_pio_request(id, 0); } - // cdrom_log("CD-ROM %i: Returning: %02X (buffer position: %i, request position: %i)\n", id, temp, cdrom[id].pos, cdrom[id].request_pos); + // cdrom_log("CD-ROM %i: Returning: %02X (buffer position: %i, request position: %i)\n", id, temp, dev->pos, dev->request_pos); return temp; } else { - // cdrom_log("CD-ROM %i: Returning zero (buffer position: %i, request position: %i)\n", id, cdrom[id].pos, cdrom[id].request_pos); + // cdrom_log("CD-ROM %i: Returning zero (buffer position: %i, request position: %i)\n", id, dev->pos, dev->request_pos); return 0; } } @@ -2950,6 +3170,8 @@ uint32_t cdrom_read(uint8_t channel, int length) /* Reimplement as 8-bit due to reimplementation of IDE data read and write. */ void cdrom_write(uint8_t channel, uint32_t val, int length) { + cdrom_t *dev; + uint16_t *cdbufferw; uint32_t *cdbufferl; @@ -2958,9 +3180,11 @@ void cdrom_write(uint8_t channel, uint32_t val, int length) if (id > CDROM_NUM) return; - if (cdrom[id].packet_status == CDROM_PHASE_IDLE) { + dev = cdrom[id]; + + if (dev->packet_status == CDROM_PHASE_IDLE) { if (!cdbufferb) - cdrom_buf_alloc(id, cdrom[id].cdb_len); + cdrom_buf_alloc(id, dev->cdb_len); } cdbufferw = (uint16_t *) cdbufferb; @@ -2971,35 +3195,35 @@ void cdrom_write(uint8_t channel, uint32_t val, int length) switch(length) { case 1: - cdbufferb[cdrom[id].pos] = val & 0xff; - cdrom[id].pos++; - cdrom[id].request_pos++; + cdbufferb[dev->pos] = val & 0xff; + dev->pos++; + dev->request_pos++; break; case 2: - cdbufferw[cdrom[id].pos >> 1] = val & 0xffff; - cdrom[id].pos += 2; - cdrom[id].request_pos += 2; + cdbufferw[dev->pos >> 1] = val & 0xffff; + dev->pos += 2; + dev->request_pos += 2; break; case 4: - cdbufferl[cdrom[id].pos >> 2] = val; - cdrom[id].pos += 4; - cdrom[id].request_pos += 4; + cdbufferl[dev->pos >> 2] = val; + dev->pos += 4; + dev->request_pos += 4; break; default: return; } - if (cdrom[id].packet_status == CDROM_PHASE_DATA_OUT) { - if ((cdrom[id].request_pos >= cdrom[id].max_transfer_len) || (cdrom[id].pos >= cdrom[id].packet_len)) { + if (dev->packet_status == CDROM_PHASE_DATA_OUT) { + if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { /* Time for a DRQ. */ cdrom_pio_request(id, 1); } return; - } else if (cdrom[id].packet_status == CDROM_PHASE_IDLE) { - if (cdrom[id].pos >= cdrom[id].cdb_len) { - cdrom[id].pos=0; - cdrom[id].status = BUSY_STAT; - cdrom[id].packet_status = CDROM_PHASE_COMMAND; + } else if (dev->packet_status == CDROM_PHASE_IDLE) { + if (dev->pos >= dev->cdb_len) { + dev->pos=0; + dev->status = BUSY_STAT; + dev->packet_status = CDROM_PHASE_COMMAND; timer_process(); cdrom_phase_callback(id); timer_update_outstanding(); @@ -3008,21 +3232,6 @@ void cdrom_write(uint8_t channel, uint32_t val, int length) } } -void cdrom_hard_reset(void) -{ - int i = 0; - - for (i=0; i= 'A') && (cdrom_drives[i].host_drive <= 'Z')) - ioctl_reset(i); - - cdrom_mode_sense_load(i); - } -} - - /* Peform a master init on the entire module. */ void cdrom_global_init(void) @@ -3043,21 +3252,31 @@ cdrom_global_init(void) void -cdrom_global_reset(void) +cdrom_hard_reset(void) { int c; - for (c=0; c='A') && (cdrom_drives[c].host_drive <= 'Z')) - ioctl_open(c, cdrom_drives[c].host_drive); - else - cdrom_null_open(c, cdrom_drives[c].host_drive); + for (c=0; c='A') && (cdrom_drives[c].host_drive <= 'Z')) { + ioctl_open(c, cdrom_drives[c].host_drive); + ioctl_reset(c); + } else + cdrom_null_open(c, cdrom_drives[c].host_drive); + } + + cdrom_mode_sense_load(c); } } diff --git a/src/cdrom/cdrom.h b/src/cdrom/cdrom.h index d463e8a25..f6a21402a 100644 --- a/src/cdrom/cdrom.h +++ b/src/cdrom/cdrom.h @@ -9,7 +9,7 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)cdrom.h 1.0.6 2018/03/15 + * Version: @(#)cdrom.h 1.0.8 2018/03/17 * * Author: Miran Grca, * @@ -121,6 +121,7 @@ typedef struct { int callback; int data_pos; + uint32_t seek_diff; int cdb_len_setting; int cdb_len; @@ -150,6 +151,20 @@ typedef struct { int init_length; int16_t cd_buffer[BUF_SIZE]; + + uint8_t rcbuf[16]; + uint8_t sub_q_data_format[16]; + uint8_t sub_q_channel_data[256]; + int last_subchannel_pos; + + uint32_t cd_end; + uint32_t cdrom_capacity; + + int cd_buflen; + int cd_state; + + int handler_inited; + int disc_changed; } cdrom_t; typedef struct { @@ -177,52 +192,31 @@ typedef struct { typedef struct { int image_is_iso; - - uint32_t last_block; - uint32_t cdrom_capacity; - int image_inited; wchar_t image_path[1024]; - wchar_t prev_image_path[1024]; + wchar_t *prev_image_path; FILE* image; - int image_changed; - - int cd_state; - uint32_t cd_pos; - uint32_t cd_end; - int cd_buflen; } cdrom_image_t; typedef struct { - uint32_t last_block; - uint32_t cdrom_capacity; - int ioctl_inited; char ioctl_path[8]; - int tocvalid; - int cd_state; - uint32_t cd_end; - int cd_buflen; int actual_requested_blocks; int last_track_pos; int last_track_nr; int capacity_read; - uint8_t rcbuf[16]; - uint8_t sub_q_data_format[16]; - uint8_t sub_q_channel_data[256]; - int last_subchannel_pos; } cdrom_ioctl_t; -extern cdrom_t cdrom[CDROM_NUM]; +extern cdrom_t *cdrom[CDROM_NUM]; extern cdrom_drive_t cdrom_drives[CDROM_NUM]; -extern uint8_t atapi_cdrom_drives[8]; -extern uint8_t scsi_cdrom_drives[16][8]; extern cdrom_image_t cdrom_image[CDROM_NUM]; extern cdrom_ioctl_t cdrom_ioctl[CDROM_NUM]; +extern uint8_t atapi_cdrom_drives[8]; +extern uint8_t scsi_cdrom_drives[16][8]; -#define cdrom_sense_error cdrom[id].sense[0] -#define cdrom_sense_key cdrom[id].sense[2] -#define cdrom_asc cdrom[id].sense[12] -#define cdrom_ascq cdrom[id].sense[13] +#define cdrom_sense_error cdrom[id]->sense[0] +#define cdrom_sense_key cdrom[id]->sense[2] +#define cdrom_asc cdrom[id]->sense[12] +#define cdrom_ascq cdrom[id]->sense[13] #define cdrom_drive cdrom_drives[id].host_drive @@ -247,6 +241,7 @@ extern uint32_t cdrom_read(uint8_t channel, int length); extern void cdrom_write(uint8_t channel, uint32_t val, int length); extern int cdrom_lba_to_msf_accurate(int lba); +extern void cdrom_destroy_drives(void); extern void cdrom_close(uint8_t id); extern void cdrom_reset(uint8_t id); diff --git a/src/cdrom/cdrom_image.cc b/src/cdrom/cdrom_image.cc index f8e32c75c..afd335497 100644 --- a/src/cdrom/cdrom_image.cc +++ b/src/cdrom/cdrom_image.cc @@ -66,51 +66,56 @@ void image_close(uint8_t id); void image_audio_callback(uint8_t id, int16_t *output, int len) { - if (!cdrom_drives[id].sound_on || (cdrom_image[id].cd_state != CD_PLAYING) || cdrom_image[id].image_is_iso) + cdrom_t *dev = cdrom[id]; + + if (!cdrom_drives[id].sound_on || (dev->cd_state != CD_PLAYING) || cdrom_image[id].image_is_iso) { cdrom_image_log("image_audio_callback(i): Not playing\n", id); - if (cdrom_ioctl[id].cd_state == CD_PLAYING) + if (dev->cd_state == CD_PLAYING) { - cdrom[id].seek_pos += (len >> 11); + dev->seek_pos += (len >> 11); } memset(output, 0, len * 2); return; } - while (cdrom_image[id].cd_buflen < len) + while (dev->cd_buflen < len) { - if (cdrom[id].seek_pos < cdrom_image[id].cd_end) + if (dev->seek_pos < dev->cd_end) { - if (!cdimg[id]->ReadSector((unsigned char*)&cdrom[id].cd_buffer[cdrom_image[id].cd_buflen], true, cdrom[id].seek_pos)) + if (!cdimg[id]->ReadSector((unsigned char*)&dev->cd_buffer[dev->cd_buflen], true, dev->seek_pos)) { - memset(&cdrom[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); - cdrom_image[id].cd_state = CD_STOPPED; - cdrom_image[id].cd_buflen = len; + memset(&dev->cd_buffer[dev->cd_buflen], 0, (BUF_SIZE - dev->cd_buflen) * 2); + dev->cd_state = CD_STOPPED; + dev->cd_buflen = len; } else { - cdrom[id].seek_pos++; - cdrom_image[id].cd_buflen += (RAW_SECTOR_SIZE / 2); + dev->seek_pos++; + dev->cd_buflen += (RAW_SECTOR_SIZE / 2); } } else { - memset(&cdrom[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); - cdrom_image[id].cd_state = CD_STOPPED; - cdrom_image[id].cd_buflen = len; + memset(&dev->cd_buffer[dev->cd_buflen], 0, (BUF_SIZE - dev->cd_buflen) * 2); + dev->cd_state = CD_STOPPED; + dev->cd_buflen = len; } } - memcpy(output, cdrom[id].cd_buffer, len * 2); - memmove(cdrom[id].cd_buffer, &cdrom[id].cd_buffer[len], (BUF_SIZE - len) * 2); - cdrom_image[id].cd_buflen -= len; + memcpy(output, dev->cd_buffer, len * 2); + memmove(dev->cd_buffer, &dev->cd_buffer[len], (BUF_SIZE - len) * 2); + dev->cd_buflen -= len; } void image_audio_stop(uint8_t id) { - cdrom_image[id].cd_state = CD_STOPPED; + cdrom_t *dev = cdrom[id]; + + dev->cd_state = CD_STOPPED; } static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) { + cdrom_t *dev = cdrom[id]; if (!cdimg[id]) return; int number; unsigned char attr; @@ -120,8 +125,8 @@ static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) if (attr == DATA_TRACK) { cdrom_image_log("Can't play data track\n"); - cdrom[id].seek_pos = 0; - cdrom_image[id].cd_state = CD_STOPPED; + dev->seek_pos = 0; + dev->cd_state = CD_STOPPED; return; } cdrom_image_log("Play audio - %08X %08X %i\n", pos, len, ismsf); @@ -141,7 +146,7 @@ static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) if (pos == 0xffffff) { cdrom_image_log("Playing from current position (MSF)\n"); - pos = cdrom[id].seek_pos; + pos = dev->seek_pos; } else { @@ -160,38 +165,46 @@ static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) if (pos == 0xffffffff) { cdrom_image_log("Playing from current position\n"); - pos = cdrom[id].seek_pos; + pos = dev->seek_pos; } len += pos; } - cdrom[id].seek_pos = pos; - cdrom_image[id].cd_end = len; - cdrom_image[id].cd_state = CD_PLAYING; - cdrom_image[id].cd_buflen = 0; + dev->seek_pos = pos; + dev->cd_end = len; + dev->cd_state = CD_PLAYING; + dev->cd_buflen = 0; } static void image_pause(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; - if (cdrom_image[id].cd_state == CD_PLAYING) - cdrom_image[id].cd_state = CD_PAUSED; + if (dev->cd_state == CD_PLAYING) + dev->cd_state = CD_PAUSED; } static void image_resume(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; - if (cdrom_image[id].cd_state == CD_PAUSED) - cdrom_image[id].cd_state = CD_PLAYING; + if (dev->cd_state == CD_PAUSED) + dev->cd_state = CD_PLAYING; } static void image_stop(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; - cdrom_image[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; } static int image_ready(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (!cdimg[id]) return 0; @@ -203,9 +216,9 @@ static int image_ready(uint8_t id) return 1; } - if (cdrom_image[id].image_changed) + if (dev->disc_changed) { - cdrom_image[id].image_changed = 0; + dev->disc_changed = 0; return 1; } @@ -239,6 +252,8 @@ static int image_get_last_block(uint8_t id, UNUSED(uint8_t starttrack), UNUSED(i static int image_medium_changed(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (!cdimg[id]) return 0; @@ -253,9 +268,9 @@ static int image_medium_changed(uint8_t id) return 1; } - if (cdrom_image[id].image_changed) + if (dev->disc_changed) { - cdrom_image[id].image_changed = 0; + dev->disc_changed = 0; return 1; } @@ -264,11 +279,12 @@ static int image_medium_changed(uint8_t id) static uint8_t image_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) { + cdrom_t *dev = cdrom[id]; if (!cdimg[id]) return 0; uint8_t ret; int pos=0; - uint32_t cdpos = cdrom[id].seek_pos; + uint32_t cdpos = dev->seek_pos; TMSF relPos, absPos; unsigned char attr, track, index; cdimg[id]->GetAudioSub(cdpos, attr, track, index, relPos, absPos); @@ -279,9 +295,9 @@ static uint8_t image_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) } else { - if (cdrom_image[id].cd_state == CD_PLAYING) + if (dev->cd_state == CD_PLAYING) ret = 0x11; - else if (cdrom_image[id].cd_state == CD_PAUSED) + else if (dev->cd_state == CD_PAUSED) ret = 0x12; else ret = 0x13; @@ -819,7 +835,9 @@ read_mode2_xa_form2: static uint32_t image_size(uint8_t id) { - return cdrom_image[id].cdrom_capacity; + cdrom_t *dev = cdrom[id]; + + return dev->cdrom_capacity; } static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) @@ -996,11 +1014,12 @@ static int image_readtoc_raw(uint8_t id, unsigned char *b, int maxlen) static int image_status(uint8_t id) { + cdrom_t *dev = cdrom[id]; if (!cdimg[id]) return CD_STATUS_EMPTY; if (cdrom_image[id].image_is_iso) return CD_STATUS_DATA_ONLY; if (cdimg[id]->HasAudioTracks()) { - switch(cdrom_image[id].cd_state) + switch(dev->cd_state) { case CD_PLAYING: return CD_STATUS_PLAYING; @@ -1021,7 +1040,9 @@ void image_reset(UNUSED(uint8_t id)) void image_close(uint8_t id) { - cdrom_image[id].cd_state = CD_STOPPED; + cdrom_t *dev = cdrom[id]; + + dev->cd_state = CD_STOPPED; if (cdimg[id]) { delete cdimg[id]; @@ -1034,15 +1055,17 @@ static char afn[1024]; int image_open(uint8_t id, wchar_t *fn) { + cdrom_t *dev = cdrom[id]; + if (wcscmp(fn, cdrom_image[id].image_path) != 0) { - cdrom_image[id].image_changed = 1; + dev->disc_changed = 1; } /* Make sure image_changed stays when changing from an image to another image. */ - if (!cdrom_image[id].image_inited && (cdrom_drives[id].host_drive != 200)) cdrom_image[id].image_changed = 0; + if (!dev->handler_inited && (cdrom_drives[id].host_drive != 200)) dev->disc_changed = 0; - if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) + if (!dev->handler_inited || dev->disc_changed) { wcscpy(cdrom_image[id].image_path, fn); } @@ -1064,16 +1087,16 @@ int image_open(uint8_t id, wchar_t *fn) cdrom_set_null_handler(id); return 1; } - cdrom_image[id].cd_state = CD_STOPPED; - cdrom[id].seek_pos = 0; - cdrom_image[id].cd_buflen = 0; - cdrom_image[id].cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0) + 1; + dev->cd_state = CD_STOPPED; + dev->seek_pos = 0; + dev->cd_buflen = 0; + dev->cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0) + 1; cdrom_drives[id].handler = &image_cdrom; - if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) + if (!dev->handler_inited || dev->disc_changed) { - if (!cdrom_image[id].image_inited) - cdrom_image[id].image_inited = 1; + if (!dev->handler_inited) + dev->handler_inited = 1; } return 0; @@ -1081,7 +1104,9 @@ int image_open(uint8_t id, wchar_t *fn) static void image_exit(uint8_t id) { - cdrom_image[id].image_inited = 0; + cdrom_t *dev = cdrom[id]; + + dev->handler_inited = 0; } /* TODO: Check for what data type a mixed CD is. */ diff --git a/src/config.c b/src/config.c index 86e002153..c6d348bc5 100644 --- a/src/config.c +++ b/src/config.c @@ -8,7 +8,7 @@ * * Configuration file handler. * - * Version: @(#)config.c 1.0.44 2018/03/06 + * Version: @(#)config.c 1.0.45 2018/03/17 * * Authors: Sarah Walker, * Miran Grca, @@ -1095,7 +1095,6 @@ load_removable_devices(void) } else #endif wcsncpy(cdrom_image[c].image_path, wp, sizeof_w(cdrom_image[c].image_path)); - wcscpy(cdrom_image[c].prev_image_path, cdrom_image[c].image_path); if (cdrom_drives[c].host_drive < 'A') cdrom_drives[c].host_drive = 0; @@ -1288,7 +1287,6 @@ load_other_removable_devices(void) } else #endif wcsncpy(cdrom_image[c].image_path, wp, sizeof_w(cdrom_image[c].image_path)); - wcscpy(cdrom_image[c].prev_image_path, cdrom_image[c].image_path); if (cdrom_drives[c].host_drive < 'A') cdrom_drives[c].host_drive = 0; diff --git a/src/disk/hdc.c b/src/disk/hdc.c index f6a6b5117..e11c80367 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.9 2018/02/14 + * Version: @(#)hdc.c 1.0.10 2018/03/17 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -24,6 +24,7 @@ #include "../machine/machine.h" #include "../device.h" #include "hdc.h" +#include "hdc_ide.h" char *hdc_name; /* configured HDC name */ @@ -158,6 +159,15 @@ hdc_reset(void) /* If we have a valid controller, add its device. */ if (hdc_current > 1) device_add(controllers[hdc_current].device); + + /* Reconfire and reset the IDE layer. */ + ide_ter_disable(); + ide_qua_disable(); + if (ide_enable[2]) + ide_ter_init(); + if (ide_enable[3]) + ide_qua_init(); + ide_reset_hard(); } diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 5dda6f166..4a6c8fa75 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.37 2018/03/16 + * Version: @(#)hdc_ide.c 1.0.38 2018/03/16 * * Authors: Sarah Walker, * Miran Grca, @@ -639,8 +639,8 @@ void ide_set_signature(IDE *ide) else if (ide_drive_is_cdrom(ide)) { cdrom_set_signature(cdrom_id); - ide->secount = cdrom[cdrom_id].phase; - ide->cylinder = cdrom[cdrom_id].request_length; + ide->secount = cdrom[cdrom_id]->phase; + ide->cylinder = cdrom[cdrom_id]->request_length; } else { @@ -832,7 +832,7 @@ void ide_reset(void) } else if ((d < 8) && ide_drive_is_cdrom(&ide_drives[d])) { - cdrom[atapi_cdrom_drives[d]].status = READY_STAT | DSC_STAT; + cdrom[atapi_cdrom_drives[d]]->status = READY_STAT | DSC_STAT; } ide_drives[d].atastat = READY_STAT | DSC_STAT; ide_drives[d].service = 0; @@ -1033,7 +1033,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) else if (ide_drive_is_cdrom(ide)) { ide_log("ATAPI transfer mode: %s\n", (val & 1) ? "DMA" : "PIO"); - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].features = val; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->features = val; } ide->cylprecomp = val; @@ -1043,7 +1043,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].features = val; + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->features = val; } ide_other->cylprecomp = val; return; @@ -1057,7 +1057,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) else if (ide_drive_is_cdrom(ide)) { ide_log("Sector count write: %i\n", val); - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].phase = val; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->phase = val; } ide->secount = val; @@ -1069,7 +1069,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) else if (ide_drive_is_cdrom(ide_other)) { ide_log("Other sector count write: %i\n", val); - cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].phase = val; + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->phase = val; } ide_other->secount = val; return; @@ -1089,8 +1089,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length &= 0xFF00; - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length |= val; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length &= 0xFF00; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length |= val; } ide->cylinder = (ide->cylinder & 0xFF00) | val; ide->lba_addr = (ide->lba_addr & 0xFFF00FF) | (val << 8); @@ -1102,8 +1102,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length &= 0xFF00; - cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length |= val; + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->request_length &= 0xFF00; + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->request_length |= val; } ide_other->cylinder = (ide_other->cylinder&0xFF00) | val; ide_other->lba_addr = (ide_other->lba_addr&0xFFF00FF) | (val << 8); @@ -1117,8 +1117,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length &= 0xFF; - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length |= (val << 8); + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length &= 0xFF; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length |= (val << 8); } ide->cylinder = (ide->cylinder & 0xFF) | (val << 8); ide->lba_addr = (ide->lba_addr & 0xF00FFFF) | (val << 16); @@ -1130,8 +1130,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length &= 0xFF; - cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length |= (val << 8); + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->request_length &= 0xFF; + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]]->request_length |= (val << 8); } ide_other->cylinder = (ide_other->cylinder & 0xFF) | (val << 8); ide_other->lba_addr = (ide_other->lba_addr & 0xF00FFFF) | (val << 16); @@ -1163,11 +1163,11 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[ide->channel]].error = 1; - cdrom[atapi_cdrom_drives[ide->channel]].phase = 1; - cdrom[atapi_cdrom_drives[ide->channel]].request_length = 0xEB14; - cdrom[atapi_cdrom_drives[ide->channel]].callback = 0LL; + cdrom[atapi_cdrom_drives[ide->channel]]->status = READY_STAT | DSC_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->error = 1; + cdrom[atapi_cdrom_drives[ide->channel]]->phase = 1; + cdrom[atapi_cdrom_drives[ide->channel]]->request_length = 0xEB14; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 0LL; ide->cylinder = 0xEB14; } @@ -1182,11 +1182,11 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[atapi_cdrom_drives[ide_other->channel]].status = READY_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[ide_other->channel]].error = 1; - cdrom[atapi_cdrom_drives[ide_other->channel]].phase = 1; - cdrom[atapi_cdrom_drives[ide_other->channel]].request_length = 0xEB14; - cdrom[atapi_cdrom_drives[ide_other->channel]].callback = 0LL; + cdrom[atapi_cdrom_drives[ide_other->channel]]->status = READY_STAT | DSC_STAT; + cdrom[atapi_cdrom_drives[ide_other->channel]]->error = 1; + cdrom[atapi_cdrom_drives[ide_other->channel]]->phase = 1; + cdrom[atapi_cdrom_drives[ide_other->channel]]->request_length = 0xEB14; + cdrom[atapi_cdrom_drives[ide_other->channel]]->callback = 0LL; ide->cylinder = 0xEB14; } @@ -1224,7 +1224,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].error = 0; + cdrom[atapi_cdrom_drives[ide->channel]]->error = 0; } if (((val >= WIN_RESTORE) && (val <= 0x1F)) || ((val >= WIN_SEEK) && (val <= 0x7F))) { @@ -1234,7 +1234,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = READY_STAT; } else { @@ -1247,7 +1247,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 100LL*IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 100LL*IDE_TIME; } idecallback[ide_board]=40000LL * TIMER_USEC /*100LL*IDE_TIME*/; timer_update_outstanding(); @@ -1262,7 +1262,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; } else { @@ -1275,7 +1275,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 100LL*IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 100LL*IDE_TIME; } idecallback[ide_board]=100LL*IDE_TIME; timer_update_outstanding(); @@ -1299,7 +1299,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; } else { @@ -1312,7 +1312,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 200LL*IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL*IDE_TIME; } idecallback[ide_board]=200LL*IDE_TIME; timer_update_outstanding(); @@ -1335,8 +1335,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = DRQ_STAT | DSC_STAT | READY_STAT; - cdrom[atapi_cdrom_drives[ide->channel]].pos = 0; + cdrom[atapi_cdrom_drives[ide->channel]]->status = DRQ_STAT | DSC_STAT | READY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->pos = 0; } else { @@ -1353,7 +1353,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; } else { @@ -1366,7 +1366,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 200LL*IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL*IDE_TIME; } idecallback[ide_board]=200LL*IDE_TIME; timer_update_outstanding(); @@ -1380,7 +1380,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; } else { @@ -1393,7 +1393,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 200LL*IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL*IDE_TIME; } idecallback[ide_board]=200LL*IDE_TIME; timer_update_outstanding(); @@ -1418,7 +1418,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; } else { @@ -1431,7 +1431,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 30LL*IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 30LL*IDE_TIME; } idecallback[ide_board]=30LL*IDE_TIME; timer_update_outstanding(); @@ -1439,16 +1439,16 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ if (ide_drive_is_zip(ide)) - zip[atapi_zip_drives[ide->channel]].status = BUSY_STAT; + zip[atapi_zip_drives[ide->channel]].status = BUSY_STAT; else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; else ide->atastat = BUSY_STAT; if (ide_drive_is_zip(ide_other)) zip[atapi_zip_drives[ide_other->channel]].status = BUSY_STAT; else if (ide_drive_is_cdrom(ide_other)) - cdrom[atapi_cdrom_drives[ide_other->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide_other->channel]]->status = BUSY_STAT; else ide_other->atastat = BUSY_STAT; @@ -1456,7 +1456,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) if (ide_drive_is_zip(ide)) zip[atapi_zip_drives[ide->channel]].callback = 200LL * IDE_TIME; else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]].callback = 200LL * IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL * IDE_TIME; idecallback[ide_board] = 200LL * IDE_TIME; timer_update_outstanding(); return; @@ -1472,7 +1472,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) if (ide_drive_is_zip(ide)) zip[atapi_zip_drives[ide->channel]].status = BUSY_STAT; else if (ide_drive_is_cdrom(ide)) - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; else ide->atastat = BUSY_STAT; timer_process(); @@ -1489,7 +1489,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; } else { @@ -1502,7 +1502,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 200LL*IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 200LL*IDE_TIME; } idecallback[ide_board]=200LL*IDE_TIME; timer_update_outstanding(); @@ -1519,10 +1519,10 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].packet_status = CDROM_PHASE_IDLE; - cdrom[atapi_cdrom_drives[ide->channel]].pos=0; - cdrom[atapi_cdrom_drives[ide->channel]].phase = 1; - cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT | DRQ_STAT | (cdrom[cur_ide[ide_board]].status & ERR_STAT); + cdrom[atapi_cdrom_drives[ide->channel]]->packet_status = CDROM_PHASE_IDLE; + cdrom[atapi_cdrom_drives[ide->channel]]->pos=0; + cdrom[atapi_cdrom_drives[ide->channel]]->phase = 1; + cdrom[atapi_cdrom_drives[ide->channel]]->status = READY_STAT | DRQ_STAT | (cdrom[cur_ide[ide_board]]->status & ERR_STAT); } else { @@ -1544,8 +1544,8 @@ ide_bad_command: } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT | ERR_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[ide->channel]].error = ABRT_ERR; + cdrom[atapi_cdrom_drives[ide->channel]]->status = READY_STAT | ERR_STAT | DSC_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->error = ABRT_ERR; } else { @@ -1567,7 +1567,7 @@ ide_bad_command: } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 0LL; + cdrom[atapi_cdrom_drives[ide->channel]]->callback = 0LL; } idecallback[ide_board]=500LL*IDE_TIME; timer_update_outstanding(); @@ -1586,7 +1586,7 @@ ide_bad_command: } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]]->status = BUSY_STAT; } ide->atastat = ide_other->atastat = BUSY_STAT; } @@ -1670,8 +1670,8 @@ uint32_t ide_read_data(int ide_board, int length) } else if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status = READY_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].packet_status = CDROM_PHASE_IDLE; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->status = READY_STAT | DSC_STAT; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->packet_status = CDROM_PHASE_IDLE; } if (ide->command == WIN_READ || ide->command == WIN_READ_NORETRY || ide->command == WIN_READ_MULTIPLE) { @@ -1733,7 +1733,7 @@ uint8_t readide(int ide_board, uint16_t addr) } else if (ide_drive_is_cdrom(ide)) { - temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].error; + temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->error; } else { @@ -1762,7 +1762,7 @@ uint8_t readide(int ide_board, uint16_t addr) } else if (ide_drive_is_cdrom(ide)) { - temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].phase; + temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->phase; } else { @@ -1787,7 +1787,7 @@ uint8_t readide(int ide_board, uint16_t addr) } else if (ide_drive_is_cdrom(ide)) { - temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length & 0xff; + temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length & 0xff; } else { @@ -1809,7 +1809,7 @@ uint8_t readide(int ide_board, uint16_t addr) } else if (ide_drive_is_cdrom(ide)) { - temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length >> 8; + temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->request_length >> 8; } else { @@ -1838,7 +1838,7 @@ uint8_t readide(int ide_board, uint16_t addr) } else if (ide_drive_is_cdrom(ide)) { - temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); + temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); } else { @@ -1860,7 +1860,7 @@ uint8_t readide(int ide_board, uint16_t addr) } else if (ide_drive_is_cdrom(ide)) { - temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); + temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]]->status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); } else { @@ -1942,10 +1942,10 @@ void callbackide(int ide_board) else if (ide_drive_is_cdrom(ide)) { cdrom_id = atapi_cdrom_drives[cur_ide[ide_board]]; - cdrom[cdrom_id].status = READY_STAT | DSC_STAT; - cdrom[cdrom_id].error = 1; - cdrom[cdrom_id].phase = 1; - cdrom[cdrom_id].request_length=0xEB14; + cdrom[cdrom_id]->status = READY_STAT | DSC_STAT; + cdrom[cdrom_id]->error = 1; + cdrom[cdrom_id]->phase = 1; + cdrom[cdrom_id]->request_length=0xEB14; ide->cylinder = 0xEB14; if (cdrom_drives[cdrom_id].handler->stop) { @@ -1968,10 +1968,10 @@ void callbackide(int ide_board) else if (ide_drive_is_cdrom(ide_other)) { cdrom_id_other = atapi_cdrom_drives[cur_ide[ide_board] ^ 1]; - cdrom[cdrom_id_other].status = READY_STAT | DSC_STAT; - cdrom[cdrom_id_other].error = 1; - cdrom[cdrom_id_other].phase = 1; - cdrom[cdrom_id_other].request_length=0xEB14; + cdrom[cdrom_id_other]->status = READY_STAT | DSC_STAT; + cdrom[cdrom_id_other]->error = 1; + cdrom[cdrom_id_other]->phase = 1; + cdrom[cdrom_id_other]->request_length=0xEB14; ide_other->cylinder = 0xEB14; if (cdrom_drives[cdrom_id_other].handler->stop) { @@ -2028,9 +2028,9 @@ void callbackide(int ide_board) } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id].status = READY_STAT | DSC_STAT; - cdrom[cdrom_id].error = 1; - cdrom[cdrom_id].phase = 1; + cdrom[cdrom_id]->status = READY_STAT | DSC_STAT; + cdrom[cdrom_id]->error = 1; + cdrom[cdrom_id]->phase = 1; cdrom_reset(cdrom_id); } ide_irq_raise(ide); @@ -2050,7 +2050,7 @@ void callbackide(int ide_board) } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id].status = READY_STAT | DSC_STAT; + cdrom[cdrom_id]->status = READY_STAT | DSC_STAT; } else { @@ -2068,8 +2068,8 @@ void callbackide(int ide_board) } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id].phase = 0xFF; - cdrom[cdrom_id].status = READY_STAT | DSC_STAT; + cdrom[cdrom_id]->phase = 0xFF; + cdrom[cdrom_id]->status = READY_STAT | DSC_STAT; } ide->secount = 0xFF; ide->atastat = READY_STAT | DSC_STAT; @@ -2361,8 +2361,8 @@ void callbackide(int ide_board) } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id].status = 0; - cdrom[cdrom_id].error = 1; + cdrom[cdrom_id]->status = 0; + cdrom[cdrom_id]->error = 1; ide_irq_raise(ide); } else @@ -2382,8 +2382,8 @@ void callbackide(int ide_board) } else if (ide_drive_is_cdrom(ide_other)) { - cdrom[cdrom_id_other].status = 0; - cdrom[cdrom_id_other].error = 1; + cdrom[cdrom_id_other]->status = 0; + cdrom[cdrom_id_other]->error = 1; } else { @@ -2426,10 +2426,10 @@ void callbackide(int ide_board) { ide_atapi_identify(ide); ide->pos = 0; - cdrom[cdrom_id].phase = 2; - cdrom[cdrom_id].pos = 0; - cdrom[cdrom_id].error = 0; - cdrom[cdrom_id].status = DRQ_STAT | READY_STAT | DSC_STAT; + cdrom[cdrom_id]->phase = 2; + cdrom[cdrom_id]->pos = 0; + cdrom[cdrom_id]->error = 0; + cdrom[cdrom_id]->status = DRQ_STAT | READY_STAT | DSC_STAT; ide_irq_raise(ide); return; } @@ -2462,8 +2462,8 @@ void callbackide(int ide_board) zip[zip_id].pos = 0; } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id].status = READY_STAT | DSC_STAT; - cdrom[cdrom_id].pos = 0; + cdrom[cdrom_id]->status = READY_STAT | DSC_STAT; + cdrom[cdrom_id]->pos = 0; } ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); @@ -2525,9 +2525,9 @@ abort_cmd: } else if (ide_drive_is_cdrom(ide)) { - cdrom[cdrom_id].status = READY_STAT | ERR_STAT | DSC_STAT; - cdrom[cdrom_id].error = ABRT_ERR; - cdrom[cdrom_id].pos = 0; + cdrom[cdrom_id]->status = READY_STAT | ERR_STAT | DSC_STAT; + cdrom[cdrom_id]->error = ABRT_ERR; + cdrom[cdrom_id]->pos = 0; } else { diff --git a/src/disk/zip.c b/src/disk/zip.c index 5e2e71dfb..86f1dd3c7 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -9,7 +9,7 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.c 1.0.10 2018/03/16 + * Version: @(#)zip.c 1.0.12 2018/03/17 * * Author: Miran Grca, * @@ -952,12 +952,12 @@ static void zip_command_common(uint8_t id) bytes_per_second = 8333333.333333333333333; /* 8.3 MB/s PIO-2 speed */ } else bytes_per_second = 3333333.333333333333333; /* 3.3 MB/s PIO-0 speed */ - } - period = 1000000.0 / bytes_per_second; - dusec = (double) TIMER_USEC; - dusec = dusec * period * (double) (zip[id].packet_len); - zip[id].callback = ((int64_t) dusec); + period = 1000000.0 / bytes_per_second; + dusec = (double) TIMER_USEC; + dusec = dusec * period * (double) (zip[id].packet_len); + zip[id].callback = ((int64_t) dusec); + } zip_set_callback(id); } @@ -2511,15 +2511,6 @@ void zip_write(uint8_t channel, uint32_t val, int length) } } -void zip_hard_reset(void) -{ - int i = 0; - - for (i=0; i * @@ -199,7 +199,6 @@ extern int find_zip_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun); extern int zip_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len); extern void zip_global_init(void); -extern void zip_global_reset(void); extern void zip_hard_reset(void); extern int zip_load(uint8_t id, wchar_t *fn); diff --git a/src/pc.c b/src/pc.c index 3aec78258..a6ee1733e 100644 --- a/src/pc.c +++ b/src/pc.c @@ -527,12 +527,7 @@ pc_reload(wchar_t *fn) fdd_close(i); for (i=0; iexit(i); - if (cdrom_drives[i].host_drive == 200) - image_close(i); - else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) - ioctl_close(i); - else - null_close(i); + cdrom_close(i); } pc_reset_hard_close(); @@ -658,9 +653,6 @@ again2: ide_init_first(); - cdrom_global_reset(); - zip_global_reset(); - device_init(); timer_reset(); @@ -675,11 +667,11 @@ again2: ide_reset_hard(); + scsi_card_init(); + cdrom_hard_reset(); zip_hard_reset(); - scsi_card_init(); - pc_full_speed(); shadowbios = 0; @@ -828,16 +820,6 @@ pc_reset_hard_init(void) /* Reset the Hard Disk Controller module. */ hdc_reset(); - /* Reconfire and reset the IDE layer. */ - // FIXME: this should have been done via hdc_reset() above.. --FvK - ide_ter_disable(); - ide_qua_disable(); - if (ide_enable[2]) - ide_ter_init(); - if (ide_enable[3]) - ide_qua_init(); - ide_reset_hard(); - /* Reset and reconfigure the SCSI layer. */ scsi_card_init(); @@ -970,6 +952,8 @@ pc_close(thread_t *ptr) mem_destroy_pages(); ide_destroy_buffers(); + + cdrom_destroy_drives(); } diff --git a/src/scsi/scsi_device.c b/src/scsi/scsi_device.c index 91350ec3d..aed66bf6c 100644 --- a/src/scsi/scsi_device.c +++ b/src/scsi/scsi_device.c @@ -8,7 +8,7 @@ * * The generic SCSI device command handler. * - * Version: @(#)scsi_device.c 1.0.14 2018/03/07 + * Version: @(#)scsi_device.c 1.0.15 2018/03/16 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -106,7 +106,7 @@ static void scsi_device_target_save_cdb_byte(int lun_type, uint8_t id, uint8_t c } else if (lun_type == SCSI_CDROM) { - cdrom[id].request_length = cdb_byte; + cdrom[id]->request_length = cdb_byte; } else if (lun_type == SCSI_ZIP) { @@ -133,7 +133,7 @@ int64_t scsi_device_get_callback(uint8_t scsi_id, uint8_t scsi_lun) break; case SCSI_CDROM: id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom[id].callback; + return cdrom[id]->callback; break; case SCSI_ZIP: id = scsi_zip_drives[scsi_id][scsi_lun]; @@ -160,7 +160,7 @@ uint8_t *scsi_device_sense(uint8_t scsi_id, uint8_t scsi_lun) break; case SCSI_CDROM: id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom[id].sense; + return cdrom[id]->sense; break; case SCSI_ZIP: id = scsi_zip_drives[scsi_id][scsi_lun]; @@ -301,7 +301,7 @@ int scsi_device_cdb_length(uint8_t scsi_id, uint8_t scsi_lun) { case SCSI_CDROM: id = scsi_cdrom_drives[scsi_id][scsi_lun]; - return cdrom[id].cdb_len; + return cdrom[id]->cdb_len; case SCSI_ZIP: id = scsi_zip_drives[scsi_id][scsi_lun]; return zip[id].cdb_len; diff --git a/src/win/win_cdrom.c b/src/win/win_cdrom.c index b27433fb9..0741bfc5e 100644 --- a/src/win/win_cdrom.c +++ b/src/win/win_cdrom.c @@ -8,7 +8,7 @@ * * Handle the platform-side of CDROM drives. * - * Version: @(#)win_cdrom.c 1.0.5 2018/03/06 + * Version: @(#)win_cdrom.c 1.0.6 2018/03/17 * * Authors: Sarah Walker, * Miran Grca, @@ -79,7 +79,13 @@ cdrom_eject(uint8_t id) IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_UNCHECKED); } + if (cdrom_image[id].prev_image_path) { + free(cdrom_image[id].prev_image_path); + cdrom_image[id].prev_image_path = NULL; + } + if (cdrom_drives[id].host_drive == 200) { + cdrom_image[id].prev_image_path = (wchar_t *) malloc(1024); wcscpy(cdrom_image[id].prev_image_path, cdrom_image[id].image_path); } cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; @@ -116,6 +122,8 @@ cdrom_reload(uint8_t id) if (cdrom_drives[id].prev_host_drive == 200) { wcscpy(cdrom_image[id].image_path, cdrom_image[id].prev_image_path); + free(cdrom_image[id].prev_image_path); + cdrom_image[id].prev_image_path = NULL; image_open(id, cdrom_image[id].image_path); if (cdrom_drives[id].bus_type) { /* Signal disc change to the emulated machine. */ diff --git a/src/win/win_cdrom_ioctl.c b/src/win/win_cdrom_ioctl.c index 4dd160986..580788025 100644 --- a/src/win/win_cdrom_ioctl.c +++ b/src/win/win_cdrom_ioctl.c @@ -9,7 +9,7 @@ * Implementation of the CD-ROM host drive IOCTL interface for * Windows using SCSI Passthrough Direct. * - * Version: @(#)cdrom_ioctl.c 1.0.13 2018/03/15 + * Version: @(#)cdrom_ioctl.c 1.0.14 2018/03/17 * * Authors: Sarah Walker, * Miran Grca, @@ -78,67 +78,72 @@ static int ioctl_hopen(uint8_t id); void ioctl_audio_callback(uint8_t id, int16_t *output, int len) { + cdrom_t *dev = cdrom[id]; + RAW_READ_INFO in; DWORD count; - if (!cdrom_drives[id].sound_on || (cdrom_ioctl[id].cd_state != CD_PLAYING)) + if (!cdrom_drives[id].sound_on || (dev->cd_state != CD_PLAYING)) { - if (cdrom_ioctl[id].cd_state == CD_PLAYING) + if (dev->cd_state == CD_PLAYING) { - cdrom[id].seek_pos += (len >> 11); + dev->seek_pos += (len >> 11); } memset(output, 0, len * 2); return; } - while (cdrom_ioctl[id].cd_buflen < len) + while (dev->cd_buflen < len) { - if (cdrom[id].seek_pos < cdrom_ioctl[id].cd_end) + if (dev->seek_pos < dev->cd_end) { - in.DiskOffset.LowPart = (cdrom[id].seek_pos - 150) * 2048; + in.DiskOffset.LowPart = (dev->seek_pos - 150) * 2048; in.DiskOffset.HighPart = 0; in.SectorCount = 1; in.TrackMode = CDDA; - if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(cdrom[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 2352, &count, NULL)) + if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(dev->cd_buffer[dev->cd_buflen]), 2352, &count, NULL)) { - memset(&(cdrom[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + memset(&(dev->cd_buffer[dev->cd_buflen]), 0, (BUF_SIZE - dev->cd_buflen) * 2); cdrom_ioctl_windows[id].is_playing = 0; ioctl_close(id); - cdrom_ioctl[id].cd_state = CD_STOPPED; - cdrom_ioctl[id].cd_buflen = len; + dev->cd_state = CD_STOPPED; + dev->cd_buflen = len; } else { - cdrom[id].seek_pos++; - cdrom_ioctl[id].cd_buflen += (2352 / 2); + dev->seek_pos++; + dev->cd_buflen += (2352 / 2); } } else { - memset(&(cdrom[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + memset(&(dev->cd_buffer[dev->cd_buflen]), 0, (BUF_SIZE - dev->cd_buflen) * 2); cdrom_ioctl_windows[id].is_playing = 0; ioctl_close(id); - cdrom_ioctl[id].cd_state = CD_STOPPED; - cdrom_ioctl[id].cd_buflen = len; + dev->cd_state = CD_STOPPED; + dev->cd_buflen = len; } } - memcpy(output, cdrom[id].cd_buffer, len * 2); - memcpy(&cdrom[id].cd_buffer[0], &(cdrom[id].cd_buffer[len]), (BUF_SIZE - len) * 2); - cdrom_ioctl[id].cd_buflen -= len; + memcpy(output, dev->cd_buffer, len * 2); + memcpy(&dev->cd_buffer[0], &(dev->cd_buffer[len]), (BUF_SIZE - len) * 2); + dev->cd_buflen -= len; } void ioctl_audio_stop(uint8_t id) { + cdrom_t *dev = cdrom[id]; cdrom_ioctl_windows[id].is_playing = 0; ioctl_close(id); - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; } static int get_track_nr(uint8_t id, uint32_t pos) { + cdrom_t *dev = cdrom[id]; + int c; int track = 0; - if (!cdrom_ioctl[id].tocvalid) + if (dev->disc_changed) { return 0; } @@ -167,9 +172,10 @@ static int get_track_nr(uint8_t id, uint32_t pos) static uint32_t get_track_msf(uint8_t id, uint32_t track_no) { + cdrom_t *dev = cdrom[id]; int c; - if (!cdrom_ioctl[id].tocvalid) + if (dev->disc_changed) { return 0; } @@ -186,6 +192,7 @@ static uint32_t get_track_msf(uint8_t id, uint32_t track_no) static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) { + cdrom_t *dev = cdrom[id]; int m = 0, s = 0, f = 0; uint32_t start_msf = 0, end_msf = 0; if (!cdrom_drives[id].host_drive) @@ -222,7 +229,7 @@ static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) if (pos == 0xffffff) { cdrom_ioctl_log("Playing from current position (MSF)\n"); - pos = cdrom[id].seek_pos; + pos = dev->seek_pos; } else { @@ -239,51 +246,54 @@ static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) if (pos == 0xffffffff) { cdrom_ioctl_log("Playing from current position\n"); - pos = cdrom[id].seek_pos; + pos = dev->seek_pos; } len += pos; } - cdrom[id].seek_pos = pos; - cdrom_ioctl[id].cd_end = len; - if (cdrom[id].seek_pos < 150) + dev->seek_pos = pos; + dev->cd_end = len; + if (dev->seek_pos < 150) { /* Adjust because the host expects a minimum adjusted LBA of 0 which is equivalent to an absolute LBA of 150. */ - cdrom[id].seek_pos = 150; + dev->seek_pos = 150; } if (!cdrom_ioctl_windows[id].is_playing) { ioctl_hopen(id); cdrom_ioctl_windows[id].is_playing = 1; } - cdrom_ioctl[id].cd_state = CD_PLAYING; + dev->cd_state = CD_PLAYING; } static void ioctl_pause(uint8_t id) { + cdrom_t *dev = cdrom[id]; if (!cdrom_drives[id].host_drive) { return; } - if (cdrom_ioctl[id].cd_state == CD_PLAYING) + if (dev->cd_state == CD_PLAYING) { - cdrom_ioctl[id].cd_state = CD_PAUSED; + dev->cd_state = CD_PAUSED; } } static void ioctl_resume(uint8_t id) { + cdrom_t *dev = cdrom[id]; if (!cdrom_drives[id].host_drive) { return; } - if (cdrom_ioctl[id].cd_state == CD_PAUSED) + if (dev->cd_state == CD_PAUSED) { - cdrom_ioctl[id].cd_state = CD_PLAYING; + dev->cd_state = CD_PLAYING; } } static void ioctl_stop(uint8_t id) { + cdrom_t *dev = cdrom[id]; if (!cdrom_drives[id].host_drive) { return; @@ -293,11 +303,12 @@ static void ioctl_stop(uint8_t id) cdrom_ioctl_windows[id].is_playing = 0; ioctl_close(id); } - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; } static int ioctl_ready(uint8_t id) { + cdrom_t *dev = cdrom[id]; unsigned long size; int temp; CDROM_TOC ltoc; @@ -322,9 +333,9 @@ static int ioctl_ready(uint8_t id) if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3]) || - !cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) + dev->disc_changed || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) { - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) { cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; @@ -336,6 +347,7 @@ static int ioctl_ready(uint8_t id) static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, int maxlen, int single) { + cdrom_t *dev = cdrom[id]; unsigned long size; int c, d = 0; CDROM_TOC lbtoc; @@ -344,11 +356,11 @@ static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, i { return 0; } - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &lbtoc, sizeof(lbtoc), &size, NULL); ioctl_close(id); - cdrom_ioctl[id].tocvalid=1; + dev->disc_changed = 0; for (c=d; c <= lbtoc.LastTrack; c++) { uint32_t address; @@ -365,6 +377,7 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b); static int ioctl_medium_changed(uint8_t id) { + cdrom_t *dev = cdrom[id]; unsigned long size; int temp; CDROM_TOC ltoc; @@ -379,11 +392,11 @@ static int ioctl_medium_changed(uint8_t id) { return 0; /* Drive empty, a not ready handler matter, not disc change. */ } - if (!cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) + if (dev->disc_changed || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) { - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; cdrom_ioctl_windows[id].toc = ltoc; - cdrom_ioctl[id].tocvalid = 1; + dev->disc_changed = 0; if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) { cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; @@ -392,7 +405,7 @@ static int ioctl_medium_changed(uint8_t id) cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ ioctl_read_capacity(id, NULL); ioctl_close(id); - cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); + dev->cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); return 1; } else @@ -401,14 +414,14 @@ static int ioctl_medium_changed(uint8_t id) (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3])) { - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; cdrom_ioctl_log("Setting TOC...\n"); cdrom_ioctl_windows[id].toc = ltoc; ioctl_hopen(id); cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ ioctl_read_capacity(id, NULL); ioctl_close(id); - cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); + dev->cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); return 1; /* TOC mismatches. */ } } @@ -417,6 +430,7 @@ static int ioctl_medium_changed(uint8_t id) static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) { + cdrom_t *dev = cdrom[id]; CDROM_SUB_Q_DATA_FORMAT insub; SUB_Q_CHANNEL_DATA sub; unsigned long size; @@ -425,12 +439,12 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) if (!cdrom_drives[id].host_drive) return 0; - cdpos = cdrom[id].seek_pos; + cdpos = dev->seek_pos; - if (cdrom_ioctl[id].last_subchannel_pos == cdpos) + if (dev->last_subchannel_pos == cdpos) { - memcpy(&insub, cdrom_ioctl[id].sub_q_data_format, sizeof(insub)); - memcpy(&sub, cdrom_ioctl[id].sub_q_channel_data, sizeof(sub)); + memcpy(&insub, dev->sub_q_data_format, sizeof(insub)); + memcpy(&sub, dev->sub_q_channel_data, sizeof(sub)); } else { @@ -438,14 +452,14 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL); ioctl_close(id); - memset(cdrom_ioctl[id].sub_q_data_format, 0, 16); - memcpy(cdrom_ioctl[id].sub_q_data_format, &insub, sizeof(insub)); - memset(cdrom_ioctl[id].sub_q_channel_data, 0, 256); - memcpy(cdrom_ioctl[id].sub_q_channel_data, &sub, sizeof(sub)); - cdrom_ioctl[id].last_subchannel_pos = cdpos; + memset(dev->sub_q_data_format, 0, 16); + memcpy(dev->sub_q_data_format, &insub, sizeof(insub)); + memset(dev->sub_q_channel_data, 0, 256); + memcpy(dev->sub_q_channel_data, &sub, sizeof(sub)); + dev->last_subchannel_pos = cdpos; } - if (cdrom_ioctl[id].cd_state == CD_PLAYING || cdrom_ioctl[id].cd_state == CD_PAUSED) + if (dev->cd_state == CD_PLAYING || dev->cd_state == CD_PAUSED) { track = get_track_nr(id, cdpos); track_address = cdrom_ioctl_windows[id].toc.TrackData[track].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[2] * 75) + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[1] * 75 * 60); @@ -484,7 +498,7 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) b[pos++] = cdpos & 0xff; } - if (cdrom_ioctl[id].cd_state == CD_PLAYING) return 0x11; + if (dev->cd_state == CD_PLAYING) return 0x11; return 0x12; } @@ -525,6 +539,7 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) static void ioctl_eject(uint8_t id) { + cdrom_t *dev = cdrom[id]; unsigned long size; if (!cdrom_drives[id].host_drive) { @@ -535,7 +550,7 @@ static void ioctl_eject(uint8_t id) cdrom_ioctl_windows[id].is_playing = 0; ioctl_stop(id); } - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL); ioctl_close(id); @@ -543,6 +558,7 @@ static void ioctl_eject(uint8_t id) static void ioctl_load(uint8_t id) { + cdrom_t *dev = cdrom[id]; unsigned long size; if (!cdrom_drives[id].host_drive) { @@ -553,23 +569,25 @@ static void ioctl_load(uint8_t id) cdrom_ioctl_windows[id].is_playing = 0; ioctl_stop(id); } - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_LOAD_MEDIA,NULL,0,NULL,0,&size,NULL); cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ ioctl_read_capacity(id, NULL); ioctl_close(id); - cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); + dev->cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); } static int ioctl_is_track_audio(uint8_t id, uint32_t pos, int ismsf) { + cdrom_t *dev = cdrom[id]; + int c; int control = 0; uint32_t track_address = 0; - if (!cdrom_ioctl[id].tocvalid) + if (dev->disc_changed) { return 0; } @@ -639,6 +657,8 @@ struct sptd_with_sense static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_blocks, int no_length_check) { + cdrom_t *dev = cdrom[id]; + int sector_type = 0; int temp_len = 0; @@ -732,7 +752,7 @@ common_handler: cdrom_illegal_mode(id); return -1; } - return temp_len * cdrom[id].requested_blocks; + return temp_len * dev->requested_blocks; break; default: /* Other commands */ @@ -792,6 +812,7 @@ static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, static void ioctl_read_capacity(uint8_t id, uint8_t *b) { + cdrom_t *dev = cdrom[id]; uint32_t len = 0; const UCHAR cdb[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -801,12 +822,12 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b) { SCSICommand(id, cdb, buf, &len, 1); - memcpy(cdrom_ioctl[id].rcbuf, buf, len); + memcpy(dev->rcbuf, buf, len); cdrom_ioctl[id].capacity_read = 1; } else { - memcpy(b, cdrom_ioctl[id].rcbuf, 16); + memcpy(b, dev->rcbuf, 16); } } @@ -937,23 +958,26 @@ static int ioctl_get_sector_data_type(uint8_t id, uint8_t b0, uint8_t b1, uint8_ static void ioctl_validate_toc(uint8_t id) { + cdrom_t *dev = cdrom[id]; unsigned long size; if (!cdrom_drives[id].host_drive) { return; } - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; ioctl_hopen(id); cdrom_ioctl_log("Validating TOC...\n"); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); ioctl_close(id); - cdrom_ioctl[id].tocvalid=1; + dev->disc_changed = 0; } UCHAR buf[262144]; static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len) { + cdrom_t *dev = cdrom[id]; + const UCHAR cdb[12]; int ret = 0; @@ -976,17 +1000,17 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t memcpy((void *) cdb, in_cdb, 12); temp_len = 0; - temp_block_length = ioctl_get_block_length(id, cdb, cdrom[id].requested_blocks, 0); + temp_block_length = ioctl_get_block_length(id, cdb, dev->requested_blocks, 0); if (temp_block_length != -1) { cdrom_ioctl[id].actual_requested_blocks = 1; if ((cdb[0] == 0x08) || (cdb[0] == 0x28) || (cdb[0] == 0xA8) || (cdb[0] == 0xB9) || (cdb[0] == 0xBE)) { buffer_pos = 0; temp_len = 0; - for (i = 0; i < cdrom[id].requested_blocks; i++) + for (i = 0; i < dev->requested_blocks; i++) { cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Transferring block...\n", id, cdrom_ioctl[id].actual_requested_blocks); - cdrom_update_cdb((uint8_t *) cdb, cdrom[id].sector_pos + i, 1); + cdrom_update_cdb((uint8_t *) cdb, dev->sector_pos + i, 1); ret = SCSICommand(id, cdb, b + buffer_pos, &temp_len, 0); buffer_pos += temp_len; } @@ -1009,6 +1033,7 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t static int ioctl_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) { + cdrom_t *dev = cdrom[id]; int len=4; DWORD size; int c,d; @@ -1018,11 +1043,11 @@ static int ioctl_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, { return 0; } - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); ioctl_close(id); - cdrom_ioctl[id].tocvalid = 1; + dev->disc_changed = 0; b[2]=cdrom_ioctl_windows[id].toc.FirstTrack; b[3]=cdrom_ioctl_windows[id].toc.LastTrack; d=0; @@ -1071,6 +1096,7 @@ static int ioctl_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, static int ioctl_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) { + cdrom_t *dev = cdrom[id]; int len=4; int size; uint32_t temp; @@ -1080,7 +1106,7 @@ static int ioctl_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxl { return 0; } - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; memset(&toc_ex,0,sizeof(toc_ex)); memset(&toc,0,sizeof(toc)); toc_ex.Format=CDROM_READ_TOC_EX_FORMAT_SESSION; @@ -1116,6 +1142,7 @@ static int ioctl_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxl static int ioctl_readtoc_raw(uint8_t id, uint8_t *b, int maxlen) { + cdrom_t *dev = cdrom[id]; int len=4; int size; int i; @@ -1125,7 +1152,7 @@ static int ioctl_readtoc_raw(uint8_t id, uint8_t *b, int maxlen) { return 0; } - cdrom_ioctl[id].cd_state = CD_STOPPED; + dev->cd_state = CD_STOPPED; memset(&toc_ex,0,sizeof(toc_ex)); memset(&toc,0,sizeof(toc)); toc_ex.Format=CDROM_READ_TOC_EX_FORMAT_FULL_TOC; @@ -1185,12 +1212,14 @@ static uint32_t ioctl_size(uint8_t id) static int ioctl_status(uint8_t id) { + cdrom_t *dev = cdrom[id]; + if (!(ioctl_ready(id)) && (cdrom_drives[id].host_drive <= 0)) { return CD_STATUS_EMPTY; } - switch(cdrom_ioctl[id].cd_state) + switch(dev->cd_state) { case CD_PLAYING: return CD_STATUS_PLAYING; @@ -1205,12 +1234,14 @@ static int ioctl_status(uint8_t id) void ioctl_reset(uint8_t id) { + cdrom_t *dev = cdrom[id]; + CDROM_TOC ltoc; unsigned long size; if (!cdrom_drives[id].host_drive) { - cdrom_ioctl[id].tocvalid = 0; + dev->disc_changed = 1; return; } @@ -1219,7 +1250,7 @@ void ioctl_reset(uint8_t id) ioctl_close(id); cdrom_ioctl_windows[id].toc = ltoc; - cdrom_ioctl[id].tocvalid = 1; + dev->disc_changed = 0; } int ioctl_hopen(uint8_t id) @@ -1231,11 +1262,12 @@ int ioctl_hopen(uint8_t id) int ioctl_open(uint8_t id, char d) { + cdrom_t *dev = cdrom[id]; sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d); - cdrom_ioctl[id].tocvalid=0; + dev->disc_changed = 1; cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); cdrom_drives[id].handler = &ioctl_cdrom; - cdrom_ioctl[id].ioctl_inited=1; + dev->handler_inited=1; cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ ioctl_read_capacity(id, NULL); CloseHandle(cdrom_ioctl_windows[id].hIOCTL); @@ -1255,10 +1287,11 @@ void ioctl_close(uint8_t id) static void ioctl_exit(uint8_t id) { + cdrom_t *dev = cdrom[id]; cdrom_ioctl_windows[id].is_playing = 0; ioctl_stop(id); - cdrom_ioctl[id].ioctl_inited=0; - cdrom_ioctl[id].tocvalid=0; + dev->handler_inited=0; + dev->disc_changed = 1; } static CDROM ioctl_cdrom= From f2460dc53410abf82949b5e6527b3ce8338e780a Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 17 Mar 2018 22:22:01 +0100 Subject: [PATCH 04/39] Fixed some bugs in cdrom.c. --- src/cdrom/cdrom.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 20a066365..f581c8cc2 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.36 2018/03/16 + * Version: @(#)cdrom.c 1.0.37 2018/03/17 * * Author: Miran Grca, * @@ -453,7 +453,6 @@ void cdrom_init(int id, int cdb_len_setting) return; if (!cdrom[id]) cdrom[id] = (cdrom_t *) malloc(sizeof(cdrom_t)); - pclog(NULL); /* Trigger segfault so we can backtrace. */ dev = cdrom[id]; memset(dev, 0, sizeof(cdrom_t)); dev->requested_blocks = 1; @@ -3262,10 +3261,11 @@ cdrom_hard_reset(void) if (cdrom_drives[c].bus_type) { cdrom_log("CDROM global_reset drive=%d host=%02x\n", c, cdrom_drives[c].host_drive); - SCSIReset(cdrom_drives[c].scsi_device_id, cdrom_drives[c].scsi_device_lun); if (!cdrom[c]) cdrom[c] = (cdrom_t *) malloc(sizeof(cdrom_t)); + SCSIReset(cdrom_drives[c].scsi_device_id, cdrom_drives[c].scsi_device_lun); + if (cdrom_drives[c].host_drive == 200) { image_open(c, cdrom_image[c].image_path); image_reset(c); From d1c3170756ce8de842d05bfd34e6d36572c1b134 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 17 Mar 2018 23:01:06 +0100 Subject: [PATCH 05/39] Fixed more CD-ROM bugs. --- src/cdrom/cdrom.c | 12 +++++------- src/disk/hdc_ide.c | 6 +++--- src/pc.c | 12 ++++++------ 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index f581c8cc2..f14ee69c0 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.37 2018/03/17 + * Version: @(#)cdrom.c 1.0.38 2018/03/17 * * Author: Miran Grca, * @@ -451,8 +451,6 @@ void cdrom_init(int id, int cdb_len_setting) if (id >= CDROM_NUM) return; - if (!cdrom[id]) - cdrom[id] = (cdrom_t *) malloc(sizeof(cdrom_t)); dev = cdrom[id]; memset(dev, 0, sizeof(cdrom_t)); dev->requested_blocks = 1; @@ -856,16 +854,16 @@ static void cdrom_command_common(uint8_t id) switch(dev->current_cdb[0]) { case 0x0b: case 0x2b: - /* Seek time is in ms. */ - period = cdrom_seek_time(id) * ((double) TIMER_USEC) * 1000.0; + /* Seek time is in us. */ + period = cdrom_seek_time(id) * ((double) TIMER_USEC); dev->callback += ((int64_t) period); cdrom_set_callback(id); return; case 0x08: case 0x28: case 0xa8: - /* Seek time is in ms. */ - period = cdrom_seek_time(id) * ((double) TIMER_USEC) * 1000.0; + /* Seek time is in us. */ + period = cdrom_seek_time(id) * ((double) TIMER_USEC); dev->callback += ((int64_t) period); case 0x25: case 0x42: diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 4a6c8fa75..6d42a91ce 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.38 2018/03/16 + * Version: @(#)hdc_ide.c 1.0.39 2018/03/17 * * Authors: Sarah Walker, * Miran Grca, @@ -1515,14 +1515,14 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) zip[atapi_zip_drives[ide->channel]].packet_status = ZIP_PHASE_IDLE; zip[atapi_zip_drives[ide->channel]].pos=0; zip[atapi_zip_drives[ide->channel]].phase = 1; - zip[atapi_zip_drives[ide->channel]].status = READY_STAT | DRQ_STAT | (zip[cur_ide[ide_board]].status & ERR_STAT); + zip[atapi_zip_drives[ide->channel]].status = READY_STAT | DRQ_STAT | (zip[atapi_zip_drives[ide->channel]].status & ERR_STAT); } else if (ide_drive_is_cdrom(ide)) { cdrom[atapi_cdrom_drives[ide->channel]]->packet_status = CDROM_PHASE_IDLE; cdrom[atapi_cdrom_drives[ide->channel]]->pos=0; cdrom[atapi_cdrom_drives[ide->channel]]->phase = 1; - cdrom[atapi_cdrom_drives[ide->channel]]->status = READY_STAT | DRQ_STAT | (cdrom[cur_ide[ide_board]]->status & ERR_STAT); + cdrom[atapi_cdrom_drives[ide->channel]]->status = READY_STAT | DRQ_STAT | (cdrom[atapi_cdrom_drives[ide->channel]]->status & ERR_STAT); } else { diff --git a/src/pc.c b/src/pc.c index a6ee1733e..b19155990 100644 --- a/src/pc.c +++ b/src/pc.c @@ -665,13 +665,13 @@ again2: hdc_init(hdc_name); + cdrom_hard_reset(); + zip_hard_reset(); + ide_reset_hard(); scsi_card_init(); - cdrom_hard_reset(); - zip_hard_reset(); - pc_full_speed(); shadowbios = 0; @@ -817,15 +817,15 @@ pc_reset_hard_init(void) /* Reset the video card. */ video_reset(gfxcard); + cdrom_hard_reset(); + zip_hard_reset(); + /* Reset the Hard Disk Controller module. */ hdc_reset(); /* Reset and reconfigure the SCSI layer. */ scsi_card_init(); - cdrom_hard_reset(); - zip_hard_reset(); - /* Reset and reconfigure the Network Card layer. */ network_reset(); From d3e11f819e43e2fa0b7e41ad4b62ff1b3c9a458a Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 17 Mar 2018 23:14:14 +0100 Subject: [PATCH 06/39] A slight tweak to CD-ROM speed calculation. --- src/cdrom/cdrom.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index f14ee69c0..89d647011 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.38 2018/03/17 + * Version: @(#)cdrom.c 1.0.39 2018/03/17 * * Author: Miran Grca, * @@ -875,7 +875,8 @@ static void cdrom_command_common(uint8_t id) case 0xb8: case 0xb9: case 0xbe: - bytes_per_second = 150.0 * 1024.0; + /* bytes_per_second = 150.0 * 1024.0; */ + bytes_per_second = (1000000.0 / 12000.0) * 2048.0; /* Account for seek time. */ bytes_per_second *= (double) cdrom_drives[id].speed; break; default: From 0cb43db2904115816029dbb713cf08b8e5714f0f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 17 Mar 2018 23:57:04 +0100 Subject: [PATCH 07/39] The CD-ROM image code in win_stbar.c now malloc's prev_image_path if it's NULL. --- src/win/win_stbar.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c index 7f078fcc1..0b50d6e39 100644 --- a/src/win/win_stbar.c +++ b/src/win/win_stbar.c @@ -8,7 +8,7 @@ * * Implement the application's Status Bar. * - * Version: @(#)win_stbar.c 1.0.15 2018/03/06 + * Version: @(#)win_stbar.c 1.0.16 2018/03/17 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -1076,6 +1076,8 @@ StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* Switching from image to the same image. Do nothing. */ break; } + if (!cdrom_image[id].prev_image_path) + cdrom_image[id].prev_image_path = (wchar_t *) malloc(1024); wcscpy(cdrom_image[id].prev_image_path, cdrom_image[id].image_path); cdrom_drives[id].handler->exit(id); cdrom_close(id); From b6c393cc9122679643d0623ae0e4fbbcac828f04 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 18 Mar 2018 20:48:10 +0100 Subject: [PATCH 08/39] Numerous CD-ROM fixes (and disc changes now work correctly in Windows 98 SE); Slight reworking in the mouse and network code (ported from VARCem) in preparation for a major change that will const a lot of things to further reduce RAM usage. --- src/cdrom/cdrom.c | 44 ++++++-- src/cdrom/cdrom.h | 5 +- src/cdrom/cdrom_dosbox.cpp | 25 +++-- src/cdrom/cdrom_image.cc | 42 ++------ src/floppy/fdd_86f.c | 206 ++++++++++++++++++------------------- src/mouse.c | 14 ++- src/network/net_pcap.c | 17 ++- src/network/net_slirp.c | 8 +- src/network/network.c | 14 +-- src/network/network.h | 6 +- src/win/win_stbar.c | 6 +- 11 files changed, 196 insertions(+), 191 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 89d647011..cc7391a0d 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.39 2018/03/17 + * Version: @(#)cdrom.c 1.0.40 2018/03/18 * * Author: Miran Grca, * @@ -128,7 +128,7 @@ uint8_t cdrom_command_flags[0x100] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED | CHECK_READY, - IMPLEMENTED | CHECK_READY, /* Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS + IMPLEMENTED | CHECK_READY | ALLOW_UA, /* Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS NOTE: The ATAPI reference says otherwise, but I think this is a question of interpreting things right - the UNIT ATTENTION condition we have here is a tradition from not ready to ready, by definition the drive @@ -232,7 +232,7 @@ static const mode_sense_pages_t cdrom_mode_sense_pages_default = { 0, 0 }, { 0, 0 }, { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x14, 0x3B, 0, 0x71, 0x60, 0x29, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0, 0, 0 } + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 1, 0, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } } }; static const mode_sense_pages_t cdrom_mode_sense_pages_default_scsi = @@ -279,7 +279,7 @@ static const mode_sense_pages_t cdrom_mode_sense_pages_default_scsi = { 0, 0 }, { 0, 0 }, { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x14, 0x3B, 0, 0x71, 0x60, 0x29, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0, 0, 0 } + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 1, 0, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } } }; static const mode_sense_pages_t cdrom_mode_sense_pages_changeable = @@ -326,12 +326,13 @@ static const mode_sense_pages_t cdrom_mode_sense_pages_changeable = { 0, 0 }, { 0, 0 }, { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x14, 0x3B, 0, 0x71, 0x60, 0x29, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0, 0, 0 } + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 1, 0, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } } }; static mode_sense_pages_t cdrom_mode_sense_pages_saved[CDROM_NUM]; +#define ENABLE_CDROM_LOG 1 #ifdef ENABLE_CDROM_LOG int cdrom_do_log = ENABLE_CDROM_LOG; #endif @@ -475,6 +476,7 @@ void cdrom_init(int id, int cdb_len_setting) cdrom_sense_key = cdrom_asc = cdrom_ascq = dev->unit_attention = 0; dev->cdb_len_setting = 0; dev->cdb_len = 12; + dev->cur_speed = cdrom_drives[id].speed; } int cdrom_supports_pio(int id) @@ -697,8 +699,20 @@ uint32_t cdrom_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, msplen = cdrom_mode_sense_read(id, page_control, i, 1); buf[pos++] = msplen; cdrom_log("CD-ROM %i: MODE SENSE: Page [%02X] length %i\n", id, i, msplen); - for (j = 0; j < msplen; j++) - buf[pos++] = cdrom_mode_sense_read(id, page_control, i, 2 + j); + for (j = 0; j < msplen; j++) { + if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 6) && (j <= 7)) { + if (j & 1) + buf[pos++] = ((cdrom_drives[id].speed * 176) & 0xff); + else + buf[pos++] = ((cdrom_drives[id].speed * 176) >> 8); + } else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 12) && (j <= 13)) { + if (j & 1) + buf[pos++] = ((dev->cur_speed * 176) & 0xff); + else + buf[pos++] = ((dev->cur_speed * 176) >> 8); + } else + buf[pos++] = cdrom_mode_sense_read(id, page_control, i, 2 + j); + } } } } @@ -852,6 +866,7 @@ static void cdrom_command_common(uint8_t id) dev->callback = 0LL; } else { switch(dev->current_cdb[0]) { + case GPCMD_REZERO_UNIT: case 0x0b: case 0x2b: /* Seek time is in us. */ @@ -877,7 +892,7 @@ static void cdrom_command_common(uint8_t id) case 0xbe: /* bytes_per_second = 150.0 * 1024.0; */ bytes_per_second = (1000000.0 / 12000.0) * 2048.0; /* Account for seek time. */ - bytes_per_second *= (double) cdrom_drives[id].speed; + bytes_per_second *= (double) dev->cur_speed; break; default: bytes_per_second = cdrom_bus_speed(id); @@ -1434,6 +1449,8 @@ void cdrom_insert(uint8_t id) cdrom_t *dev = cdrom[id]; dev->unit_attention = 1; + + cdrom_log("CD-ROM %i: Media insert\n", id); } /*SCSI Sense Initialization*/ @@ -1500,7 +1517,7 @@ skip_ready_check: /* Only increment the unit attention phase if the command can not pass through it. */ if (!(cdrom_command_flags[cdb[0]] & ALLOW_UA)) { /* cdrom_log("CD-ROM %i: Unit attention now 2\n", id); */ - dev->unit_attention = 2; + dev->unit_attention++; cdrom_log("CD-ROM %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", id, cdb[0]); cdrom_unit_attention(id); return 0; @@ -1574,6 +1591,9 @@ void cdrom_reset(uint8_t id) { cdrom_t *dev = cdrom[id]; + if (!dev) + return; + cdrom_rezero(id); dev->status = 0; dev->callback = 0LL; @@ -1771,6 +1791,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) if (cdrom_drives[id].handler->stop) cdrom_drives[id].handler->stop(id); dev->sector_pos = dev->sector_len = 0; + dev->seek_diff = dev->seek_pos; cdrom_seek(id, 0); cdrom_set_phase(id, SCSI_PHASE_STATUS); break; @@ -1788,6 +1809,11 @@ void cdrom_command(uint8_t id, uint8_t *cdb) case GPCMD_SET_SPEED: case GPCMD_SET_SPEED_ALT: + dev->cur_speed = (cdb[3] | (cdb[2] << 8)) / 176; + if (dev->cur_speed < 1) + dev->cur_speed = 1; + else if (dev->cur_speed > cdrom_drives[id].speed) + dev->cur_speed = cdrom_drives[id].speed; cdrom_set_phase(id, SCSI_PHASE_STATUS); cdrom_command_complete(id); break; diff --git a/src/cdrom/cdrom.h b/src/cdrom/cdrom.h index f6a21402a..9b2e97e59 100644 --- a/src/cdrom/cdrom.h +++ b/src/cdrom/cdrom.h @@ -9,7 +9,7 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)cdrom.h 1.0.8 2018/03/17 + * Version: @(#)cdrom.h 1.0.9 2018/03/18 * * Author: Miran Grca, * @@ -165,6 +165,8 @@ typedef struct { int handler_inited; int disc_changed; + + int cur_speed; } cdrom_t; typedef struct { @@ -249,6 +251,7 @@ extern void cdrom_set_signature(int id); extern void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length); extern void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks); extern void cdrom_insert(uint8_t id); +extern void cdrom_new_image(uint8_t id); extern int find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun); extern int cdrom_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len); diff --git a/src/cdrom/cdrom_dosbox.cpp b/src/cdrom/cdrom_dosbox.cpp index 99e966640..a7347abf7 100644 --- a/src/cdrom/cdrom_dosbox.cpp +++ b/src/cdrom/cdrom_dosbox.cpp @@ -58,41 +58,41 @@ CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) { memset(fn, 0, sizeof(fn)); strcpy(fn, filename); - error = false; + file = fopen64(fn, "rb"); + if (file == NULL) + error = true; + else + error = false; } CDROM_Interface_Image::BinaryFile::~BinaryFile() { + fclose(file); + file = NULL; memset(fn, 0, sizeof(fn)); } bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, uint64_t seek, uint64_t count) { - file = fopen64(fn, "rb"); - if (file == NULL) return 0; fseeko64(file, seek, SEEK_SET); fread(buffer, 1, count, file); - fclose(file); return 1; } uint64_t CDROM_Interface_Image::BinaryFile::getLength() { - uint64_t ret = 0; - file = fopen64(fn, "rb"); - if (file == NULL) return 0; fseeko64(file, 0, SEEK_END); - ret = ftello64(file); - fclose(file); - return ret; + return ftello64(file); } CDROM_Interface_Image::CDROM_Interface_Image() { + printf("CDROM_Interface_Image constructor\n"); } CDROM_Interface_Image::~CDROM_Interface_Image() { + printf("CDROM_Interface_Image destructor\n"); ClearTracks(); } @@ -357,6 +357,7 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) ifstream in; in.open(cuefile, ios::in); if (in.fail()) return false; + int last_attr; while(!in.eof()) { // get next line @@ -427,6 +428,7 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) track.attr = DATA_TRACK; track.mode2 = true; } else success = false; + last_attr = track.attr; canAddTrack = true; } @@ -479,7 +481,8 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) track.number++; track.track_number = 0xAA; // track.attr = 0;//sync with load iso - track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ + // track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ + track.attr = last_attr | 0x02; track.start = 0; track.length = 0; track.file = NULL; diff --git a/src/cdrom/cdrom_image.cc b/src/cdrom/cdrom_image.cc index afd335497..50cee9e20 100644 --- a/src/cdrom/cdrom_image.cc +++ b/src/cdrom/cdrom_image.cc @@ -68,6 +68,7 @@ void image_audio_callback(uint8_t id, int16_t *output, int len) { cdrom_t *dev = cdrom[id]; + return; if (!cdrom_drives[id].sound_on || (dev->cd_state != CD_PLAYING) || cdrom_image[id].image_is_iso) { cdrom_image_log("image_audio_callback(i): Not playing\n", id); @@ -216,12 +217,6 @@ static int image_ready(uint8_t id) return 1; } - if (dev->disc_changed) - { - dev->disc_changed = 0; - return 1; - } - return 1; } @@ -267,12 +262,6 @@ static int image_medium_changed(uint8_t id) cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; return 1; } - - if (dev->disc_changed) - { - dev->disc_changed = 0; - return 1; - } return 0; } @@ -848,7 +837,7 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, uint32_t temp; int first_track; - int last_track; + int last_track, last_track_pos; int number; unsigned char attr; TMSF tmsf; @@ -881,6 +870,7 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, break; cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + last_track_pos = 0; b[len++] = 0; /* reserved */ b[len++] = attr; b[len++] = number; /* track number */ @@ -971,10 +961,8 @@ static int image_readtoc_raw(uint8_t id, unsigned char *b, int maxlen) cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); - if (maxlen >= 3) b[2] = first_track; - if (maxlen >= 4) b[3] = last_track; - - if (maxlen <= 4) return len; + b[2] = first_track; + b[3] = last_track; for (track = first_track; track <= last_track; track++) { @@ -1057,18 +1045,7 @@ int image_open(uint8_t id, wchar_t *fn) { cdrom_t *dev = cdrom[id]; - if (wcscmp(fn, cdrom_image[id].image_path) != 0) - { - dev->disc_changed = 1; - } - - /* Make sure image_changed stays when changing from an image to another image. */ - if (!dev->handler_inited && (cdrom_drives[id].host_drive != 200)) dev->disc_changed = 0; - - if (!dev->handler_inited || dev->disc_changed) - { - wcscpy(cdrom_image[id].image_path, fn); - } + wcscpy(cdrom_image[id].image_path, fn); if (! wcscasecmp(plat_get_extension(fn), L"ISO")) { @@ -1080,6 +1057,7 @@ int image_open(uint8_t id, wchar_t *fn) } cdimg[id] = new CDROM_Interface_Image(); + memset(afn, 0, sizeof(afn)); wcstombs(afn, fn, sizeof(afn)); if (!cdimg[id]->SetDevice(afn, false)) { @@ -1093,12 +1071,6 @@ int image_open(uint8_t id, wchar_t *fn) dev->cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0) + 1; cdrom_drives[id].handler = &image_cdrom; - if (!dev->handler_inited || dev->disc_changed) - { - if (!dev->handler_inited) - dev->handler_inited = 1; - } - return 0; } diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 4c8f6c600..a110798db 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -10,7 +10,7 @@ * data in the form of FM/MFM-encoded transitions) which also * forms the core of the emulator's floppy disk emulation. * - * Version: @(#)fdd_86f.c 1.0.17 2018/03/14 + * Version: @(#)fdd_86f.c 1.0.18 2018/03/17 * * Author: Miran Grca, * Copyright 2016-2018 Miran Grca. @@ -51,7 +51,7 @@ uint64_t table[256]; enum { /* 0 ?? ?? ??? */ - STATE_IDLE = 0x00, + STATE_IDLE = 0x00, STATE_SECTOR_NOT_FOUND, /* 1 00 00 ??? */ @@ -206,17 +206,17 @@ typedef struct #pragma pack(push,1) struct { - FILE *f; + 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]; + 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; @@ -728,32 +728,32 @@ uint32_t d86f_header_size(int drive) 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; + 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; + 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) @@ -1102,17 +1102,17 @@ void d86f_put_bit(int drive, int side, int bit) static uint8_t decodefm(int drive, uint16_t dat) { - uint8_t temp = 0; + 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; + 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) @@ -1458,7 +1458,7 @@ void d86f_compare_byte(int drive, uint8_t received_byte, uint8_t disk_byte) /* State 4: Read sector data and CRC*/ void d86f_read_sector_data(int drive, int side) { - int data = 0; + int data = 0; int recv_data = 0; int read_status = 0; uint32_t sector_len = d86f[drive].last_sector.id.n; @@ -1847,7 +1847,7 @@ void d86f_format_turbo_finish(int drive, int side, int do_write) void d86f_format_track(int drive, int side, int do_write) { - int data; + int data; uint16_t max_len; int mfm; @@ -1889,17 +1889,17 @@ void d86f_format_track(int drive, int side, int do_write) max_len = sync_len; if (d86f[drive].datac <= 3) { - data = fdc_getdata(d86f_fdc, 0); + data = fdc_getdata(d86f_fdc, 0); if (data != -1) { data &= 0xff; } - if ((data == -1) && (d86f[drive].datac < 3)) + 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) + if (d86f[drive].datac == 3) { fdc_stop_id_request(d86f_fdc); } @@ -2968,13 +2968,13 @@ void d86f_zero_track(int drive) void d86f_seek(int drive, int track) { int sides; - int side, thin_track; + 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)) + if (!fdd_doublestep_40(drive)) { - track <<= 1; + track <<= 1; for (thin_track = 0; thin_track < sides; thin_track++) { @@ -2993,7 +2993,7 @@ void d86f_seek(int drive, int track) d86f[drive].cur_track = track; - if (!fdd_doublestep_40(drive)) + if (!fdd_doublestep_40(drive)) { for (side = 0; side < sides; side++) { @@ -3059,7 +3059,7 @@ void d86f_set_cur_track(int drive, int track) void d86f_write_tracks(int drive, FILE **f, uint32_t *track_table) { int sides; - int side, thin_track; + int side, thin_track; int logical_track = 0; sides = d86f_get_sides(drive); uint32_t *tbl = d86f[drive].track_offset; @@ -3067,7 +3067,7 @@ void d86f_write_tracks(int drive, FILE **f, uint32_t *track_table) tbl = track_table; int fdd_side = fdd_get_head(drive); - if (!fdd_doublestep_40(drive)) + if (!fdd_doublestep_40(drive)) { for (side = 0; side < sides; side++) { @@ -3135,9 +3135,9 @@ void d86f_writeback(int drive) FILE *cf; header_size = d86f_header_size(drive); - if (!d86f[drive].f) + if (!d86f[drive].f) { - return; + return; } /* First write the track offsets table. */ @@ -3166,10 +3166,10 @@ void d86f_writeback(int drive) 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); + 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) { @@ -3184,15 +3184,15 @@ void d86f_writeback(int drive) void d86f_stop(int drive) { - d86f[drive].state = STATE_IDLE; + d86f[drive].state = STATE_IDLE; } int d86f_common_command(int drive, int sector, int track, int side, int rate, int sector_size) { - 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_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[drive].req_sector.id.c = track; - d86f[drive].req_sector.id.h = side; + 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; @@ -3231,12 +3231,12 @@ void d86f_readsector(int drive, int sector, int track, int side, int rate, int s ret = d86f_common_command(drive, sector, track, side, rate, sector_size); if (!ret) return; - if (sector == SECTOR_FIRST) - d86f[drive].state = STATE_02_SPIN_TO_INDEX; - else if (sector == SECTOR_NEXT) - d86f[drive].state = STATE_02_FIND_ID; + 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); + 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); } void d86f_writesector(int drive, int sector, int track, int side, int rate, int sector_size) @@ -3254,7 +3254,7 @@ void d86f_writesector(int drive, int sector, int track, int side, int rate, int ret = d86f_common_command(drive, sector, track, side, rate, sector_size); if (!ret) return; - d86f[drive].state = fdc_is_deleted(d86f_fdc) ? STATE_09_FIND_ID : STATE_05_FIND_ID; + d86f[drive].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) @@ -3264,7 +3264,7 @@ void d86f_comparesector(int drive, int sector, int track, int side, int rate, in ret = d86f_common_command(drive, sector, track, side, rate, sector_size); if (!ret) return; - d86f[drive].state = STATE_11_FIND_ID; + d86f[drive].state = STATE_11_FIND_ID; } void d86f_readaddress(int drive, int side, int rate) @@ -3283,7 +3283,7 @@ void d86f_readaddress(int drive, int side, int rate) d86f[drive].id_found = 0; d86f[drive].dma_over = 0; - d86f[drive].state = STATE_0A_FIND_ID; + d86f[drive].state = STATE_0A_FIND_ID; } void d86f_add_track(int drive, int track, int side) @@ -3384,7 +3384,7 @@ void d86f_common_format(int drive, int side, int rate, uint8_t fill, int proxy) } } - d86f[drive].fill = fill; + d86f[drive].fill = fill; if (!proxy) { @@ -3423,20 +3423,20 @@ void d86f_format(int drive, int side, int rate, uint8_t fill) 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; + 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; } int d86f_export(int drive, wchar_t *fn) { FILE *f; - uint32_t tt[512]; + uint32_t tt[512]; int tracks = 86; int i; @@ -3506,22 +3506,22 @@ void d86f_load(int drive, wchar_t *fn) 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) + 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; + return; } - writeprot[drive] = 1; - } + writeprot[drive] = 1; + } if (ui_writeprot[drive]) { - writeprot[drive] = 1; + writeprot[drive] = 1; } - fwriteprot[drive] = writeprot[drive]; + fwriteprot[drive] = writeprot[drive]; fseek(d86f[drive].f, 0, SEEK_END); len = ftell(d86f[drive].f); @@ -3620,12 +3620,12 @@ void d86f_load(int drive, wchar_t *fn) fclose(d86f[drive].f); d86f[drive].f = NULL; - d86f[drive].f = plat_fopen(temp_file_name, L"wb"); - if (!d86f[drive].f) - { + 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; + return; } tf = plat_fopen(fn, L"rb"); @@ -3693,7 +3693,7 @@ void d86f_load(int drive, wchar_t *fn) if (!writeprot[drive]) { writeprot[drive] = (d86f[drive].disk_flags & 0x10) ? 1 : 0; - fwriteprot[drive] = writeprot[drive]; + fwriteprot[drive] = writeprot[drive]; } if (writeprot[drive]) @@ -3790,9 +3790,9 @@ void d86f_load(int drive, wchar_t *fn) d86f_register_86f(drive); - drives[drive].seek = d86f_seek; + drives[drive].seek = d86f_seek; d86f_common_handlers(drive); - drives[drive].format = d86f_format; + 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"); } @@ -3801,8 +3801,8 @@ void d86f_init() { int i; - memset(d86f, 0, sizeof(d86f)); - d86f_setupcrc(0x1021); + memset(d86f, 0, sizeof(d86f)); + d86f_setupcrc(0x1021); for (i = 0; i < (FDD_NUM + 1); i++) { @@ -3822,11 +3822,11 @@ void d86f_close(int drive) memcpy(temp_file_name, drive ? nvr_path(L"TEMP$$$1.$$$") : nvr_path(L"TEMP$$$0.$$$"), 26); - if (d86f[drive].f) + if (d86f[drive].f) { - fclose(d86f[drive].f); + fclose(d86f[drive].f); d86f[drive].f = NULL; } if (d86f[drive].is_compressed) - plat_remove(temp_file_name); + plat_remove(temp_file_name); } diff --git a/src/mouse.c b/src/mouse.c index 7c11c6389..1c69a792c 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.21 2018/01/29 + * Version: @(#)mouse.c 1.0.22 2018/03/18 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -75,6 +75,7 @@ static mouse_t mouse_devices[] = { static device_t *mouse_curr; static void *mouse_priv; static int mouse_nbut; +static int (*mouse_dev_poll)(); /* Initialize the mouse module. */ @@ -89,6 +90,7 @@ mouse_init(void) mouse_curr = NULL; mouse_priv = NULL; mouse_nbut = 0; + mouse_dev_poll = NULL; } @@ -100,6 +102,7 @@ mouse_close(void) mouse_curr = NULL; mouse_priv = NULL; mouse_nbut = 0; + mouse_dev_poll = NULL; } @@ -145,8 +148,11 @@ mouse_process(void) mouse_poll(); - if (mouse_curr->available != NULL) { - mouse_curr->available(mouse_x,mouse_y,mouse_z,mouse_buttons, mouse_priv); + if ((mouse_dev_poll != NULL) || (mouse_curr->available != NULL)) { + if (mouse_curr->available != NULL) + mouse_curr->available(mouse_x,mouse_y,mouse_z,mouse_buttons, mouse_priv); + else + mouse_dev_poll(mouse_x,mouse_y,mouse_z,mouse_buttons, mouse_priv); /* Reset mouse deltas. */ mouse_x = mouse_y = mouse_z = 0; @@ -161,7 +167,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_poll = func; mouse_priv = arg; } diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index b9889b579..d78c716b2 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -8,11 +8,11 @@ * * Handle WinPcap library processing. * - * Version: @(#)net_pcap.c 1.0.13 2017/11/04 + * Version: @(#)net_pcap.c 1.0.14 2018/03/18 * * Author: Fred N. van Kempen, * - * Copyright 2017 Fred N. van Kempen. + * Copyright 2017,2018 Fred N. van Kempen. */ #include #include @@ -274,7 +274,7 @@ net_pcap_close(void) * tries to attach to the network module. */ int -net_pcap_reset(netcard_t *card) +net_pcap_reset(netcard_t *card, uint8_t *mac) { char errbuf[PCAP_ERRBUF_SIZE]; char filter_exp[255]; @@ -293,14 +293,11 @@ net_pcap_reset(netcard_t *card) /* 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); @@ -318,7 +315,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 656867aa5..a1f336aa8 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -8,11 +8,11 @@ * * Handle SLiRP library processing. * - * Version: @(#)net_slirp.c 1.0.13 2017/11/04 + * Version: @(#)net_slirp.c 1.0.14 2018/03/18 * * Author: Fred N. van Kempen, * - * Copyright 2017 Fred N. van Kempen. + * Copyright 2017,2018 Fred N. van Kempen. */ #include #include @@ -143,14 +143,14 @@ net_slirp_init(void) /* Initialize SLiRP for use. */ int -net_slirp_reset(netcard_t *card) +net_slirp_reset(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 1c079247b..930b9eea0 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.21 2018/02/18 + * Version: @(#)network.c 1.0.22 2018/03/18 * * Author: Fred N. van Kempen, * @@ -51,12 +51,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 { @@ -98,7 +99,7 @@ network_busy(uint8_t set) thread_set_event(poll_data.wake_poll_thread); } - + void network_end(void) { @@ -149,7 +150,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(); @@ -158,11 +159,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; } } @@ -194,6 +195,7 @@ network_close(void) /* Close the network thread mutex. */ thread_close_mutex(network_mutex); network_mutex = NULL; + network_mac = NULL; pclog("NETWORK: closed.\n"); } diff --git a/src/network/network.h b/src/network/network.h index 28e716be2..65288b503 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.12 2018/02/18 + * Version: @(#)network.h 1.0.13 2018/03/18 * * Author: Fred N. van Kempen, */ @@ -79,12 +79,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(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(netcard_t *, uint8_t *); extern void net_slirp_close(void); extern void net_slirp_in(uint8_t *, int); diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c index 0b50d6e39..9c2ac2593 100644 --- a/src/win/win_stbar.c +++ b/src/win/win_stbar.c @@ -8,7 +8,7 @@ * * Implement the application's Status Bar. * - * Version: @(#)win_stbar.c 1.0.16 2018/03/17 + * Version: @(#)win_stbar.c 1.0.17 2018/03/18 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -1072,10 +1072,6 @@ StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (!file_dlg_w_st(hwnd, IDS_2075, cdrom_image[id].image_path, 0)) { cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; wcscpy(temp_path, wopenfilestring); - if ((wcscmp(cdrom_image[id].image_path, temp_path) == 0) && (cdrom_drives[id].host_drive == 200)) { - /* Switching from image to the same image. Do nothing. */ - break; - } if (!cdrom_image[id].prev_image_path) cdrom_image[id].prev_image_path = (wchar_t *) malloc(1024); wcscpy(cdrom_image[id].prev_image_path, cdrom_image[id].image_path); From b1efb99ed63f127554df68823bc13453614d6b51 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Mar 2018 01:02:04 +0100 Subject: [PATCH 09/39] Applied a whole slew of patches, getting RAM usage down by a further 10 MB. --- src/86box.h | 7 +- src/bugger.c | 10 +- src/bugger.h | 6 +- src/cdrom/cdrom.c | 4 +- src/config.c | 32 +- src/device.c | 171 +- src/device.h | 55 +- src/disk/hdc.c | 16 +- src/disk/hdc.h | 36 +- src/disk/hdc_esdi_at.c | 12 +- src/disk/hdc_esdi_mca.c | 10 +- src/disk/hdc_ide.c | 22 +- src/disk/hdc_mfm_at.c | 10 +- src/disk/hdc_mfm_xt.c | 14 +- src/disk/hdc_xtide.c | 18 +- src/disk/zip.c | 4 +- src/floppy/fdc.c | 57 +- src/floppy/fdc.h | 62 +- src/floppy/fdd.c | 71 +- src/floppy/fdd.h | 271 +- src/floppy/fdd_86f.c | 6932 ++++++++++++------------ src/floppy/fdd_86f.h | 60 +- src/floppy/fdd_common.c | 44 +- src/floppy/fdd_common.h | 47 +- src/floppy/fdd_fdi.c | 589 +- src/floppy/fdd_fdi.h | 53 +- src/floppy/fdd_imd.c | 1483 +++-- src/floppy/fdd_imd.h | 40 +- src/floppy/fdd_img.c | 1888 +++---- src/floppy/fdd_img.h | 46 +- src/floppy/fdd_json.c | 281 +- src/floppy/fdd_json.h | 50 +- src/floppy/fdd_td0.c | 2129 ++++---- src/floppy/fdd_td0.h | 46 +- src/floppy/fdi2raw.c | 63 +- src/floppy/fdi2raw.h | 41 +- src/game/gameport.c | 496 +- src/game/gameport.h | 153 +- src/game/joystick_ch_flightstick_pro.c | 41 +- src/game/joystick_ch_flightstick_pro.h | 39 +- src/game/joystick_standard.c | 47 +- src/game/joystick_standard.h | 45 +- src/game/joystick_sw_pad.c | 87 +- src/game/joystick_sw_pad.h | 39 +- src/game/joystick_tm_fcs.c | 39 +- src/game/joystick_tm_fcs.h | 39 +- src/intel_flash.c | 12 +- src/intel_flash.h | 12 +- src/keyboard.h | 24 +- src/keyboard_at.c | 18 +- src/keyboard_xt.c | 12 +- src/lpt.c | 2 +- src/machine/m_amstrad.c | 10 +- src/machine/m_at.c | 18 +- src/machine/m_at_430fx.c | 16 +- src/machine/m_at_430hx.c | 12 +- src/machine/m_at_430lx_nx.c | 10 +- src/machine/m_at_430vx.c | 10 +- src/machine/m_at_440fx.c | 8 +- src/machine/m_at_4gpv31.c | 4 +- src/machine/m_at_ali1429.c | 2 +- src/machine/m_at_commodore.c | 2 +- src/machine/m_at_compaq.c | 4 +- src/machine/m_at_headland.c | 2 +- src/machine/m_at_neat.c | 4 +- src/machine/m_at_opti495.c | 4 +- src/machine/m_at_scat.c | 6 +- src/machine/m_at_sis_85c471.c | 4 +- src/machine/m_at_sis_85c496.c | 4 +- src/machine/m_at_sis_85c50x.c | 4 +- src/machine/m_at_t3100e.c | 4 +- src/machine/m_at_t3100e.h | 4 +- src/machine/m_at_t3100e_vid.c | 6 +- src/machine/m_at_wd76c10.c | 2 +- src/machine/m_europc.c | 10 +- src/machine/m_europc_hdc.c | 6 +- src/machine/m_olivetti_m24.c | 6 +- src/machine/m_pcjr.c | 10 +- src/machine/m_ps1.c | 14 +- src/machine/m_ps2_isa.c | 2 +- src/machine/m_ps2_mca.c | 14 +- src/machine/m_tandy.c | 20 +- src/machine/m_xt.c | 2 +- src/machine/m_xt_compaq.c | 4 +- src/machine/m_xt_laserxt.c | 2 +- src/machine/m_xt_t1000.c | 10 +- src/machine/m_xt_t1000.h | 6 +- src/machine/m_xt_t1000_vid.c | 10 +- src/machine/m_xt_xi8088.c | 8 +- src/machine/m_xt_xi8088.h | 2 +- src/machine/machine.c | 4 +- src/machine/machine.h | 154 +- src/machine/machine_table.c | 6 +- src/mouse.c | 12 +- src/mouse.h | 18 +- src/mouse_bus.c | 10 +- src/mouse_ps2.c | 8 +- src/mouse_serial.c | 10 +- src/network/bswap.h | 43 +- src/network/net_ne2000.c | 177 +- src/network/net_ne2000.h | 52 +- src/network/net_pcap.c | 58 +- src/network/net_slirp.c | 46 +- src/network/network.c | 176 +- src/network/network.h | 80 +- src/network/pcap_if.c | 46 +- src/network/slirp/debug.c | 2 + src/nvr_ps2.c | 6 +- src/nvr_ps2.h | 4 +- src/pc.c | 3 +- src/plat_joystick.h | 65 - src/scsi/scsi.c | 12 +- src/scsi/scsi.h | 4 +- src/scsi/scsi_aha154x.c | 16 +- src/scsi/scsi_aha154x.h | 8 +- src/scsi/scsi_buslogic.c | 18 +- src/scsi/scsi_buslogic.h | 16 +- src/scsi/scsi_disk.c | 4 +- src/scsi/scsi_ncr5380.c | 14 +- src/scsi/scsi_ncr5380.h | 12 +- src/scsi/scsi_ncr53c810.c | 6 +- src/scsi/scsi_ncr53c810.h | 10 +- src/scsi/scsi_x54x.c | 4 +- src/scsi/scsi_x54x.h | 4 +- src/sound/midi.c | 6 +- src/sound/midi.h | 2 +- src/sound/midi_fluidsynth.c | 6 +- src/sound/midi_fluidsynth.h | 2 +- src/sound/midi_mt32.c | 10 +- src/sound/midi_mt32.h | 4 +- src/sound/midi_system.c | 6 +- src/sound/midi_system.h | 2 +- src/sound/snd_adlib.c | 8 +- src/sound/snd_adlib.h | 4 +- src/sound/snd_adlibgold.c | 6 +- src/sound/snd_adlibgold.h | 2 +- src/sound/snd_audiopci.c | 2 +- src/sound/snd_audiopci.h | 2 +- src/sound/snd_cms.c | 4 +- src/sound/snd_cms.h | 2 +- src/sound/snd_gus.c | 4 +- src/sound/snd_gus.h | 2 +- src/sound/snd_mpu401.c | 14 +- src/sound/snd_mpu401.h | 12 +- src/sound/snd_pas16.c | 4 +- src/sound/snd_pas16.h | 2 +- src/sound/snd_pssj.c | 4 +- src/sound/snd_pssj.h | 2 +- src/sound/snd_sb.c | 30 +- src/sound/snd_sb.h | 24 +- src/sound/snd_sn76489.c | 8 +- src/sound/snd_sn76489.h | 4 +- src/sound/snd_ssi2001.c | 4 +- src/sound/snd_ssi2001.h | 2 +- src/sound/snd_wss.c | 4 +- src/sound/snd_wss.h | 2 +- src/sound/sound.c | 8 +- src/sound/sound.h | 4 +- src/video/vid_ati18800.c | 10 +- src/video/vid_ati18800.h | 6 +- src/video/vid_ati28800.c | 18 +- src/video/vid_ati28800.h | 8 +- src/video/vid_ati_mach64.c | 20 +- src/video/vid_ati_mach64.h | 10 +- src/video/vid_cga.c | 8 +- src/video/vid_cga.h | 10 +- src/video/vid_cl54xx.c | 30 +- src/video/vid_cl54xx.h | 22 +- src/video/vid_colorplus.c | 12 +- src/video/vid_colorplus.h | 2 +- src/video/vid_compaq_cga.c | 8 +- src/video/vid_compaq_cga.h | 4 +- src/video/vid_ega.c | 16 +- src/video/vid_ega.h | 8 +- src/video/vid_et4000.c | 6 +- src/video/vid_et4000.h | 2 +- src/video/vid_et4000w32.c | 14 +- src/video/vid_et4000w32.h | 8 +- src/video/vid_genius.c | 10 +- src/video/vid_genius.h | 2 +- src/video/vid_hercules.c | 12 +- src/video/vid_hercules.h | 2 +- src/video/vid_herculesplus.c | 10 +- src/video/vid_herculesplus.h | 2 +- src/video/vid_incolor.c | 10 +- src/video/vid_incolor.h | 2 +- src/video/vid_mda.c | 12 +- src/video/vid_mda.h | 2 +- src/video/vid_nv_riva128.c | 26 +- src/video/vid_nv_riva128.h | 6 +- src/video/vid_oak_oti.c | 14 +- src/video/vid_oak_oti.h | 8 +- src/video/vid_paradise.c | 36 +- src/video/vid_paradise.h | 12 +- src/video/vid_s3.c | 58 +- src/video/vid_s3.h | 30 +- src/video/vid_s3_virge.c | 34 +- src/video/vid_s3_virge.h | 16 +- src/video/vid_t1000.c | 721 --- src/video/vid_t1000.h | 5 - src/video/vid_t3100e.c | 726 --- src/video/vid_t3100e.h | 4 - src/video/vid_table.c | 6 +- src/video/vid_tgui9440.c | 16 +- src/video/vid_tgui9440.h | 6 +- src/video/vid_ti_cf62011.c | 10 +- src/video/vid_ti_cf62011.h | 4 +- src/video/vid_tvga.c | 8 +- src/video/vid_tvga.h | 2 +- src/video/vid_vga.c | 14 +- src/video/vid_vga.h | 8 +- src/video/vid_voodoo.c | 8 +- src/video/vid_voodoo.h | 2 +- src/video/vid_wy700.c | 10 +- src/video/vid_wy700.h | 2 +- src/video/video.c | 2 +- src/video/video.h | 4 +- src/win/win.h | 4 +- src/win/win_devconf.c | 22 +- src/win/win_joystick.cpp | 7 +- src/win/win_jsconf.c | 1 - src/win/win_settings.c | 39 +- 222 files changed, 9538 insertions(+), 9980 deletions(-) delete mode 100644 src/plat_joystick.h delete mode 100644 src/video/vid_t1000.c delete mode 100644 src/video/vid_t1000.h delete mode 100644 src/video/vid_t3100e.c delete mode 100644 src/video/vid_t3100e.h diff --git a/src/86box.h b/src/86box.h index 19ffc1e30..7998741cf 100644 --- a/src/86box.h +++ b/src/86box.h @@ -8,7 +8,7 @@ * * Main include file for the application. * - * Version: @(#)86box.h 1.0.19 2018/03/17 + * Version: @(#)86box.h 1.0.20 2018/03/18 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -90,11 +90,11 @@ extern int vid_cga_contrast, /* (C) video */ video_fullscreen_scale, /* (C) video */ enable_overscan, /* (C) video */ force_43, /* (C) video */ + gfxcard, /* (C) graphics/video card */ video_speed; /* (C) video */ extern int serial_enabled[], /* (C) enable serial ports */ lpt_enabled, /* (C) enable LPT ports */ bugger_enabled; /* (C) enable ISAbugger */ -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 */ @@ -106,6 +106,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/bugger.c b/src/bugger.c index 7f2ced877..f70a25c6e 100644 --- a/src/bugger.c +++ b/src/bugger.c @@ -44,10 +44,10 @@ * configuration register (CTRL_SPCFG bit set) but have to * remember that stuff first... * - * Version: @(#)bugger.c 1.0.9 2017/10/28 + * Version: @(#)bugger.c 1.0.10 2018/03/18 * * Author: Fred N. van Kempen, - * Copyright 1989-2017 Fred N. van Kempen. + * Copyright 1989-2018 Fred N. van Kempen. */ #include #include @@ -309,7 +309,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); @@ -320,7 +320,7 @@ bug_init(device_t *info) bug_read, NULL, NULL, bug_write, NULL, NULL, NULL); /* Just so its not NULL. */ - return(info); + return(&bug_ctrl); } @@ -333,7 +333,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 0726d8b01..d3a1ac775 100644 --- a/src/bugger.h +++ b/src/bugger.h @@ -15,11 +15,11 @@ * * Definitions for the BUGGER card. * - * Version: @(#)bugger.h 1.0.5 2017/10/28 + * Version: @(#)bugger.h 1.0.6 2018/03/18 * * Author: Fred N. van Kempen, * - * Copyright 1989-2017 Fred N. van Kempen. + * Copyright 1989-2018 Fred N. van Kempen. */ #ifndef BUGGER_H # define BUGGER_H @@ -35,7 +35,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 cc7391a0d..437b686cd 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.40 2018/03/18 + * Version: @(#)cdrom.c 1.0.41 2018/03/18 * * Author: Miran Grca, * @@ -97,7 +97,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 c6d348bc5..494600002 100644 --- a/src/config.c +++ b/src/config.c @@ -8,7 +8,7 @@ * * Configuration file handler. * - * Version: @(#)config.c 1.0.45 2018/03/17 + * Version: @(#)config.c 1.0.46 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -55,7 +55,6 @@ #include "sound/sound.h" #include "video/video.h" #include "plat.h" -#include "plat_joystick.h" #include "plat_midi.h" #include "ui.h" @@ -649,22 +648,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_host_device", NULL); + if (p != NULL) + config_delete_var(cat, "net_host_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) @@ -1752,14 +1756,14 @@ 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_set_string(cat, "net_host_device", "none"); */ + config_delete_var(cat, "net_host_device"); } if (network_card == 0) diff --git a/src/device.c b/src/device.c index 0e057cd53..98f665a5e 100644 --- a/src/device.c +++ b/src/device.c @@ -1,21 +1,41 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Implementation of the generic device interface to handle * all devices attached to the emulator. * - * Version: @(#)device.c 1.0.9 2018/03/02 + * Version: @(#)device.c 1.0.5 2018/03/18 * - * Authors: Sarah Walker, + * Authors: Fred N. van Kempen, * Miran Grca, + * Sarah Walker, * - * Copyright 2008-2018 Sarah Walker. + * Copyright 2017,2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #include #include @@ -32,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; @@ -45,48 +65,49 @@ 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) { - fatal("device_add: device already exists!\n"); - break; + if (devices[c] == (device_t *)d) { + pclog("DEVICE: device already exists!\n"); + return(NULL); } if (devices[c] == NULL) break; } if (c >= DEVICE_MAX) - fatal("device_add: too many devices\n"); + fatal("DEVICE: too many devices\n"); - device_current = d; + device_current = (device_t *)d; if (d->init != NULL) { priv = d->init(d); if (priv == NULL) { if (d->name) - fatal("device_add: device init failed (%s)\n", d->name); - else - fatal("device_add: device init failed\n"); + pclog("DEVICE: device '%s' init failed\n", d->name); + else + pclog("DEVICE: device init failed\n"); + return(NULL); } } - devices[c] = d; + devices[c] = (device_t *)d; device_priv[c] = priv; - return priv; + return(priv); } /* 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; } @@ -95,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; } @@ -132,7 +153,7 @@ device_reset_all(void) void * -device_get_priv(device_t *d) +device_get_priv(const device_t *d) { int c; @@ -148,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); @@ -207,11 +228,11 @@ 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)) - return(config_get_string((char *) device_current->name, s, (char *) c->default_string)); + return(config_get_string((char *)device_current->name, s, (char *)c->default_string)); c++; } @@ -223,11 +244,11 @@ 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)) - return(config_get_int((char *) device_current->name, s, c->default_int)); + return(config_get_int((char *)device_current->name, s, c->default_int)); c++; } @@ -239,11 +260,11 @@ 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)) - return(config_get_int((char *) device_current->name, s, default_int)); + return(config_get_int((char *)device_current->name, s, default_int)); c++; } @@ -255,11 +276,11 @@ 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)) - return(config_get_hex16((char *) device_current->name, s, c->default_int)); + return(config_get_hex16((char *)device_current->name, s, c->default_int)); c++; } @@ -271,11 +292,11 @@ 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)) - return(config_get_hex20((char *) device_current->name, s, c->default_int)); + return(config_get_hex20((char *)device_current->name, s, c->default_int)); c++; } @@ -287,11 +308,11 @@ 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)) - return(config_get_mac((char *) device_current->name, s, default_int)); + return(config_get_mac((char *)device_current->name, s, default_int)); c++; } @@ -303,11 +324,11 @@ 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)) { - config_set_int((char *) device_current->name, s, val); + config_set_int((char *)device_current->name, s, val); break; } @@ -319,11 +340,11 @@ 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)) { - config_set_hex16((char *) device_current->name, s, val); + config_set_hex16((char *)device_current->name, s, val); break; } @@ -335,11 +356,11 @@ 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)) { - config_set_hex20((char *) device_current->name, s, val); + config_set_hex20((char *)device_current->name, s, val); break; } @@ -351,11 +372,11 @@ 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)) { - config_set_mac((char *) device_current->name, s, val); + config_set_mac((char *)device_current->name, s, val); break; } @@ -365,65 +386,43 @@ device_set_config_mac(char *s, int val) int -device_is_valid(device_t *device, int machine_flags) +device_is_valid(const device_t *device, int mflags) { - if (!device) - { - return 1; - } + if (device == NULL) return(1); - if ((device->flags & DEVICE_AT) && !(machine_flags & MACHINE_AT)) { - return 0; - } + if ((device->flags & DEVICE_AT) && !(mflags & MACHINE_AT)) return(0); - if ((device->flags & DEVICE_CBUS) && !(machine_flags & MACHINE_CBUS)) { - return 0; - } + if ((device->flags & DEVICE_CBUS) && !(mflags & MACHINE_CBUS)) return(0); - if ((device->flags & DEVICE_ISA) && !(machine_flags & MACHINE_ISA)) { - return 0; - } + if ((device->flags & DEVICE_ISA) && !(mflags & MACHINE_ISA)) return(0); - if ((device->flags & DEVICE_MCA) && !(machine_flags & MACHINE_MCA)) { - return 0; - } + if ((device->flags & DEVICE_MCA) && !(mflags & MACHINE_MCA)) return(0); - if ((device->flags & DEVICE_EISA) && !(machine_flags & MACHINE_EISA)) { - return 0; - } + if ((device->flags & DEVICE_EISA) && !(mflags & MACHINE_EISA)) return(0); - if ((device->flags & DEVICE_VLB) && !(machine_flags & MACHINE_VLB)) { - return 0; - } + if ((device->flags & DEVICE_VLB) && !(mflags & MACHINE_VLB)) return(0); - if ((device->flags & DEVICE_PCI) && !(machine_flags & MACHINE_PCI)) { - return 0; - } + if ((device->flags & DEVICE_PCI) && !(mflags & MACHINE_PCI)) return(0); - if ((device->flags & DEVICE_PS2) && !(machine_flags & MACHINE_HDC_PS2)) { - return 0; - } + if ((device->flags & DEVICE_PS2) && !(mflags & MACHINE_HDC_PS2)) return(0); + if ((device->flags & DEVICE_AGP) && !(mflags & MACHINE_AGP)) return(0); - if ((device->flags & DEVICE_AGP) && !(machine_flags & MACHINE_AGP)) { - return 0; - } - - return 1; + return(1); } 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); c = d->config; while (c && c->type != -1) { if (! strcmp(s, c->name)) - return(config_get_int((char *) d->name, s, c->default_int)); + return(config_get_int((char *)d->name, s, c->default_int)); c++; } @@ -435,15 +434,15 @@ 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); c = d->config; while (c && c->type != -1) { if (! strcmp(s, c->name)) - return(config_get_string((char *) d->name, s, (char *) c->default_string)); + return(config_get_string((char *)d->name, s, (char *)c->default_string)); c++; } diff --git a/src/device.h b/src/device.h index 5c55c7992..32f803aff 100644 --- a/src/device.h +++ b/src/device.h @@ -1,23 +1,40 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * - * Implementation of the generic device interface to handle - * all devices attached to the emulator. + * Definitions for the device handler. * - * Version: @(#)device.h 1.0.8 2018/02/18 + * Version: @(#)device.h 1.0.3 2018/03/15 * - * Authors: Sarah Walker, + * Authors: Fred N. van Kempen, * Miran Grca, - * Fred N. van Kempen, + * Sarah Walker, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #ifndef EMU_DEVICE_H # define EMU_DEVICE_H @@ -81,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*/); @@ -89,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; @@ -98,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); @@ -118,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 e11c80367..809b82592 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.10 2018/03/17 + * Version: @(#)hdc.c 1.0.11 2018/03/18 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -32,7 +32,7 @@ int hdc_current; static void * -null_init(device_t *info) +null_init(const device_t *info) { return(NULL); } @@ -44,7 +44,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 @@ -52,7 +52,7 @@ static device_t null_device = { static void * -inthdc_init(device_t *info) +inthdc_init(const device_t *info) { return(NULL); } @@ -64,17 +64,17 @@ 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 { +static const struct { char *name; char *internal_name; - device_t *device; + const device_t *device; int is_mfm; } controllers[] = { { "None", "none", @@ -185,7 +185,7 @@ hdc_get_internal_name(int hdc) } -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 3066a579b..5f4f9a934 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.5 2018/02/14 + * Version: @(#)hdc.h 1.0.6 2018/03/18 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -32,25 +32,25 @@ 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); @@ -58,7 +58,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 6dc05e237..fe8dd1870 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -8,15 +8,15 @@ * * Driver for the ESDI controller (WD1007-vse1) for PC/AT. * - * Version: @(#)hdc_esdi_at.c 1.0.8 2017/11/08 + * Version: @(#)hdc_esdi_at.c 1.0.9 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - * Copyright 2017 Fred N. van Kempen. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. */ #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE @@ -770,7 +770,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; @@ -835,7 +835,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 c2d0bf5c2..b7dbeb515 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -52,13 +52,13 @@ * however, are auto-configured by the system software as * shown above. * - * Version: @(#)hdc_esdi_mca.c 1.0.8 2017/11/04 + * Version: @(#)hdc_esdi_mca.c 1.0.9 2018/03/18 * * Authors: Sarah Walker, * Fred N. van Kempen, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2017 Fred N. van Kempen. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2017,2018 Fred N. van Kempen. */ #include #include @@ -1041,7 +1041,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; @@ -1135,7 +1135,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 6d42a91ce..889058198 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.39 2018/03/17 + * Version: @(#)hdc_ide.c 1.0.40 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -2856,12 +2856,12 @@ void secondary_ide_check(void) * Initialization of standalone IDE controller instance. * * Eventually, we should clean up the whole mess by only - * using device_t units, with configuration parameters to + * using const device_t units, with configuration parameters to * indicate primary/secondary and all that, rather than * 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 */ @@ -2891,7 +2891,7 @@ ide_sainit(device_t *info) break; } - return(info); + return(ide_drives); } @@ -2903,7 +2903,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, @@ -2912,7 +2912,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, @@ -2921,7 +2921,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, @@ -2930,7 +2930,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, @@ -2939,7 +2939,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, @@ -2948,7 +2948,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, @@ -2957,7 +2957,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_mfm_at.c b/src/disk/hdc_mfm_at.c index 907338b6a..0879c75b5 100644 --- a/src/disk/hdc_mfm_at.c +++ b/src/disk/hdc_mfm_at.c @@ -12,13 +12,13 @@ * 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.12 2017/12/09 + * Version: @(#)hdc_mfm_at.c 1.0.13 2018/03/18 * * Authors: Sarah Walker, * Fred N. van Kempen, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2017 Fred N. van Kempen. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2017,2018 Fred N. van Kempen. */ #define __USE_LARGEFILE64 #define _LARGEFILE_SOURCE @@ -707,7 +707,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; @@ -764,7 +764,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 798fa526a..2eb2fd2c4 100644 --- a/src/disk/hdc_mfm_xt.c +++ b/src/disk/hdc_mfm_xt.c @@ -41,13 +41,13 @@ * 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.13 2017/11/06 + * Version: @(#)hdc_mfm_xt.c 1.0.14 2018/03/18 * * Authors: Sarah Walker, * Fred N. van Kempen, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2017 Fred N. van Kempen. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2017,2018 Fred N. van Kempen. */ #define __USE_LARGEFILE64 #define _LARGEFILE_SOURCE @@ -808,7 +808,7 @@ mfm_set_switches(mfm_t *mfm) static void * -xebec_init(device_t *info) +xebec_init(const device_t *info) { int i, c = 0; @@ -863,7 +863,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, @@ -874,7 +874,7 @@ device_t mfm_xt_xebec_device = { static void * -dtc5150x_init(device_t *info) +dtc5150x_init(const device_t *info) { int i, c = 0; @@ -918,7 +918,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 6948869f8..bc4cdcd92 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.11 2018/02/14 + * Version: @(#)hdc_xtide.c 1.0.11 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -127,7 +127,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)); @@ -154,7 +154,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)); @@ -177,7 +177,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)); @@ -204,7 +204,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)); @@ -235,7 +235,7 @@ xtide_close(void *priv) } -device_t xtide_device = { +const device_t xtide_device = { "XTIDE", DEVICE_ISA, 0, @@ -244,7 +244,7 @@ device_t xtide_device = { NULL }; -device_t xtide_at_device = { +const device_t xtide_at_device = { "XTIDE (AT)", DEVICE_ISA | DEVICE_AT, 0, @@ -253,7 +253,7 @@ device_t xtide_at_device = { NULL }; -device_t xtide_acculogic_device = { +const device_t xtide_acculogic_device = { "XTIDE (Acculogic)", DEVICE_ISA, 0, @@ -262,7 +262,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/disk/zip.c b/src/disk/zip.c index 86f1dd3c7..a02f64204 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -9,7 +9,7 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.c 1.0.12 2018/03/17 + * Version: @(#)zip.c 1.0.13 2018/03/18 * * Author: Miran Grca, * @@ -70,7 +70,7 @@ uint8_t scsi_zip_drives[16][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0 /* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ -uint8_t zip_command_flags[0x100] = +const uint8_t zip_command_flags[0x100] = { IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 04b9c118b..ab4e8c4ef 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -1,21 +1,39 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Implementation of the NEC uPD-765 and compatible floppy disk * controller. * - * Version: @(#)fdc->c 1.0.18 2018/03/08 + * Version: @(#)fdc.c 1.0.5 2018/03/16 * - * Authors: Sarah Walker, - * Miran Grca, + * Authors: Miran Grca, + * Sarah Walker, * - * Copyright 2008-2018 Sarah Walker. * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #include #include @@ -42,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, @@ -1147,7 +1165,6 @@ fdc_read(uint16_t addr, void *priv) { fdc_t *fdc = (fdc_t *) priv; uint8_t ret; - int drive; cycles -= ISA_CYCLES(8); @@ -2020,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)); @@ -2058,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, @@ -2068,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, @@ -2078,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, @@ -2088,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, @@ -2098,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, @@ -2108,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, @@ -2118,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, @@ -2128,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 4f59828b5..0d540e918 100644 --- a/src/floppy/fdc.h +++ b/src/floppy/fdc.h @@ -1,20 +1,41 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Implementation of the NEC uPD-765 and compatible floppy disk * controller. * - * Version: @(#)fdc.h 1.0.5 2018/03/02 + * Version: @(#)fdc.h 1.0.3 2018/03/17 * - * Authors: Sarah Walker, + * Authors: Fred N. van Kempen, * Miran Grca, - * Copyright 2008-2018 Sarah Walker. + * Sarah Walker, + * + * Copyright 2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #ifndef EMU_FDC_H # define EMU_FDC_H @@ -29,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]; @@ -79,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); @@ -148,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); @@ -156,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 a309e7e3a..006a6ed87 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -1,20 +1,40 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Implementation of the floppy drive emulation. * - * Version: @(#)fdd.c 1.0.9 2018/03/14 + * Version: @(#)fdd.c 1.0.5 2018/03/16 * - * Authors: Sarah Walker, + * Authors: Fred N. van Kempen, * Miran Grca, + * Sarah Walker, * - * Copyright 2008-2018 Sarah Walker. + * Copyright 2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #include #include @@ -66,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); @@ -150,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; @@ -207,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) @@ -221,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++; } @@ -433,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; @@ -447,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); @@ -456,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])); @@ -465,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; @@ -526,18 +551,7 @@ double fdd_real_period(int drive) return (32.0 * dusec); } -#if defined(DEV_BRANCH) && defined(USE_MRTHOR) - if (romset == ROM_MRTHOR) - { - return (ddbp * dusec) / 4.0; - } - else - { - return (ddbp * dusec); - } -#else return (ddbp * dusec); -#endif } void fdd_poll(int drive) @@ -705,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 f4a26e988..7610cee46 100644 --- a/src/floppy/fdd.h +++ b/src/floppy/fdd.h @@ -1,34 +1,54 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * - * Implementation of the floppy drive emulation. + * Definitions for the floppy drive emulation. * - * Version: @(#)fdd.h 1.0.5 2018/01/18 + * Version: @(#)fdd.h 1.0.3 2018/03/17 * - * Authors: Sarah Walker, + * Authors: Fred N. van Kempen, * Miran Grca, + * Sarah Walker, * - * Copyright 2008-2018 Sarah Walker. + * Copyright 2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #ifndef EMU_FDD_H # 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); @@ -65,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; @@ -115,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]; @@ -176,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); @@ -271,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 a110798db..21500c44d 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -1,19 +1,40 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Implementation of the 86F floppy image format (stores the * 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.18 2018/03/17 + * 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 + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #include #include @@ -22,7 +43,6 @@ #include #include #include -#include "../lzf/lzf.h" #define HAVE_STDARG_H #include "../86box.h" #include "../config.h" @@ -34,317 +54,221 @@ #include "fdd.h" #include "fdc.h" #include "fdd_86f.h" +#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 void -d86f_log(const char *format, ...) -{ -#ifdef ENABLE_D86F_LOG - va_list ap; +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 +}; - if (d86f_do_log) - { - va_start(ap, format); - pclog_ex(format, ap); - va_end(ap); - } -#endif -} +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]; -void d86f_initialize_linked_lists(int drive) -{ - d86f[drive].last_side_sector[0] = NULL; - d86f[drive].last_side_sector[1] = NULL; -} - -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; - } -} - -static void d86f_setupcrc(uint16_t poly) -{ - int c = 256, bc; - uint16_t crctemp; - - while(c--) - { - crctemp = c << 8; - bc = 8; - - while(bc--) - { - if(crctemp & 0x8000) - { - crctemp = (crctemp << 1) ^ poly; - } - else - { - crctemp <<= 1; - } - } - - CRCTable[c] = crctemp; - } -} - -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); @@ -352,3481 +276,3529 @@ 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) + +static void +d86f_log(const char *format, ...) { - return d86f[drive].disk_flags; +#ifdef ENABLE_D86F_LOG + va_list ap; + + if (d86f_do_log) { + va_start(ap, format); + pclog_ex(format, ap); + va_end(ap); + } +#endif } -uint32_t d86f_index_hole_pos(int drive, int side) +static void +setup_crc(uint16_t poly) { - return d86f[drive].index_hole_pos[side]; -} + int c = 256, bc; + uint16_t temp; -uint32_t null_index_hole_pos(int drive, int side) -{ - return 0; -} + while(c--) { + temp = c << 8; + bc = 8; -uint16_t null_disk_flags(int drive) -{ - return 0x09; -} + while (bc--) { + if (temp & 0x8000) + temp = (temp << 1) ^ poly; + else + temp <<= 1; -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) -{ - 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; + CRCTable[c] = temp; } - return tf; + } } -uint32_t common_get_raw_size(int drive, int side) + +void +d86f_destroy_linked_lists(int drive, int side) { - double rate = 0.0; - int mfm = 0; - double rpm; - double rpm_diff = 0.0; - double size = 100000.0; + d86f_t *dev = d86f[drive]; + sector_t *s, *t; - mfm = d86f_is_mfm(drive); - rpm = ((d86f_track_flags(drive) & 0xE0) == 0x20) ? 360.0 : 300.0; - rpm_diff = 1.0; + if (dev == NULL) return; - switch (d86f_get_rpm_mode(drive)) - { - case 1: - rpm_diff = 1.01; + if (dev->last_side_sector[side]) { + s = dev->last_side_sector[side]; + while (s) { + t = s->prev; + free(s); + s = NULL; + if (! t) 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); + s = t; + } + dev->last_side_sector[side] = NULL; + } } -void d86f_set_version(int drive, uint16_t version) + +static int +d86f_has_surface_desc(int drive) { - d86f[drive].version = version; + return (d86f_handler[drive].disk_flags(drive) & 1); } -void d86f_unregister(int drive) + +int +d86f_get_sides(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. */ + return ((d86f_handler[drive].disk_flags(drive) >> 3) & 1) + 1; } -void d86f_register_86f(int drive) + +int +d86f_get_rpm_mode(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; + return (d86f_handler[drive].disk_flags(drive) & 0x60) >> 5; } -int d86f_get_array_size(int drive, int side) +int +d86f_reverse_bytes(int drive) { - 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; + return (d86f_handler[drive].disk_flags(drive) & 0x800) >> 11; } -int d86f_valid_bit_rate(int drive) + +uint16_t +d86f_disk_flags(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; + d86f_t *dev = d86f[drive]; + + return dev->disk_flags; } -int d86f_hole(int drive) + +uint32_t +d86f_index_hole_pos(int drive, int side) { - if (((d86f_handler[drive].disk_flags(drive) >> 1) & 3) == 3) return 2; - return (d86f_handler[drive].disk_flags(drive) >> 1) & 3; + d86f_t *dev = d86f[drive]; + + return dev->index_hole_pos[side]; } -uint8_t d86f_get_encoding(int drive) + +uint32_t +null_index_hole_pos(int drive, int side) { - return (d86f_track_flags(drive) & 0x18) >> 3; + return 0; } -double d86f_byteperiod(int drive) + +uint16_t +null_disk_flags(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; + return 0x09; } -int d86f_is_mfm(int drive) + +uint16_t +null_side_flags(int drive) { - return (d86f_track_flags(drive) & 8) ? 1 : 0; + return 0x0A; } -uint32_t d86f_get_data_len(int drive) + +void +null_writeback(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); + 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; } - else - { - return (128 << ((uint32_t) d86f[drive].req_sector.id.n)); + break; + + default: + tf |= rr; + break; + } + + return tf; +} + + +uint32_t +common_get_raw_size(int drive, int 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); +} + + +void +d86f_set_version(int drive, uint16_t version) +{ + d86f_t *dev = d86f[drive]; + + dev->version = version; +} + + +void +d86f_unregister(int drive) +{ + 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. */ +} + + +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; + int hole, rm; + + 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: + break; } - } -} + break; -uint32_t d86f_has_extra_bit_cells(int drive) -{ - return (d86f_handler[drive].disk_flags(drive) >> 7) & 1; -} + case 2: + array_size = 25000; + switch (rm) { + case 1: + array_size = 25250; + break; -uint32_t d86f_header_size(int drive) -{ - return 8; -} + case 2: + array_size = 25375; + 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 = 25500; + 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); - } + 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: + break; } - } - 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) -{ - int 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; - dpbyte.byte = d86f[drive].preceding_bit[side]; - - 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 < (128 << 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) -{ - int 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) { - int 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) { - int 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); - } - 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, dev->f); } - if (!writeprot[drive]) - { - writeprot[drive] = (d86f[drive].disk_flags & 0x10) ? 1 : 0; - fwriteprot[drive] = writeprot[drive]; + 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); - if (writeprot[drive]) - { - fclose(d86f[drive].f); - d86f[drive].f = NULL; + fclose(tf); + fclose(dev->f); + dev->f = NULL; - 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(d86f[drive].f, 8, SEEK_SET); - - fread(d86f[drive].track_offset, 1, d86f_get_track_table_size(drive), d86f[drive].f); - - 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; - } - - 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"); -} - -void d86f_init() -{ - int i; - - memset(d86f, 0, sizeof(d86f)); - d86f_setupcrc(0x1021); - - for (i = 0; i < (FDD_NUM + 1); i++) - { - d86f[i].state = STATE_IDLE; - d86f_initialize_linked_lists(i); - } -} - -void d86f_set_fdc(void *fdc) -{ - d86f_fdc = (fdc_t *) fdc; -} - -void d86f_close(int drive) -{ - wchar_t temp_file_name[2048]; - - memcpy(temp_file_name, drive ? nvr_path(L"TEMP$$$1.$$$") : nvr_path(L"TEMP$$$0.$$$"), 26); - - if (d86f[drive].f) - { - fclose(d86f[drive].f); - d86f[drive].f = NULL; - } - if (d86f[drive].is_compressed) + if (! temp) { + d86f_log("86F: Error decompressing file\n"); plat_remove(temp_file_name); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + free(dev); + return; + } + + 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; + } + + dev->extra_bit_cells[1] = 0; + } + + fseek(dev->f, 0, SEEK_END); + dev->file_size = ftell(dev->f); + + fseek(dev->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 does%s have surface description data\n", + dev->is_compressed ? "" : "not ", + d86f_has_surface_desc(drive) ? "" : " not"); +} + + +void +d86f_init(void) +{ + int i; + + setup_crc(0x1021); + + for (i = 0; i < FDD_NUM; i++) + d86f[i] = NULL; +} + + +void +d86f_set_fdc(void *fdc) +{ + d86f_fdc = (fdc_t *) fdc; +} + + +void +d86f_close(int drive) +{ + wchar_t temp_file_name[2048]; + d86f_t *dev = d86f[drive]; + + /* Make sure the drive is alive. */ + if (dev == NULL) return; + + 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 f272ff59b..8242f5bb7 100644 --- a/src/floppy/fdd_86f.h +++ b/src/floppy/fdd_86f.h @@ -1,24 +1,46 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * - * Implementation of the 86F floppy image format (stores the - * data in the form of FM/MFM-encoded transitions) which also - * forms the core of the emulator's floppy disk emulation. + * Definitions for the 86F floppy image format. * - * Version: @(#)floppy_86f.h 1.0.5 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 + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #ifndef EMU_FLOPPY_86F_H # 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); @@ -39,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 @@ -59,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 fcd04ab16..5638b0565 100644 --- a/src/floppy/fdd_common.c +++ b/src/floppy/fdd_common.c @@ -1,17 +1,36 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Shared code for all the floppy modules. * - * Version: @(#)fdd_common.c 1.0.5 2018/01/16 + * Version: @(#)fdd_common.c 1.0.2 2018/03/16 * * Author: Fred N. van Kempen, + * * Copyright 2017,2018 Fred N. van Kempen. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #include #include @@ -23,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, @@ -46,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 */ @@ -57,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, @@ -346,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 77d9a4798..02ff78375 100644 --- a/src/floppy/fdd_common.h +++ b/src/floppy/fdd_common.h @@ -1,27 +1,46 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Shared code for all the floppy modules. * - * Version: @(#)fdd_common.h 1.0.2 2018/01/16 + * Version: @(#)fdd_common.h 1.0.2 2018/03/16 * * Author: Fred N. van Kempen, + * * Copyright 2017,2018 Fred N. van Kempen. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ -#ifndef fdd_COMMON_H -# define fdd_COMMON_H +#ifndef FDD_COMMON_H +# 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); @@ -31,4 +50,4 @@ extern int fdd_bps_valid(uint16_t bps); extern int fdd_interleave(int sector, int skew, int spt); -#endif /*fdd_COMMON_H*/ +#endif /*FDD_COMMON_H*/ diff --git a/src/floppy/fdd_fdi.c b/src/floppy/fdd_fdi.c index d8004fc51..b780fa233 100644 --- a/src/floppy/fdd_fdi.c +++ b/src/floppy/fdd_fdi.c @@ -1,25 +1,46 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Implementation of the FDI floppy stream image format * interface to the FDI2RAW module. * - * Version: @(#)fdd_fdi.c 1.0.7 2018/01/16 + * Version: @(#)fdd_fdi.c 1.0.2 2018/03/17 * - * Authors: Sarah Walker, + * Authors: Fred N. van Kempen, * Miran Grca, + * Sarah Walker, * - * Copyright 2008-2018 Sarah Walker. + * Copyright 2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #include #include #include +#include #include #include "../86box.h" #include "../plat.h" @@ -31,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 f63f241e3..4808ecb03 100644 --- a/src/floppy/fdd_fdi.h +++ b/src/floppy/fdd_fdi.h @@ -1,38 +1,49 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Implementation of the FDI floppy stream image format * interface to the FDI2RAW module. * - * Version: @(#)floppy_fdi.h 1.0.3 2017/12/14 + * Version: @(#)floppy_fdi.h 1.0.2 2018/03/17 * - * Authors: Sarah Walker, + * Authors: Fred N. van Kempen, * Miran Grca, + * Sarah Walker, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #ifndef EMU_FLOPPY_FDI_H # 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 503521e1d..c78e85692 100644 --- a/src/floppy/fdd_imd.c +++ b/src/floppy/fdd_imd.c @@ -1,17 +1,38 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Implementation of the IMD floppy image format. * - * Version: @(#)fdd_imd.c 1.0.8 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 + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #include #include @@ -25,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; - uint8_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 7215639bd..4e16bd096 100644 --- a/src/floppy/fdd_imd.h +++ b/src/floppy/fdd_imd.h @@ -1,17 +1,38 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * - * Implementation of the IMD floppy image format. + * Definitions for the IMD floppy image format. * - * Version: @(#)floppy_imd.h 1.0.2 2017/09/03 + * Version: @(#)floppy_imd.h 1.0.2 2018/03/17 * - * Author: Miran Grca, - * Copyright 2016,2017 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 + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #ifndef EMU_FLOPPY_IMD_H # define EMU_FLOPPY_IMD_H @@ -20,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 daab0ad39..ce9dd4837 100644 --- a/src/floppy/fdd_img.c +++ b/src/floppy/fdd_img.c @@ -1,21 +1,45 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * 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.9 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: Sarah Walker, + * Version: @(#)fdd_img.c 1.0.5 2018/03/17 + * + * Authors: Fred N. van Kempen, * Miran Grca, + * Sarah Walker, * - * Copyright 2008-2018 Sarah Walker. + * Copyright 2018 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #include #include @@ -30,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}, @@ -84,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} }, @@ -103,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] */ @@ -257,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 81c2d8035..b5bddb4ad 100644 --- a/src/floppy/fdd_img.h +++ b/src/floppy/fdd_img.h @@ -1,29 +1,49 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * 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.2 2017/09/03 + * Version: @(#)floppy_img.h 1.0.2 2018/03/17 * - * Authors: Sarah Walker, + * Authors: Fred N. van Kempen, * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Sarah Walker, + * + * Copyright 2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #ifndef EMU_FLOPPY_IMG_H # 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 1daad4ee8..d3ae99ac9 100644 --- a/src/floppy/fdd_json.c +++ b/src/floppy/fdd_json.c @@ -1,18 +1,48 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Implementation of the PCjs JSON floppy image format. * - * Version: @(#)fdd_json.c 1.0.11 2018/03/14 + * Version: @(#)fdd_json.c 1.0.4 2018/03/17 * * Author: Fred N. van Kempen, * * Copyright 2017,2018 Fred N. van Kempen. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include @@ -71,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; @@ -84,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) { @@ -98,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; } @@ -159,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); } @@ -173,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; } @@ -191,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 { @@ -239,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 */ @@ -264,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; @@ -297,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; @@ -317,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); } @@ -336,69 +366,71 @@ 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. */ d86f_reset_index_hole_pos(drive, 0); - d86f_reset_index_hole_pos(drive, 1); d86f_destroy_linked_lists(drive, 0); + d86f_reset_index_hole_pos(drive, 1); d86f_destroy_linked_lists(drive, 1); 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; - id[3] = img->sects[track][side][asec].size; - ssize = fdd_sector_code_size(img->sects[track][side][asec].size); + if (dev->sects[track][side][asec].size > 255) + perror("fdd_json.c: json_seek: sector size too big."); + 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*/ @@ -414,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; } } } @@ -454,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]); } @@ -471,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; } @@ -493,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; @@ -560,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; @@ -622,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 82e2a6820..0df9dab7d 100644 --- a/src/floppy/fdd_json.h +++ b/src/floppy/fdd_json.h @@ -1,26 +1,56 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * - * Implementation of the PCjs JSON floppy image format. + * Definitions for the PCjs JSON floppy image format. * - * Version: @(#)floppy_json.h 1.0.1 2017/09/06 + * Version: @(#)floppy_json.h 1.0.2 2018/03/17 * * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen. + * + * Copyright 2017,2018 Fred N. van Kempen. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef EMU_FLOPPY_JSON_H # 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 c3056f705..b5558437f 100644 --- a/src/floppy/fdd_td0.c +++ b/src/floppy/fdd_td0.c @@ -1,41 +1,50 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Implementation of the Teledisk floppy image format. * - * Version: @(#)fdd_td0.c 1.0.8 2018/03/14 + * Version: @(#)fdd_td0.c 1.0.4 2018/03/17 * - * Authors: Milodrag Milanovic, + * Authors: Fred N. van Kempen, + * Miran Grca, + * Milodrag Milanovic, * Haruhiko OKUMURA, * Haruyasu YOSHIZAKI, * Kenji RIKITAKE, - * Miran Grca, + * + * 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. * Copyright 1988-2018 Haruyasu YOSHIZAKI. * Copyright 1988-2018 Kenji RIKITAKE. - * Copyright 2013-2018 Milodrag Milanovic. - * Copyright 2016-2018 Miran Grca. - */ - -/* license:BSD-3-Clause - copyright-holders:Miodrag Milanovic, Miran Grca (translation to C and port to 86Box) */ -/********************************************************************* - - 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 + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #include #include @@ -49,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; - uint64_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; - } - 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; - state->text_buf[state->tdctl.r++] = c; - 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; - state->tdctl.bufndx++; - state->text_buf[state->tdctl.r++] = c; - 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 int max_size = 4*1024*1024; /* 4MB ought to be large enough for any floppy */ -const int 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; - uint8_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 ad15d1bac..8c3593241 100644 --- a/src/floppy/fdd_td0.h +++ b/src/floppy/fdd_td0.h @@ -1,25 +1,38 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * - * Implementation of the Teledisk floppy image format. + * Definitions for the Teledisk floppy image format. * - * Version: @(#)floppy_td0.h 1.0.2 2017/09/03 + * Version: @(#)floppy_td0.h 1.0.2 2018/03/17 * - * Authors: Milodrag Milanovic, - * Haruhiko OKUMURA, - * Haruyasu YOSHIZAKI, - * Kenji RIKITAKE, + * Authors: Fred N. van Kempen, * Miran Grca, - * Copyright 1988-2017 Haruhiko OKUMURA. - * Copyright 1988-2017 Haruyasu YOSHIZAKI. - * Copyright 1988-2017 Kenji RIKITAKE. - * Copyright 2013-2017 Milodrag Milanovic. - * Copyright 2016,2017 Miran Grca. + * + * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #ifndef EMU_FLOPPY_TD0_H # define EMU_FLOPPY_TD0_H @@ -28,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/floppy/fdi2raw.c b/src/floppy/fdi2raw.c index c7aefa431..0cb7ca4fd 100644 --- a/src/floppy/fdi2raw.c +++ b/src/floppy/fdi2raw.c @@ -1,22 +1,45 @@ -/* Copyright holders: Toni Wilen - see COPYING for more details -*/ /* - - FDI to raw bit stream converter - Copyright (c) 2001 by Toni Wilen - FDI 2.0 support - Copyright (c) 2003-2004 by Toni Wilen - and Vincent Joguin - - FDI format created by Vincent "ApH" Joguin - - Tiny changes - function type fixes, multiple drives, addition of - get_last_head and C++ callability - by Thomas Harte, 2001, - T.Harte@excite.co.uk - -*/ - + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * FDI to raw bit stream converter + * FDI format created by Vincent "ApH" Joguin + * Tiny changes - function type fixes, multiple drives, + * addition of get_last_head and C++ callability by Thomas + * Harte. + * + * Version: @(#)fdi2raw.c 1.0.2 2018/03/12 + * + * Authors: Toni Wilen, + * and Vincent Joguin, + * Thomas Harte, + * + * Copyright 2001-2004 Toni Wilen. + * Copyright 2001-2004 Vincent Joguin. + * Copyright 2001 Thomas Harte. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ #define STATIC_INLINE #include #include @@ -1857,7 +1880,7 @@ static int decode_lowlevel_track (FDI *fdi, int track, struct fdi_cache *cache) indexoffset = 0; p1 = idxp; for (i = 0; i < pulses; i++) { - if (p1[idx_off1] + p1[idx_off2] > maxidx) + if ((uint32_t)p1[idx_off1] + (uint32_t)p1[idx_off2] > maxidx) maxidx = p1[idx_off1] + p1[idx_off2]; p1 += idx_off3; } @@ -1893,7 +1916,7 @@ static int decode_lowlevel_track (FDI *fdi, int track, struct fdi_cache *cache) totalavg = 0; weakbits = 0; for (i = 0; i < pulses; i++) { - int sum = p1[idx_off1] + p1[idx_off2]; + uint32_t sum = p1[idx_off1] + p1[idx_off2]; if (sum >= maxidx) { totalavg += *p2; } else { diff --git a/src/floppy/fdi2raw.h b/src/floppy/fdi2raw.h index b8c3201e5..3c93ae2df 100644 --- a/src/floppy/fdi2raw.h +++ b/src/floppy/fdi2raw.h @@ -1,6 +1,41 @@ -/* Copyright holders: Toni Wilen - see COPYING for more details -*/ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the FDI floppy file format. + * + * Version: @(#)fdi2raw.h 1.0.1 2018/02/14 + * + * Authors: Toni Wilen, + * and Vincent Joguin, + * Thomas Harte, + * + * Copyright 2001-2004 Toni Wilen. + * Copyright 2001-2004 Vincent Joguin. + * Copyright 2001 Thomas Harte. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ #ifndef __FDI2RAW_H #define __FDI2RAW_H diff --git a/src/game/gameport.c b/src/game/gameport.c index c33f84cf8..c1f06ecb5 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -1,6 +1,39 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Implementation of a generic Game Port. + * + * Version: @(#)gameport.c 1.0.3 2018/03/15 + * + * Authors: Miran Grca, + * Sarah Walker, + * + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ #include #include #include @@ -17,261 +50,286 @@ #include "joystick_standard.h" #include "joystick_sw_pad.h" #include "joystick_tm_fcs.h" -#include "../plat_joystick.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 81c95cc48..3db999646 100644 --- a/src/game/gameport.h +++ b/src/game/gameport.h @@ -1,49 +1,142 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the generic game port handlers. + * + * NOTE: This module needs a good cleanup someday. + * + * Version: @(#)gameport.h 1.0.3 2018/03/15 + * + * Authors: Miran Grca, + * Sarah Walker, + * + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2017 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ #ifndef EMU_GAMEPORT_H # define EMU_GAMEPORT_H -#define AXIS_NOT_PRESENT -99999 +#define MAX_PLAT_JOYSTICKS 8 +#define MAX_JOYSTICKS 4 + +#define POV_X 0x80000000 +#define POV_Y 0x40000000 + +#define AXIS_NOT_PRESENT -99999 + +#define JOYSTICK_PRESENT(n) (joystick_state[n].plat_joystick_nr != 0) -typedef struct -{ - const char *name; - void *(*init)(void); - void (*close)(void *p); - uint8_t (*read)(void *p); - void (*write)(void *p); - int (*read_axis)(void *p, int axis); - void (*a0_over)(void *p); - int axis_count, button_count, pov_count; - int max_joysticks; - const char *axis_names[8]; - const char *button_names[32]; - const char *pov_names[4]; +typedef struct { + char name[64]; + + int a[8]; + int b[32]; + int p[4]; + + struct { + char name[32]; + int id; + } axis[8]; + + struct { + char name[32]; + int id; + } button[32]; + + struct { + char name[32]; + int id; + } pov[4]; + + int nr_axes; + int nr_buttons; + int nr_povs; +} plat_joystick_t; + +typedef struct { + int axis[8]; + int button[32]; + int pov[4]; + + int plat_joystick_nr; + int axis_mapping[8]; + int button_mapping[32]; + int pov_mapping[4][2]; +} joystick_t; + +typedef struct { + const char *name; + + void *(*init)(void); + void (*close)(void *p); + uint8_t (*read)(void *p); + void (*write)(void *p); + int (*read_axis)(void *p, int axis); + void (*a0_over)(void *p); + + int axis_count, + button_count, + pov_count; + int max_joysticks; + const char *axis_names[8]; + const char *button_names[32]; + const char *pov_names[4]; } joystick_if_t; - #ifdef __cplusplus extern "C" { #endif -extern device_t gameport_device; -extern device_t gameport_201_device; +#ifdef EMU_DEVICE_H +extern const device_t gameport_device; +extern const device_t gameport_201_device; +#endif -extern int joystick_type; +extern plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +extern joystick_t joystick_state[MAX_JOYSTICKS]; +extern int joysticks_present; + +extern int joystick_type; -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 void joystick_init(void); +extern void joystick_close(void); +extern void joystick_process(void); + +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 ae7539a01..062e753a6 100644 --- a/src/game/joystick_ch_flightstick_pro.c +++ b/src/game/joystick_ch_flightstick_pro.c @@ -1,3 +1,39 @@ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Implementation of the Flight Stick Pro. + * + * Version: @(#)flightstick_pro.c 1.0.4 2018/03/15 + * + * Authors: Miran Grca, + * Sarah Walker, + * + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ #include #include #include @@ -6,12 +42,11 @@ #include "../86box.h" #include "../device.h" #include "../timer.h" -#include "../plat_joystick.h" #include "gameport.h" #include "joystick_standard.h" -static void *ch_flightstick_pro_init() +static void *ch_flightstick_pro_init(void) { return NULL; } @@ -78,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 291cb0bfa..7cbb71767 100644 --- a/src/game/joystick_ch_flightstick_pro.h +++ b/src/game/joystick_ch_flightstick_pro.h @@ -1 +1,38 @@ -extern joystick_if_t joystick_ch_flightstick_pro; +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the Flight Stick Pro driver. + * + * Version: @(#)joystick_ch_flightstickpro.h 1.0.2 2018/03/15 + * + * Authors: Miran Grca, + * Sarah Walker, + * + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ + +extern const joystick_if_t joystick_ch_flightstick_pro; diff --git a/src/game/joystick_standard.c b/src/game/joystick_standard.c index 71be48d3b..f05634a9b 100644 --- a/src/game/joystick_standard.c +++ b/src/game/joystick_standard.c @@ -1,3 +1,39 @@ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Implementation of a standard joystick. + * + * Version: @(#)joystick_standard.c 1.0.4 2018/03/15 + * + * Authors: Miran Grca, + * Sarah Walker, + * + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ #include #include #include @@ -6,12 +42,11 @@ #include "../86box.h" #include "../device.h" #include "../timer.h" -#include "../plat_joystick.h" #include "gameport.h" #include "joystick_standard.h" -static void *joystick_standard_init() +static void *joystick_standard_init(void) { return NULL; } @@ -160,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, @@ -176,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, @@ -192,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, @@ -208,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 7150058a8..26b16998e 100644 --- a/src/game/joystick_standard.h +++ b/src/game/joystick_standard.h @@ -1,4 +1,41 @@ -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; +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the joystick driver. + * + * Version: @(#)joystick_standard.h 1.0.2 2018/03/15 + * + * Authors: Miran Grca, + * Sarah Walker, + * + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ + +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 f0bb71e75..feec60593 100644 --- a/src/game/joystick_sw_pad.c +++ b/src/game/joystick_sw_pad.c @@ -1,24 +1,60 @@ -/*Sidewinder game pad notes : - - - Write to 0x201 starts packet transfer (5*N or 15*N bits) - - Currently alternates between Mode A and Mode B (is there any way of - actually controlling which is used?) - - Windows 9x drivers require Mode B when more than 1 pad connected - - Packet preceeded by high data (currently 50us), and followed by low - data (currently 160us) - timings are probably wrong, but good enough - for everything I've tried - - Analogue inputs are only used to time ID packet request. If A0 timing - out is followed after ~64us by another 0x201 write then an ID packet - is triggered - - Sidewinder game pad ID is 'H0003' - - ID is sent in Mode A (1 bit per clock), but data bit 2 must change - during ID packet transfer, or Windows 9x drivers won't use Mode B. I - don't know if it oscillates, mirrors the data transfer, or something - else - the drivers only check that it changes at least 10 times during - the transfer - - Some DOS stuff will write to 0x201 while a packet is being transferred. - This seems to be ignored. -*/ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Implementation of a Side Winder GamePad. + * + * Notes: - Write to 0x201 starts packet transfer (5*N or 15*N bits) + * - Currently alternates between Mode A and Mode B (is there + * any way of actually controlling which is used?) + * - Windows 9x drivers require Mode B when more than 1 pad + * connected + * - Packet preceeded by high data (currently 50us), and + * followed by low data (currently 160us) - timings are + * probably wrong, but good enoughfor everything I've tried + * - Analog inputs are only used to time ID packet request. + * If A0 timing out is followed after ~64us by another 0x201 + * write then an ID packet is triggered + * - Sidewinder game pad ID is 'H0003' + * - ID is sent in Mode A (1 bit per clock), but data bit 2 + * must change during ID packet transfer, or Windows 9x + * drivers won't use Mode B. I don't know if it oscillates, + * mirrors the data transfer, or something else - the drivers + * only check that it changes at least 10 times during the + * transfer + * - Some DOS stuff will write to 0x201 while a packet is + * being transferred. This seems to be ignored. + * + * Version: @(#)sw_pad.c 1.0.5 2018/03/15 + * + * Authors: Miran Grca, + * Sarah Walker, + * + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ #include #include #include @@ -27,7 +63,6 @@ #include "../86box.h" #include "../device.h" #include "../timer.h" -#include "../plat_joystick.h" #include "gameport.h" #include "joystick_sw_pad.h" @@ -90,7 +125,7 @@ static int sw_parity(uint16_t data) return bits_set & 1; } -static void *sw_init() +static void *sw_init(void) { sw_data *sw = (sw_data *)malloc(sizeof(sw_data)); memset(sw, 0, sizeof(sw_data)); @@ -139,7 +174,7 @@ static uint8_t sw_read(void *p) static void sw_write(void *p) { sw_data *sw = (sw_data *)p; - int time_since_last = sw->trigger_time / TIMER_USEC; + int64_t time_since_last = sw->trigger_time / TIMER_USEC; if (!JOYSTICK_PRESENT(0)) return; @@ -177,7 +212,7 @@ static void sw_write(void *p) for (c = 0; c < 4; c++) { - uint64_t data = 0x3fff; + uint16_t data = 0x3fff; int b; if (!JOYSTICK_PRESENT(c)) @@ -235,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 ba5ceb680..0cd4132a5 100644 --- a/src/game/joystick_sw_pad.h +++ b/src/game/joystick_sw_pad.h @@ -1 +1,38 @@ -extern joystick_if_t joystick_sw_pad; +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the Sidewinder Pro driver. + * + * Version: @(#)joystick_sw_pad.h 1.0.2 2018/03/15 + * + * Authors: Miran Grca, + * Sarah Walker, + * + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ + +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 892c0d546..69fa19d2b 100644 --- a/src/game/joystick_tm_fcs.c +++ b/src/game/joystick_tm_fcs.c @@ -1,3 +1,39 @@ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Implementation of Thrust Master Flight Control System. + * + * Version: @(#)tm_fcs.c 1.0.3 2018/03/15 + * + * Authors: Miran Grca, + * Sarah Walker, + * + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ #include #include #include @@ -6,7 +42,6 @@ #include "../86box.h" #include "../device.h" #include "../timer.h" -#include "../plat_joystick.h" #include "gameport.h" #include "joystick_standard.h" @@ -77,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 9759cf897..7ada355ed 100644 --- a/src/game/joystick_tm_fcs.h +++ b/src/game/joystick_tm_fcs.h @@ -1 +1,38 @@ -extern joystick_if_t joystick_tm_fcs; +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the Flight Control System driver. + * + * Version: @(#)joystick_tm_fcs.h 1.0.2 2018/03/15 + * + * Authors: Miran Grca, + * Sarah Walker, + * + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ + +extern const joystick_if_t joystick_tm_fcs; diff --git a/src/intel_flash.c b/src/intel_flash.c index 3bcb24090..ccf141eff 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -6,9 +6,9 @@ * * This file is part of the 86Box distribution. * - * Implementation of the Intel 2 Mbit 8-bit flash devices. + * Implementation of the Intel 1 Mbit 8-bit flash devices. * - * Version: @(#)intel_flash.c 1.0.13 2018/02/09 + * Version: @(#)intel_flash.c 1.0.14 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -288,7 +288,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, 0, @@ -298,7 +298,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, 0, @@ -308,7 +308,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, @@ -318,7 +318,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, 0, diff --git a/src/intel_flash.h b/src/intel_flash.h index d63b48c18..241a07c02 100644 --- a/src/intel_flash.h +++ b/src/intel_flash.h @@ -6,9 +6,9 @@ * * This file is part of the 86Box distribution. * - * Implementation of the Intel 2 Mbit 8-bit flash devices. + * Implementation of the Intel 1 Mbit 8-bit flash devices. * - * Version: @(#)intel_flash.h 1.0.0 2017/05/30 + * Version: @(#)intel_flash.h 1.0.1 2018/03/14 * * Author: Sarah Walker, * Miran Grca, @@ -16,7 +16,7 @@ * Copyright 2016-2017 Miran Grca. */ -extern device_t intel_flash_bxt_ami_device; -extern device_t intel_flash_bxb_ami_device; -extern device_t intel_flash_bxt_device; -extern device_t intel_flash_bxb_device; +extern const device_t intel_flash_bxt_ami_device; +extern const device_t intel_flash_bxb_ami_device; +extern const device_t intel_flash_bxt_device; +extern const device_t intel_flash_bxb_device; diff --git a/src/keyboard.h b/src/keyboard.h index aff83f49f..c9d5ebcd4 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -8,15 +8,15 @@ * * Definitions for the keyboard interface. * - * Version: @(#)keyboard.h 1.0.11 2018/02/10 + * Version: @(#)keyboard.h 1.0.12 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * * Copyright 2008-2018 Sarah Walker. - * Copyright 2016,2018 Miran Grca. - * Copyright 2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. */ #ifndef EMU_KEYBOARD_H # define EMU_KEYBOARD_H @@ -60,15 +60,15 @@ 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); diff --git a/src/keyboard_at.c b/src/keyboard_at.c index ea7357c28..09f255515 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.30 2018/03/13 + * Version: @(#)keyboard_at.c 1.0.31 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -1891,7 +1891,7 @@ kbd_reset(void *priv) static void * -kbd_init(device_t *info) +kbd_init(const device_t *info) { atkbd_t *kbd; @@ -1969,7 +1969,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, @@ -1979,7 +1979,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, @@ -1989,7 +1989,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, @@ -1999,7 +1999,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, @@ -2009,7 +2009,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, @@ -2019,7 +2019,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, @@ -2029,7 +2029,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 2b97cb564..28bd1b645 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -8,15 +8,15 @@ * * Implementation of the XT-style keyboard. * - * Version: @(#)keyboard_xt.c 1.0.9 2018/02/24 + * Version: @(#)keyboard_xt.c 1.0.10 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * * Copyright 2008-2018 Sarah Walker. - * Copyright 2016,2018 Miran Grca. - * Copyright 2018 Fred N. van kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van kempen. */ #include #include @@ -530,7 +530,7 @@ kbd_reset(void *priv) static void * -kbd_init(device_t *info) +kbd_init(const device_t *info) { xtkbd_t *kbd; @@ -574,7 +574,7 @@ kbd_close(void *priv) } -device_t keyboard_xt_device = { +const device_t keyboard_xt_device = { "PC/XT Keyboard", 0, 0, @@ -584,7 +584,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 56ec62299..4f692a37a 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -15,7 +15,7 @@ char lpt_device_names[3][16]; -static struct +static const struct { const char *name; const char *internal_name; diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index e8cc23add..108a7b638 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -32,7 +32,7 @@ * in alpha mode, but in highres ("ECD350") mode, it displays * some semi-random junk. Video-memory pointer maybe? * - * Version: @(#)m_amstrad.c 1.0.10 2018/02/02 + * Version: @(#)m_amstrad.c 1.0.11 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -557,7 +557,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, @@ -721,7 +721,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, @@ -856,7 +856,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, @@ -1198,7 +1198,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; diff --git a/src/machine/m_at.c b/src/machine/m_at.c index df8227881..edbec78a2 100644 --- a/src/machine/m_at.c +++ b/src/machine/m_at.c @@ -19,7 +19,7 @@ void -machine_at_common_init(machine_t *model) +machine_at_common_init(const machine_t *model) { machine_common_init(model); @@ -38,7 +38,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); @@ -47,7 +47,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); @@ -56,7 +56,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); @@ -65,7 +65,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); @@ -74,7 +74,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); @@ -83,7 +83,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); @@ -92,7 +92,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); @@ -101,7 +101,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 258a4ff7a..31c63d74a 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.13 2018/02/23 + * Version: @(#)m_at_430fx.c 1.0.14 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -207,7 +207,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); @@ -228,7 +228,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); @@ -253,7 +253,7 @@ machine_at_endeavor_init(machine_t *model) } -device_t * +const device_t * at_endeavor_get_device(void) { return &s3_phoenix_trio64_onboard_pci_device; @@ -261,7 +261,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); @@ -282,7 +282,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); @@ -302,7 +302,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); @@ -323,7 +323,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 5e734158f..74f735a28 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.11 2018/02/14 + * Version: @(#)m_at_430hx.c 1.0.11 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -216,7 +216,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); @@ -239,7 +239,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); @@ -262,7 +262,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); @@ -286,7 +286,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); @@ -307,7 +307,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 865a85204..c2c80483e 100644 --- a/src/machine/m_at_430lx_nx.c +++ b/src/machine/m_at_430lx_nx.c @@ -8,13 +8,13 @@ * * Implementation of the Intel 430LX and 430NX PCISet chips. * - * Version: @(#)m_at_430lx_nx.c 1.0.10 2018/02/14 + * Version: @(#)m_at_430lx_nx.c 1.0.10 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, * * Copyright 2008-2018 Sarah Walker. - * Copyright 2016,2018 Miran Grca. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -211,7 +211,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); @@ -233,7 +233,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); @@ -242,7 +242,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 07d5ebf23..9165dd203 100644 --- a/src/machine/m_at_430vx.c +++ b/src/machine/m_at_430vx.c @@ -8,13 +8,13 @@ * * Implementation of the Intel 430VX PCISet chip. * - * Version: @(#)m_at_430vx.c 1.0.11 2018/02/14 + * Version: @(#)m_at_430vx.c 1.0.11 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, * * Copyright 2008-2018 Sarah Walker. - * Copyright 2016,2018 Miran Grca. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -193,7 +193,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); @@ -214,7 +214,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); @@ -235,7 +235,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 13747304f..6d3038048 100644 --- a/src/machine/m_at_440fx.c +++ b/src/machine/m_at_440fx.c @@ -8,13 +8,13 @@ * * Implementation of the Intel 440FX PCISet chip. * - * Version: @(#)m_at_440fx.c 1.0.10 2018/02/14 + * Version: @(#)m_at_440fx.c 1.0.11 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, * * Copyright 2008-2018 Sarah Walker. - * Copyright 2016,2018 Miran Grca. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -195,7 +195,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); @@ -217,7 +217,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 c8d3d8215..b870131bf 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.4 2018/01/16 + * Version: @(#)m_4gpv31.c 1.0.5 2018/03/18 * * Author: Fred N. van Kempen, * Copyright 2017,2018 Fred N. van Kempen. @@ -143,7 +143,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 aadec2a14..a0dc3ddf0 100644 --- a/src/machine/m_at_ali1429.c +++ b/src/machine/m_at_ali1429.c @@ -98,7 +98,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 ea5eb8fcc..e12e13970 100644 --- a/src/machine/m_at_commodore.c +++ b/src/machine/m_at_commodore.c @@ -46,7 +46,7 @@ static void cbm_io_init() 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); diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 4c0705cc9..9497a8498 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.4 2018/02/14 + * Version: @(#)m_at_compaq.c 1.0.5 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -98,7 +98,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 a8997e1a6..b8f707d4e 100644 --- a/src/machine/m_at_headland.c +++ b/src/machine/m_at_headland.c @@ -70,7 +70,7 @@ static void headland_init(void) void -machine_at_headland_init(machine_t *model) +machine_at_headland_init(const machine_t *model) { machine_at_common_ide_init(model); diff --git a/src/machine/m_at_neat.c b/src/machine/m_at_neat.c index 89baf7e17..2f789b3a1 100644 --- a/src/machine/m_at_neat.c +++ b/src/machine/m_at_neat.c @@ -88,7 +88,7 @@ static void neat_init(void) 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); @@ -98,7 +98,7 @@ machine_at_neat_init(machine_t *model) void -machine_at_neat_ami_init(machine_t *model) +machine_at_neat_ami_init(const machine_t *model) { machine_at_common_init(model); diff --git a/src/machine/m_at_opti495.c b/src/machine/m_at_opti495.c index 5db7ca55f..21f984827 100644 --- a/src/machine/m_at_opti495.c +++ b/src/machine/m_at_opti495.c @@ -323,7 +323,7 @@ static void opti495_init(void) void -machine_at_opti495_init(machine_t *model) +machine_at_opti495_init(const machine_t *model) { machine_at_common_ide_init(model); @@ -335,7 +335,7 @@ machine_at_opti495_init(machine_t *model) void -machine_at_opti495_ami_init(machine_t *model) +machine_at_opti495_ami_init(const machine_t *model) { machine_at_common_ide_init(model); diff --git a/src/machine/m_at_scat.c b/src/machine/m_at_scat.c index 37c4b2080..39ee46ea3 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.10 2018/03/02 + * Version: @(#)m_at_scat.c 1.0.11 2018/03/18 * * Authors: Original by GreatPsycho for PCem. * Fred N. van Kempen, @@ -712,7 +712,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); @@ -722,7 +722,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 c3f6b47fc..fc511d7c6 100644 --- a/src/machine/m_at_sis_85c471.c +++ b/src/machine/m_at_sis_85c471.c @@ -9,7 +9,7 @@ * SiS sis85c471 Super I/O Chip * Used by DTK PKM-0038S E-2 * - * Version: @(#)m_at_sis85c471.c 1.0.9 2018/01/16 + * Version: @(#)m_at_sis85c471.c 1.0.10 2018/03/18 * * Author: Miran Grca, * @@ -240,7 +240,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 8e0fe7064..1705425cb 100644 --- a/src/machine/m_at_sis_85c496.c +++ b/src/machine/m_at_sis_85c496.c @@ -162,7 +162,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); @@ -180,7 +180,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 e650e71dc..c5f18eeca 100644 --- a/src/machine/m_at_sis_85c50x.c +++ b/src/machine/m_at_sis_85c50x.c @@ -6,11 +6,11 @@ * * Emulation of the SiS 50x PCI chips. * - * Version: @(#)m_at_sis_85c50x.c 1.0.5 2017/11/04 + * Version: @(#)m_at_sis_85c50x.c 1.0.6 2018/03/18 * * Author: Miran Grca, * - * Copyright 2017 Miran Grca. + * Copyright 2015-2018 Miran Grca. */ #include #include diff --git a/src/machine/m_at_t3100e.c b/src/machine/m_at_t3100e.c index 9031d430d..799e4055c 100644 --- a/src/machine/m_at_t3100e.c +++ b/src/machine/m_at_t3100e.c @@ -117,7 +117,7 @@ * 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/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -716,7 +716,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 0de5cf62a..e92d23b73 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/18 * * 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 814d0dc3f..033520034 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/18 * * 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 1e1f3ac1f..f63cf2b8b 100644 --- a/src/machine/m_at_wd76c10.c +++ b/src/machine/m_at_wd76c10.c @@ -142,7 +142,7 @@ static void wd76c10_init(void) void -machine_at_wd76c10_init(machine_t *model) +machine_at_wd76c10_init(const machine_t *model) { machine_at_common_ide_init(model); diff --git a/src/machine/m_europc.c b/src/machine/m_europc.c index f2dae9a28..63d4b4b4d 100644 --- a/src/machine/m_europc.c +++ b/src/machine/m_europc.c @@ -68,7 +68,7 @@ * * 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/18 * * Author: Fred N. van Kempen, * @@ -546,7 +546,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; @@ -674,7 +674,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 +695,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 +713,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 ef8b21514..315f0f85c 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/18 * * 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 9492af865..bf6c0ec6f 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.10 2018/01/29 + * Version: @(#)m_olivetti_m24.c 1.0.11 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -789,7 +789,7 @@ vid_close(void *priv) free(m24); } -device_t m24_device = { +const device_t m24_device = { "Olivetti M24", 0, 0, NULL, vid_close, NULL, @@ -801,7 +801,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 6f8f1ec4a..d2167ff70 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.5 2018/02/09 + * Version: @(#)m_pcjr.c 1.0.6 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -693,7 +693,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, { @@ -714,7 +714,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, @@ -726,7 +726,7 @@ static device_t pcjr_device = { }; -device_t * +const device_t * pcjr_get_device(void) { return &pcjr_device; @@ -734,7 +734,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 482fc2430..9be9cbd2c 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.6 2018/02/14 + * Version: @(#)m_ps1.c 1.0.7 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -236,7 +236,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; @@ -265,7 +265,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, @@ -535,7 +535,7 @@ ps1_setup(int model) static void -ps1_common_init(machine_t *model) +ps1_common_init(const machine_t *model) { machine_common_init(model); @@ -570,7 +570,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); @@ -579,7 +579,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); @@ -588,7 +588,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 8f9c1906d..60300adf0 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -148,7 +148,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 f85a06c0b..5033945c2 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -1218,7 +1218,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); @@ -1236,7 +1236,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); @@ -1245,7 +1245,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); @@ -1253,7 +1253,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); @@ -1261,7 +1261,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); @@ -1269,7 +1269,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); @@ -1279,7 +1279,7 @@ machine_ps2_model_80_init(machine_t *model) #ifdef WALTJE void -machine_ps2_model_80_486_init(machine_t *model) +machine_ps2_model_80_486_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 8d2a1b38e..a31fffde8 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.3 2018/02/09 + * Version: @(#)m_tandy.c 1.0.4 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -1353,7 +1353,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, { @@ -1374,7 +1374,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, @@ -1385,7 +1385,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, @@ -1396,7 +1396,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, @@ -1408,14 +1408,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; @@ -1501,7 +1501,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; @@ -1548,7 +1548,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, @@ -1692,7 +1692,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 bb4ef2fb1..3878c98b1 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -15,7 +15,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 f070a05b3..751e45da8 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.3 2018/02/24 + * Version: @(#)m_xt_compaq.c 1.0.4 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -37,7 +37,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 61ae8d983..fe5d86606 100644 --- a/src/machine/m_xt_laserxt.c +++ b/src/machine/m_xt_laserxt.c @@ -132,7 +132,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 b1d5c2367..969329680 100644 --- a/src/machine/m_xt_t1000.c +++ b/src/machine/m_xt_t1000.c @@ -51,7 +51,7 @@ * 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.2 2018/03/11 + * Version: @(#)m_xt_t1000.c 1.0.3 2018/03/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -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 545861eb5..e2a1ade1f 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/18 * * 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 e2058c94f..a1baa8f22 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/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -658,7 +658,7 @@ 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)); @@ -704,7 +704,7 @@ static void t1000_speed_changed(void *p) t1000_recalctimings(t1000); } -static device_config_t t1000_config[] = +static const device_config_t t1000_config[] = { { .name = "display_language", @@ -729,7 +729,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, @@ -741,7 +741,7 @@ device_t t1000_video_device = { }; -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 bf06bb572..f4137cfb0 100644 --- a/src/machine/m_xt_xi8088.c +++ b/src/machine/m_xt_xi8088.c @@ -76,7 +76,7 @@ static void *xi8088_init() return &xi8088; } -static device_config_t xi8088_config[] = +static const device_config_t xi8088_config[] = { { .name = "turbo_setting", @@ -101,7 +101,7 @@ static device_config_t xi8088_config[] = }; -device_t xi8088_device = +const device_t xi8088_device = { "Xi8088", 0, @@ -116,13 +116,13 @@ device_t xi8088_device = 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) { /* 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); diff --git a/src/machine/m_xt_xi8088.h b/src/machine/m_xt_xi8088.h index 1c33c6532..0270ed16d 100644 --- a/src/machine/m_xt_xi8088.h +++ b/src/machine/m_xt_xi8088.h @@ -1,6 +1,6 @@ #include "../device.h" -extern device_t xi8088_device; +extern const device_t xi8088_device; uint8_t xi8088_turbo_get(); void xi8088_turbo_set(uint8_t value); diff --git a/src/machine/machine.c b/src/machine/machine.c index a000a9fb5..4a17cc7ae 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.30 2018/03/15 + * Version: @(#)machine.c 1.0.31 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -65,7 +65,7 @@ machine_init(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 2cd9880f4..7822ffd2f 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.21 2018/03/02 + * Version: @(#)machine.h 1.0.22 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -58,9 +58,9 @@ typedef struct _machine_ { int min_ram, max_ram; int ram_granularity; int nvrmask; - 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; #endif @@ -69,7 +69,7 @@ typedef struct _machine_ { /* Global variables. */ -extern machine_t machines[]; +extern const machine_t machines[]; extern int machine; extern int romset; extern int AT, PCI; @@ -84,7 +84,7 @@ extern char *machine_get_internal_name(void); extern int machine_get_machine_from_internal_name(char *s); 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); @@ -93,119 +93,119 @@ 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 *); #ifdef WALTJE -extern void machine_ps2_model_80_486_init(machine_t *); +extern void machine_ps2_model_80_486_init(const machine_t *); #endif -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 8bb8d4982..8f02f57c8 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.25 2018/03/13 + * Version: @(#)machine_table.c 1.0.26 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -34,7 +34,7 @@ #include "machine.h" -machine_t machines[] = { +const machine_t machines[] = { { "[8088] AMI XT clone", ROM_AMIXT, "amixt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL, NULL }, { "[8088] Compaq Portable", ROM_PORTABLE, "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", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL, NULL }, @@ -223,7 +223,7 @@ machine_getname(void) } -device_t * +const device_t * machine_getdevice(int machine) { if (machines[machine].get_device) diff --git a/src/mouse.c b/src/mouse.c index 1c69a792c..0ee64943f 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.22 2018/03/18 + * Version: @(#)mouse.c 1.0.23 2018/03/18 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -30,7 +30,7 @@ typedef struct { const char *internal_name; - device_t *device; + const device_t *device; } mouse_t; @@ -41,14 +41,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, @@ -72,7 +72,7 @@ static mouse_t mouse_devices[] = { }; -static device_t *mouse_curr; +static const device_t *mouse_curr; static void *mouse_priv; static int mouse_nbut; static int (*mouse_dev_poll)(); @@ -211,7 +211,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 84a6c5ec4..4d402fa0a 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -8,7 +8,7 @@ * * Definitions for the mouse driver. * - * Version: @(#)mouse.h 1.0.14 2018/01/29 + * Version: @(#)mouse.h 1.0.15 2018/03/18 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -44,17 +44,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 695f84f6a..ebd81a6df 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.31 2018/02/01 + * Version: @(#)mouse_bus.c 1.0.32 2018/03/18 * * Authors: Fred N. van Kempen, * @@ -669,7 +669,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; @@ -723,7 +723,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, { { @@ -762,7 +762,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, @@ -771,7 +771,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 e3743438d..3cf6ee27e 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.5 2017/12/14 + * Version: @(#)mouse_ps2.c 1.0.6 2018/03/18 * * Authors: Fred N. van Kempen, */ @@ -224,7 +224,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; @@ -264,7 +264,7 @@ ps2_close(void *priv) } -static device_config_t ps2_config[] = { +static const device_config_t ps2_config[] = { { "buttons", "Buttons", CONFIG_SELECTION, "", 2, { { @@ -287,7 +287,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 22dc1973a..a0a487f9c 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.20 2018/01/25 + * Version: @(#)mouse_serial.c 1.0.21 2018/03/18 * * Author: Fred N. van Kempen, */ @@ -196,7 +196,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; @@ -247,7 +247,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, { { @@ -283,7 +283,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, @@ -292,7 +292,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/bswap.h b/src/network/bswap.h index 81275a6e6..75311d39b 100644 --- a/src/network/bswap.h +++ b/src/network/bswap.h @@ -1,6 +1,39 @@ -/* Copyright holders: neozeed - see COPYING for more details -*/ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Various definitions for portable byte-swapping. + * + * Version: @(#)bswap.h 1.0.2 2018/03/12 + * + * Authors: Fred N. van Kempen, + * neozeed, + * + * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2016-2018 neozeed. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ #ifndef BSWAP_H #define BSWAP_H @@ -138,7 +171,7 @@ static __inline void cpu_to_le16wu(uint16_t *p, uint16_t v) { uint8_t *p1 = (uint8_t *)p; - p1[0] = v; + p1[0] = v & 0xff; p1[1] = v >> 8; } @@ -169,7 +202,7 @@ static __inline void cpu_to_be16wu(uint16_t *p, uint16_t v) uint8_t *p1 = (uint8_t *)p; p1[0] = v >> 8; - p1[1] = v; + p1[1] = v & 0xff; } static __inline void cpu_to_be32wu(uint32_t *p, uint32_t v) diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index 7c28acb23..97376fce7 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -1,10 +1,10 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Implementation of the following network controllers: * - Novell NE1000 (ISA 8-bit); @@ -12,21 +12,36 @@ * - Realtek RTL8019AS (ISA 16-bit, PnP); * - Realtek RTL8029AS (PCI). * - * NOTE: The file will also implement an NE1000 for 8-bit ISA systems. - * - * Version: @(#)net_ne2000.c 1.0.30 2018/02/09 - * - * Authors: Fred N. van Kempen, - * Peter Grehan, - * Miran Grca, - * Sarah Walker, - * SA1988 + * 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 * - * Portions Copyright (C) 2002 MandrakeSoft S.A. - * Portions Copyright (C) 2018 Sarah Walker. + * Authors: Fred N. van Kempen, + * TheCollector1995, + * Miran Grca, + * Peter Grehan, + * * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Portions Copyright (C) 2002 MandrakeSoft S.A. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #include #include @@ -2362,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; @@ -2370,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 @@ -2388,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; @@ -2430,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. */ @@ -2473,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; @@ -2503,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, @@ -2536,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]; @@ -2620,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, @@ -2679,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, @@ -2764,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 @@ -2774,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 @@ -2788,7 +2809,7 @@ static device_config_t rtl8029as_config[] = }; -device_t ne1000_device = { +const device_t ne1000_device = { "Novell NE1000", DEVICE_ISA, NE2K_NE1000, @@ -2797,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, @@ -2806,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, @@ -2815,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 b623c10d9..0453a3ba5 100644 --- a/src/network/net_ne2000.h +++ b/src/network/net_ne2000.h @@ -1,34 +1,54 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Definitions for the NE2000 ethernet controller. * - * Version: @(#)net_ne2000.h 1.0.5 2018/01/28 + * Version: @(#)net_ne2000.h 1.0.2 2018/03/15 * - * Author: Fred N. van Kempen, + * Authors: Fred N. van Kempen, + * + * Copyright 2017,2018 Fred N. van Kempen. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #ifndef NET_NE2000_H # define NET_NE2000_H enum { - NE2K_NONE = 0, - NE2K_NE1000, /* 8-bit ISA NE1000 */ - NE2K_NE2000, /* 16-bit ISA NE2000 */ - NE2K_RTL8019AS, /* 16-bit ISA PnP Realtek 8019AS */ - NE2K_RTL8029AS /* 32-bit PCI Realtek 8029AS */ + NE2K_NONE = 0, + NE2K_NE1000, /* 8-bit ISA NE1000 */ + NE2K_NE2000, /* 16-bit ISA NE2000 */ + NE2K_RTL8019AS, /* 16-bit ISA PnP Realtek 8019AS */ + NE2K_RTL8029AS /* 32-bit PCI Realtek 8029AS */ }; -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 d78c716b2..a619868b6 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -1,25 +1,55 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Handle WinPcap library processing. * - * Version: @(#)net_pcap.c 1.0.14 2018/03/18 + * Version: @(#)net_pcap.c 1.0.3 2018/03/15 * * Author: Fred N. van Kempen, * * Copyright 2017,2018 Fred N. van Kempen. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include -#include +#include #include "../86box.h" #include "../config.h" #include "../device.h" @@ -31,7 +61,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; @@ -204,9 +234,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); } @@ -274,22 +302,22 @@ net_pcap_close(void) * tries to attach to the network module. */ int -net_pcap_reset(netcard_t *card, uint8_t *mac) +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", diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index a1f336aa8..4fe2d4e98 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -1,18 +1,48 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Handle SLiRP library processing. * - * Version: @(#)net_slirp.c 1.0.14 2018/03/18 + * Version: @(#)net_slirp.c 1.0.2 2018/03/15 * * Author: Fred N. van Kempen, * * Copyright 2017,2018 Fred N. van Kempen. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include @@ -30,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; @@ -143,7 +173,7 @@ net_slirp_init(void) /* Initialize SLiRP for use. */ int -net_slirp_reset(netcard_t *card, uint8_t *mac) +net_slirp_reset(const netcard_t *card, uint8_t *mac) { /* Save the callback info. */ poll_card = card; diff --git a/src/network/network.c b/src/network/network.c index 930b9eea0..9a4bcd76a 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -1,10 +1,10 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Implementation of the network module. * @@ -12,17 +12,50 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.22 2018/03/18 + * Version: @(#)network.c 1.0.3 2018/03/15 * * Author: Fred N. van Kempen, * * Copyright 2017,2018 Fred N. van Kempen. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include +#ifdef WALTJE +# include +#endif #include "../86box.h" #include "../device.h" #include "../plat.h" @@ -32,18 +65,18 @@ static netcard_t net_cards[] = { - { "None", "none", NULL, - NULL, NULL }, + { "None", "none", 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, + NULL } }; @@ -51,7 +84,7 @@ static netcard_t net_cards[] = { int network_type; int network_ndev; int network_card; -char network_pcap[512]; +char network_host[512]; netdev_t network_devs[32]; #ifdef ENABLE_NIC_LOG int nic_do_log = ENABLE_NIC_LOG; @@ -70,6 +103,87 @@ static struct { } poll_data; +#ifdef WALTJE +# define is_print(c) (isalnum((int)(c)) || ((c) == ' ')) + + +#if 0 +/* Dump a buffer in hex, standard output. */ +static void +hexdump(uint8_t *bufp, int len) +{ + char asci[20]; + uint8_t c; + int addr; + + addr = 0; + while (len-- > 0) { + c = bufp[addr]; + if ((addr % 16) == 0) { + printf("%06X %02X", addr, c); + } else { + printf(" %02X", c); + } + asci[(addr & 15)] = (char)((is_print(c) ? c : '.') & 0xff); + if ((++addr % 16) == 0) { + asci[16] = '\0'; + printf(" | %s |\n", asci); + } + } + + if (addr % 16) { + while (addr % 16) { + printf(" "); + asci[(addr & 15)] = ' '; + addr++; + } + asci[16] = '\0'; + printf(" | %s |\n", asci); + } +} +#endif + + +/* Dump a buffer in hex to output buffer. */ +static void +hexdump_p(char *ptr, uint8_t *bufp, int len) +{ + char asci[20]; + uint8_t c; + int addr; + + addr = 0; + while (len-- > 0) { + c = bufp[addr]; + if ((addr % 16) == 0) { + sprintf(ptr, "%06X %02X", addr, c); + } else { + sprintf(ptr, " %02X", c); + } + ptr += strlen(ptr); + asci[(addr & 15)] = (char)((is_print(c) ? c : '.') & 0xff); + if ((++addr % 16) == 0) { + asci[16] = '\0'; + sprintf(ptr, " | %s |\n", asci); + ptr += strlen(ptr); + } + } + + if (addr % 16) { + while (addr % 16) { + sprintf(ptr, " "); + ptr += strlen(ptr); + asci[(addr & 15)] = ' '; + addr++; + } + asci[16] = '\0'; + sprintf(ptr, " | %s |\n", asci); + ptr += strlen(ptr); + } +} +#endif + + void network_wait(uint8_t wait) { @@ -99,7 +213,7 @@ network_busy(uint8_t set) thread_set_event(poll_data.wake_poll_thread); } - + void network_end(void) { @@ -214,7 +328,13 @@ network_reset(void) { int i = -1; - pclog("NETWORK: reset (type=%d, card=%d)\n", network_type, network_card); +#ifdef ENABLE_NIC_LOG + pclog("NETWORK: reset (type=%d, card=%d) debug=%d\n", + network_type, network_card, nic_do_log); +#else + pclog("NETWORK: reset (type=%d, card=%d)\n", + network_type, network_card); +#endif ui_sb_update_icon(SB_NETWORK, 0); /* Just in case.. */ @@ -223,7 +343,7 @@ network_reset(void) /* If no active card, we're done. */ if ((network_type==NET_TYPE_NONE) || (network_card==0)) return; - network_mutex = thread_create_mutex(L"86Box.NetMutex"); + network_mutex = thread_create_mutex(L"VARCem.NetMutex"); /* Initialize the platform module. */ switch(network_type) { @@ -269,6 +389,14 @@ network_tx(uint8_t *bufp, int len) { ui_sb_update_icon(SB_NETWORK, 1); +#ifdef WALTJE +{ + char temp[4096]; + hexdump_p(temp, bufp, len); + pclog("NETWORK: >> len=%d\n%s\n", len, temp); +} +#endif + switch(network_type) { case NET_TYPE_PCAP: net_pcap_in(bufp, len); @@ -289,7 +417,7 @@ network_dev_to_id(char *devname) int i = 0; for (i=0; i + * + * Copyright 2017,2018 Fred N. van Kempen. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef EMU_NETWORK_H # define EMU_NETWORK_H @@ -24,11 +56,11 @@ /* Supported network cards. */ enum { - NONE = 0, - NE1000, - NE2000, - RTL8019AS, - RTL8029AS + NONE = 0, + NE1000, + NE2000, + RTL8019AS, + RTL8029AS }; @@ -36,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; @@ -57,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]; @@ -79,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 *, uint8_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 *, uint8_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); @@ -94,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/network/pcap_if.c b/src/network/pcap_if.c index 4d2c848ef..439dbfa94 100644 --- a/src/network/pcap_if.c +++ b/src/network/pcap_if.c @@ -1,20 +1,50 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * Simple program to show usage of (Win)Pcap. * * Based on the "libpcap" examples. * - * Version: @(#)pcap_if.c 1.0.7 2017/10/28 + * Version: @(#)pcap_if.c 1.0.10 2018/03/10 * * Author: Fred N. van Kempen, * - * Copyright 2017 Fred N. van Kempen. + * Copyright 2017,2018 Fred N. van Kempen. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include @@ -22,7 +52,7 @@ #include #include #include -#include +#include #include #include "../86box.h" #include "../plat.h" diff --git a/src/network/slirp/debug.c b/src/network/slirp/debug.c index 9e727732a..eef2c7de1 100644 --- a/src/network/slirp/debug.c +++ b/src/network/slirp/debug.c @@ -19,7 +19,9 @@ int dostats = 0; #endif int slirp_debug = 0; +#ifndef _MSC_VER extern char *strerror _P((int)); +#endif /* Carry over one item from main.c so that the tty's restored. * Only done when the tty being used is /dev/tty --RedWolf */ diff --git a/src/nvr_ps2.c b/src/nvr_ps2.c index ce1cdfe2a..ff887ca2c 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/13 + * Version: @(#)nvr_ps2.c 1.0.5 2018/03/18 * * Authors: Fred N. van Kempen, * Sarah Walker, @@ -103,7 +103,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; @@ -159,7 +159,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 802c27f4a..57293f212 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/18 * * 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 b19155990..fc4b205d9 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.64 2018/03/15 + * Version: @(#)pc.c 1.0.65 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -75,7 +75,6 @@ #include "video/video.h" #include "ui.h" #include "plat.h" -#include "plat_joystick.h" #include "plat_midi.h" diff --git a/src/plat_joystick.h b/src/plat_joystick.h deleted file mode 100644 index d1287f769..000000000 --- a/src/plat_joystick.h +++ /dev/null @@ -1,65 +0,0 @@ -#define MAX_PLAT_JOYSTICKS 8 -#define MAX_JOYSTICKS 4 - -#define POV_X 0x80000000 -#define POV_Y 0x40000000 - - -typedef struct { - char name[64]; - - int a[8]; - int b[32]; - int p[4]; - - struct { - char name[32]; - int id; - } axis[8]; - - struct { - char name[32]; - int id; - } button[32]; - - struct { - char name[32]; - int id; - } pov[4]; - - int nr_axes; - int nr_buttons; - int nr_povs; -} plat_joystick_t; - -typedef struct { - int axis[8]; - int button[32]; - int pov[4]; - - int plat_joystick_nr; - int axis_mapping[8]; - int button_mapping[32]; - int pov_mapping[4][2]; -} joystick_t; - - -#ifdef __cplusplus -extern "C" { -#endif - -extern plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -extern joystick_t joystick_state[MAX_JOYSTICKS]; -extern int joysticks_present; - - -#define JOYSTICK_PRESENT(n) (joystick_state[n].plat_joystick_nr != 0) - - -extern void joystick_init(void); -extern void joystick_close(void); -extern void joystick_process(void); - -#ifdef __cplusplus -} -#endif diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index fa4033ec5..e75993d82 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.16 2018/03/06 + * Version: @(#)scsi.c 1.0.17 2018/03/18 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -56,10 +56,10 @@ static volatile mutex_t *scsiMutex; -typedef struct { - const char *name; - const char *internal_name; - device_t *device; +typedef const struct { + const char *name; + const char *internal_name; + const device_t *device; void (*reset)(void *p); } SCSI_CARD; @@ -102,7 +102,7 @@ char *scsi_card_getname(int card) } -device_t *scsi_card_getdevice(int card) +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 898596f68..0a8239cc6 100644 --- a/src/scsi/scsi.h +++ b/src/scsi/scsi.h @@ -8,7 +8,7 @@ * * SCSI controller handler header. * - * Version: @(#)scsi_h 1.0.13 2018/02/07 + * Version: @(#)scsi_h 1.0.14 2018/03/18 * * Authors: TheCollector1995, * Miran Grca, @@ -298,7 +298,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); diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index efc9a5fcb..efb34ebf8 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.39 2018/03/07 + * Version: @(#)scsi_aha154x.c 1.0.40 2018/03/18 * * Authors: Fred N. van Kempen, * Original Buslogic version by SA1988 and Miran Grca. @@ -733,7 +733,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; @@ -878,7 +878,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, { @@ -1009,7 +1009,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, { @@ -1108,7 +1108,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, @@ -1117,7 +1117,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, @@ -1126,7 +1126,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, @@ -1135,7 +1135,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 12c39b375..73eb10b89 100644 --- a/src/scsi/scsi_aha154x.h +++ b/src/scsi/scsi_aha154x.h @@ -2,10 +2,10 @@ # 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); diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index cd95e823b..e796ec23e 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -11,7 +11,7 @@ * 1 - BT-545S ISA; * 2 - BT-958D PCI * - * Version: @(#)scsi_buslogic.c 1.0.35 2018/03/07 + * Version: @(#)scsi_buslogic.c 1.0.36 2018/03/18 * * Authors: TheCollector1995, * Miran Grca, @@ -1446,7 +1446,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; @@ -1660,7 +1660,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, { @@ -1756,7 +1756,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 }, @@ -1766,7 +1766,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, @@ -1775,7 +1775,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, @@ -1784,7 +1784,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, @@ -1793,7 +1793,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, @@ -1802,7 +1802,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 4383ad640..83ce417d9 100644 --- a/src/scsi/scsi_buslogic.h +++ b/src/scsi/scsi_buslogic.h @@ -7,24 +7,24 @@ * Emulation of BusLogic BT-542B ISA and BT-958D PCI SCSI * controllers. * - * Version: @(#)scsi_buslogic.h 1.0.2 2017/10/14 + * Version: @(#)scsi_buslogic.h 1.0.3 2018/03/18 * * Authors: TheCollector1995, * Miran Grca, * Fred N. van Kempen, - * Copyright 2016,2017 Miran Grca. - * Copyright 2017 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. */ #ifndef SCSI_BUSLOGIC_H # 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 c5c374935..b4121ed36 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -6,7 +6,7 @@ * * Emulation of SCSI fixed and removable disks. * - * Version: @(#)scsi_disk.c 1.0.17 2018/03/07 + * Version: @(#)scsi_disk.c 1.0.18 2018/03/18 * * Author: Miran Grca, * @@ -78,7 +78,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 97440394f..fd88997c4 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.11 2018/03/07 + * Version: @(#)scsi_ncr5380.c 1.0.12 2018/03/18 * * Authors: Sarah Walker, * TheCollector1995, @@ -825,7 +825,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; @@ -948,7 +948,7 @@ scsiat_available(void) } -static device_config_t scsiat_config[] = { +static const device_config_t scsiat_config[] = { { "base", "Address", CONFIG_HEX16, "", 0x0310, { @@ -1045,7 +1045,7 @@ static device_config_t scsiat_config[] = { }; -device_t scsi_lcs6821n_device = +const device_t scsi_lcs6821n_device = { "Longshine LCS-6821N", DEVICE_ISA, @@ -1056,7 +1056,7 @@ device_t scsi_lcs6821n_device = NULL }; -device_t scsi_rt1000b_device = +const device_t scsi_rt1000b_device = { "Ranco RT1000B", DEVICE_ISA, @@ -1067,7 +1067,7 @@ device_t scsi_rt1000b_device = NULL }; -device_t scsi_t130b_device = +const device_t scsi_t130b_device = { "Trantor T130B", DEVICE_ISA, @@ -1078,7 +1078,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 6bafa8751..55b16f654 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 2017/12/16 + * Version: @(#)scsi_ncr5380.c 1.0.2 2018/03/18 * * Authors: Sarah Walker, * TheCollector1995, @@ -18,16 +18,16 @@ * * Copyright 2017-2018 Sarah Walker. * Copyright 2017-2018 TheCollector1995. - * Copyright 2018 Fred N. van Kempen. + * Copyright 2017,2018 Fred N. van Kempen. */ #ifndef SCSI_NCR5380_H # 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 04b4e9e40..0dcb1fced 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.9 2018/03/10 + * Version: @(#)scsi_ncr53c810.c 1.0.10 2018/03/18 * * Authors: Paul Brook (QEMU) * Artyom Tarasenko (QEMU) @@ -2134,7 +2134,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; @@ -2171,7 +2171,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 06286cda8..29666e935 100644 --- a/src/scsi/scsi_ncr53c810.h +++ b/src/scsi/scsi_ncr53c810.h @@ -10,22 +10,22 @@ * NCR and later Symbios and LSI. This controller was designed * for the PCI bus. * - * Version: @(#)scsi_ncr53c810.c 1.0.0 2017/12/10 + * Version: @(#)scsi_ncr53c810.c 1.0.1 2018/03/18 * * Authors: TheCollector1995, * Miran Grca, * Paul Brook (QEMU), * Artyom Tarasenko (QEMU), * - * Copyright 2006-2017 Paul Brook. - * Copyright 2009-2017 Artyom Tarasenko. - * Copyright 2017 Miran Grca. + * Copyright 2006-2018 Paul Brook. + * Copyright 2009-2018 Artyom Tarasenko. + * Copyright 2017,2018 Miran Grca. */ #ifndef SCSI_NCR5C3810_H # 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 9ed018692..10f27249f 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -11,7 +11,7 @@ * series of SCSI Host Adapters made by Mylex. * These controllers were designed for various buses. * - * Version: @(#)scsi_x54x.c 1.0.19 2018/03/09 + * Version: @(#)scsi_x54x.c 1.0.20 2018/03/18 * * Authors: TheCollector1995, * Miran Grca, @@ -1891,7 +1891,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 c9b0d190e..a35932169 100644 --- a/src/scsi/scsi_x54x.h +++ b/src/scsi/scsi_x54x.h @@ -11,7 +11,7 @@ * of SCSI Host Adapters made by Mylex. * These controllers were designed for various buses. * - * Version: @(#)scsi_x54x.h 1.0.5 2018/03/07 + * Version: @(#)scsi_x54x.h 1.0.6 2018/03/18 * * Authors: TheCollector1995, * Miran Grca, @@ -501,7 +501,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 bb0f5f5c7..d49eb6b29 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -25,10 +25,10 @@ typedef struct { const char *name; const char *internal_name; - device_t *device; + const device_t *device; } MIDI_DEVICE; -static MIDI_DEVICE devices[] = +static const MIDI_DEVICE devices[] = { {"None", "none", NULL}, #ifdef USE_FLUIDSYNTH @@ -57,7 +57,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 2b38c5a5f..6268a0e0c 100644 --- a/src/sound/midi.h +++ b/src/sound/midi.h @@ -8,7 +8,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 71aebb31c..6fff49a1f 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -236,7 +236,7 @@ void fluidsynth_sysex(uint8_t* data, unsigned int len) f_fluid_synth_sysex(d->synth, (const char *) data, len, 0, 0, 0, 0); } -void* fluidsynth_init(device_t *info) +void* fluidsynth_init(const device_t *info) { fluidsynth_t* data = &fsdev; memset(data, 0, sizeof(fluidsynth_t)); @@ -390,7 +390,7 @@ void fluidsynth_close(void* p) /* pclog("fluidsynth closed\n"); */ } -static device_config_t fluidsynth_config[] = +static const device_config_t fluidsynth_config[] = { { .name = "sound_font", @@ -566,7 +566,7 @@ static device_config_t fluidsynth_config[] = } }; -device_t fluidsynth_device = +const device_t fluidsynth_device = { "FluidSynth", 0, diff --git a/src/sound/midi_fluidsynth.h b/src/sound/midi_fluidsynth.h index 1daeb29c0..518b1461d 100644 --- a/src/sound/midi_fluidsynth.h +++ b/src/sound/midi_fluidsynth.h @@ -1 +1 @@ -extern device_t fluidsynth_device; +extern const device_t fluidsynth_device; diff --git a/src/sound/midi_mt32.c b/src/sound/midi_mt32.c index a218df8bb..2687c5e10 100644 --- a/src/sound/midi_mt32.c +++ b/src/sound/midi_mt32.c @@ -222,12 +222,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"); } @@ -265,7 +265,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", @@ -312,7 +312,7 @@ static device_config_t mt32_config[] = } }; -device_t mt32_device = +const device_t mt32_device = { "Roland MT-32 Emulation", 0, @@ -327,7 +327,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 b881ea4cc..0aa012fa1 100644 --- a/src/sound/midi_mt32.h +++ b/src/sound/midi_mt32.h @@ -1,2 +1,2 @@ -extern device_t mt32_device; -extern device_t cm32l_device; +extern const device_t mt32_device; +extern const device_t cm32l_device; diff --git a/src/sound/midi_system.c b/src/sound/midi_system.c index 209889401..cbf1a469a 100644 --- a/src/sound/midi_system.c +++ b/src/sound/midi_system.c @@ -11,7 +11,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)); @@ -39,7 +39,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", @@ -52,7 +52,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 7afbb4c45..b79bbf96f 100644 --- a/src/sound/midi_system.h +++ b/src/sound/midi_system.h @@ -1 +1 @@ -extern device_t system_midi_device; +extern const device_t system_midi_device; diff --git a/src/sound/snd_adlib.c b/src/sound/snd_adlib.c index 819fb12c0..cc9733bc5 100644 --- a/src/sound/snd_adlib.c +++ b/src/sound/snd_adlib.c @@ -63,7 +63,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)); @@ -75,7 +75,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); @@ -94,7 +94,7 @@ void adlib_close(void *p) free(adlib); } -device_t adlib_device = +const device_t adlib_device = { "AdLib", DEVICE_ISA, @@ -104,7 +104,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 1e2c363af..4a6a161ca 100644 --- a/src/sound/snd_adlib.h +++ b/src/sound/snd_adlib.h @@ -1,2 +1,2 @@ -extern device_t adlib_device; -extern device_t adlib_mca_device; +extern const device_t adlib_device; +extern const device_t adlib_mca_device; diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index 820dd020c..02e692491 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -754,7 +754,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; @@ -827,7 +827,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 @@ -837,7 +837,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 b952aaf03..daea1b490 100644 --- a/src/sound/snd_adlibgold.h +++ b/src/sound/snd_adlibgold.h @@ -1 +1 @@ -extern device_t adgold_device; +extern const device_t adgold_device; diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 716327192..a7e0257a9 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -1300,7 +1300,7 @@ void es1371_add_status_info(char *s, int max_len, void *p) es1371_add_status_info_dac(es1371, s, max_len, 1); } -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 5aff3d024..66600ed24 100644 --- a/src/sound/snd_audiopci.h +++ b/src/sound/snd_audiopci.h @@ -1 +1 @@ -extern device_t es1371_device; +extern const device_t es1371_device; diff --git a/src/sound/snd_cms.c b/src/sound/snd_cms.c index 69b0292a2..ce416650a 100644 --- a/src/sound/snd_cms.c +++ b/src/sound/snd_cms.c @@ -175,7 +175,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)); @@ -193,7 +193,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 d5795cc0f..41b6d6059 100644 --- a/src/sound/snd_cms.h +++ b/src/sound/snd_cms.h @@ -1 +1 @@ -extern device_t cms_device; +extern const device_t cms_device; diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index e04b5b55b..d08b01da8 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -996,7 +996,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; @@ -1058,7 +1058,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 6c124f9f8..89e8ea331 100644 --- a/src/sound/snd_gus.h +++ b/src/sound/snd_gus.h @@ -1 +1 @@ -extern device_t gus_device; +extern const device_t gus_device; diff --git a/src/sound/snd_mpu401.c b/src/sound/snd_mpu401.c index 9ae51c697..a885d72d3 100644 --- a/src/sound/snd_mpu401.c +++ b/src/sound/snd_mpu401.c @@ -8,16 +8,16 @@ * * Roland MPU-401 emulation. * - * Version: @(#)snd_mpu401.c 1.0.7 2017/11/23 + * Version: @(#)snd_mpu401.c 1.0.8 2018/03/18 * * Authors: Sarah Walker, * DOSBox Team, * Miran Grca, * TheCollector1995, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2008-2017 DOSBox Team. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2008-2018 DOSBox Team. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -895,7 +895,7 @@ mpu401_device_add(void) static void * -mpu401_standalone_init(device_t *info) +mpu401_standalone_init(const device_t *info) { mpu_t *mpu; @@ -918,7 +918,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, @@ -980,7 +980,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 41c1e9240..0dda1b25a 100644 --- a/src/sound/snd_mpu401.h +++ b/src/sound/snd_mpu401.h @@ -8,16 +8,16 @@ * * Roland MPU-401 emulation. * - * Version: @(#)sound_mpu401.h 1.0.0 2017/05/30 + * Version: @(#)sound_mpu401.h 1.0.1 2018/03/18 * * Author: Sarah Walker, * DOSBox Team, * Miran Grca, * TheCollector1995, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2008-2017 DOSBox Team. - * Copyright 2016-2017 Miran Grca. - * Copyright 2016-2017 TheCollector1995. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2008-2018 DOSBox Team. + * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2018 TheCollector1995. */ #define MPU401_VERSION 0x15 @@ -89,6 +89,6 @@ 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; +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 bf900df50..5a0c4738d 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -722,7 +722,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)); @@ -746,7 +746,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 e3a134751..d7a208faa 100644 --- a/src/sound/snd_pas16.h +++ b/src/sound/snd_pas16.h @@ -1 +1 @@ -extern device_t pas16_device; +extern const device_t pas16_device; diff --git a/src/sound/snd_pssj.c b/src/sound/snd_pssj.c index 0dfcfd6cf..2e200c589 100644 --- a/src/sound/snd_pssj.c +++ b/src/sound/snd_pssj.c @@ -184,7 +184,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)); @@ -205,7 +205,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 2255d48fb..71126f615 100644 --- a/src/sound/snd_pssj.h +++ b/src/sound/snd_pssj.h @@ -1 +1 @@ -extern device_t pssj_device; +extern const device_t pssj_device; diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 0f21b9464..c4c4ff255 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.5 2018/02/15 + * Version: @(#)sound_sb.c 1.0.6 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -1339,7 +1339,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, @@ -1397,7 +1397,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, @@ -1438,7 +1438,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, @@ -1496,7 +1496,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, @@ -1634,7 +1634,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, @@ -1815,7 +1815,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, @@ -1826,7 +1826,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, @@ -1837,7 +1837,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, @@ -1848,7 +1848,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, @@ -1859,7 +1859,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, @@ -1870,7 +1870,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, @@ -1881,7 +1881,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, @@ -1892,7 +1892,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, @@ -1903,7 +1903,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 a7197dfd2..feaec6c78 100644 --- a/src/sound/snd_sb.h +++ b/src/sound/snd_sb.h @@ -8,14 +8,14 @@ * * Sound Blaster emulation. * - * Version: @(#)sound_sb.h 1.0.2 2017/11/04 + * Version: @(#)sound_sb.h 1.0.3 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, * TheCollector1995, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #ifndef SOUND_SND_SB_H # define SOUND_SND_SB_H @@ -33,15 +33,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_SND_SB_H*/ diff --git a/src/sound/snd_sn76489.c b/src/sound/snd_sn76489.c index 0040f1769..c9dea8937 100644 --- a/src/sound/snd_sn76489.c +++ b/src/sound/snd_sn76489.c @@ -205,7 +205,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)); @@ -214,7 +214,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)); @@ -231,7 +231,7 @@ void sn76489_device_close(void *p) free(sn76489); } -device_t sn76489_device = +const device_t sn76489_device = { "TI SN74689 PSG", 0, @@ -241,7 +241,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 84c102821..01d19e0e5 100644 --- a/src/sound/snd_sn76489.h +++ b/src/sound/snd_sn76489.h @@ -5,8 +5,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 df2ff48da..5408a652d 100644 --- a/src/sound/snd_ssi2001.c +++ b/src/sound/snd_ssi2001.c @@ -57,7 +57,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)); @@ -79,7 +79,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 337c6260a..83af6838a 100644 --- a/src/sound/snd_ssi2001.h +++ b/src/sound/snd_ssi2001.h @@ -1 +1 @@ -extern device_t ssi2001_device; +extern const device_t ssi2001_device; diff --git a/src/sound/snd_wss.c b/src/sound/snd_wss.c index 5c97ebc35..8a6c82369 100644 --- a/src/sound/snd_wss.c +++ b/src/sound/snd_wss.c @@ -77,7 +77,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)); @@ -112,7 +112,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 bd387d6f3..0836e5808 100644 --- a/src/sound/snd_wss.h +++ b/src/sound/snd_wss.h @@ -1 +1 @@ -extern device_t wss_device; +extern const device_t wss_device; diff --git a/src/sound/sound.c b/src/sound/sound.c index de3bc47fd..66f8a0c87 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -8,7 +8,7 @@ * * Sound emulation core. * - * Version: @(#)sound.c 1.0.14 2018/02/18 + * Version: @(#)sound.c 1.0.15 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -45,7 +45,7 @@ typedef struct { const char *name; const char *internal_name; - device_t *device; + const device_t *device; } SOUND_CARD; typedef struct { @@ -77,7 +77,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 }, @@ -115,7 +115,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 5f26736cc..05bfe4959 100644 --- a/src/sound/sound.h +++ b/src/sound/sound.h @@ -8,7 +8,7 @@ * * Sound emulation core. * - * Version: @(#)sound.h 1.0.5 2018/02/15 + * Version: @(#)sound.h 1.0.6 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -45,7 +45,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 2081f0786..d31561816 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.7 2018/03/16 + * Version: @(#)vid_ati18800.c 1.0.8 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -215,7 +215,7 @@ static void ati18800_recalctimings(svga_t *svga) } } -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)); @@ -294,7 +294,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, @@ -308,7 +308,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, @@ -322,7 +322,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 b0d4bb55a..b41facab3 100644 --- a/src/video/vid_ati18800.h +++ b/src/video/vid_ati18800.h @@ -1,6 +1,6 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -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; diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 0a1a0337d..1d20906b1 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.12 2018/03/16 + * Version: @(#)vid_ati28800.c 1.0.13 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -387,7 +387,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)); @@ -422,7 +422,7 @@ ati28800k_init(device_t *info) } static void * -ati28800_init(device_t *info) +ati28800_init(const device_t *info) { ati28800_t *ati; ati = malloc(sizeof(ati28800_t)); @@ -555,7 +555,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, @@ -580,7 +580,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, @@ -605,7 +605,7 @@ static device_config_t ati28800_wonderxl_config[] = }; #endif -device_t ati28800_device = +const device_t ati28800_device = { "ATI-28800", DEVICE_ISA, @@ -618,7 +618,7 @@ device_t ati28800_device = ati28800_config }; -device_t ati28800k_device = +const device_t ati28800k_device = { "ATI Korean VGA", DEVICE_ISA, @@ -631,7 +631,7 @@ device_t ati28800k_device = ati28800_config }; -device_t compaq_ati28800_device = +const device_t compaq_ati28800_device = { "Compaq ATI-28800", DEVICE_ISA, @@ -645,7 +645,7 @@ device_t compaq_ati28800_device = }; #if defined(DEV_BRANCH) && defined(USE_XL24) -device_t ati28800_wonderxl24_device = +const device_t ati28800_wonderxl24_device = { "ATI-28800 (VGA Wonder XL24)", DEVICE_ISA, diff --git a/src/video/vid_ati28800.h b/src/video/vid_ati28800.h index 70535331a..9db0fa7bc 100644 --- a/src/video/vid_ati28800.h +++ b/src/video/vid_ati28800.h @@ -1,9 +1,9 @@ /* Copyright holders: Sarah Walker, Tenshi see COPYING for more details */ -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 3b349c635..b8f414ad3 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.16 2018/03/16 + * Version: @(#)vid_ati_mach64.c 1.0.17 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -3416,7 +3416,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)); @@ -3462,7 +3462,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); @@ -3487,7 +3487,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; @@ -3600,7 +3600,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, @@ -3624,7 +3624,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, @@ -3645,7 +3645,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, @@ -3658,7 +3658,7 @@ device_t mach64gx_isa_device = mach64gx_config }; -device_t mach64gx_vlb_device = +const device_t mach64gx_vlb_device = { "ATI Mach64GX VLB", DEVICE_VLB, @@ -3671,7 +3671,7 @@ device_t mach64gx_vlb_device = mach64gx_config }; -device_t mach64gx_pci_device = +const device_t mach64gx_pci_device = { "ATI Mach64GX PCI", DEVICE_PCI, @@ -3684,7 +3684,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 49dc5b9c8..c44444d7a 100644 --- a/src/video/vid_ati_mach64.h +++ b/src/video/vid_ati_mach64.h @@ -8,7 +8,7 @@ * * ATi Mach64 graphics card emulation. * - * Version: @(#)vid_ati_mach64.h 1.0.1 2018/01/21 + * Version: @(#)vid_ati_mach64.h 1.0.2 2018/03/18 * * Author: Sarah Walker, * Miran Grca, @@ -16,7 +16,7 @@ * Copyright 2016-2018 Miran Grca. */ -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; diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index 79dc94dc9..4f94e7e20 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.13 2018/01/25 + * Version: @(#)vid_cga.c 1.0.14 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -482,7 +482,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)); @@ -524,7 +524,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, @@ -585,7 +585,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 93c8bac68..74aba09c2 100644 --- a/src/video/vid_cga.h +++ b/src/video/vid_cga.h @@ -8,12 +8,12 @@ * * Emulation of the old and new IBM CGA graphics cards. * - * Version: @(#)vid_cga.h 1.0.2 2017/12/31 + * Version: @(#)vid_cga.h 1.0.3 2018/03/18 * * Author: Sarah Walker, * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ typedef struct cga_t @@ -61,5 +61,5 @@ 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; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index e58e11a23..de04c6fb2 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, CL-GD 5430, CL-GD 5434 and CL-GD 5436 are supported). * - * Version: @(#)vid_cl_54xx.c 1.0.9 2018/03/02 + * Version: @(#)vid_cl_54xx.c 1.0.10 2018/03/18 * * Authors: Sarah Walker, * Barry Rodewald, @@ -2290,7 +2290,7 @@ cl_pci_write(int func, int addr, uint8_t val, void *p) static void -*gd54xx_init(device_t *info) +*gd54xx_init(const device_t *info) { gd54xx_t *gd54xx = malloc(sizeof(gd54xx_t)); svga_t *svga = &gd54xx->svga; @@ -2451,7 +2451,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", @@ -2478,7 +2478,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 gd5426_vlb_device = +const device_t gd5426_vlb_device = { "Cirrus Logic CL-GD 5426 (VLB)", DEVICE_VLB, @@ -2520,7 +2520,7 @@ device_t gd5426_vlb_device = gd5428_config }; -device_t gd5428_isa_device = +const device_t gd5428_isa_device = { "Cirrus Logic CL-GD 5428 (ISA)", DEVICE_AT | DEVICE_ISA, @@ -2535,7 +2535,7 @@ device_t gd5428_isa_device = gd5428_config }; -device_t gd5428_vlb_device = +const device_t gd5428_vlb_device = { "Cirrus Logic CL-GD 5428 (VLB)", DEVICE_VLB, @@ -2550,7 +2550,7 @@ device_t gd5428_vlb_device = gd5428_config }; -device_t gd5429_isa_device = +const device_t gd5429_isa_device = { "Cirrus Logic CL-GD 5429 (ISA)", DEVICE_AT | DEVICE_ISA, @@ -2565,7 +2565,7 @@ device_t gd5429_isa_device = gd5428_config }; -device_t gd5429_vlb_device = +const device_t gd5429_vlb_device = { "Cirrus Logic CL-GD 5429 (VLB)", DEVICE_VLB, @@ -2580,7 +2580,7 @@ device_t gd5429_vlb_device = gd5428_config }; -device_t gd5430_vlb_device = +const device_t gd5430_vlb_device = { "Cirrus Logic CL-GD 5430 (VLB)", DEVICE_VLB, @@ -2595,7 +2595,7 @@ device_t gd5430_vlb_device = gd5428_config }; -device_t gd5430_pci_device = +const device_t gd5430_pci_device = { "Cirrus Logic CL-GD 5430 (PCI)", DEVICE_PCI, @@ -2610,7 +2610,7 @@ device_t gd5430_pci_device = gd5428_config }; -device_t gd5434_isa_device = +const device_t gd5434_isa_device = { "Cirrus Logic CL-GD 5434 (ISA)", DEVICE_AT | DEVICE_ISA, @@ -2625,7 +2625,7 @@ device_t gd5434_isa_device = gd5434_config }; -device_t gd5434_vlb_device = +const device_t gd5434_vlb_device = { "Cirrus Logic CL-GD 5434 (VLB)", DEVICE_VLB, @@ -2640,7 +2640,7 @@ device_t gd5434_vlb_device = gd5434_config }; -device_t gd5434_pci_device = +const device_t gd5434_pci_device = { "Cirrus Logic CL-GD 5434 (PCI)", DEVICE_PCI, @@ -2655,7 +2655,7 @@ device_t gd5434_pci_device = gd5434_config }; -device_t gd5436_pci_device = +const device_t gd5436_pci_device = { "Cirrus Logic CL-GD 5436 (PCI)", DEVICE_PCI, diff --git a/src/video/vid_cl54xx.h b/src/video/vid_cl54xx.h index 472d8316b..af7707f0a 100644 --- a/src/video/vid_cl54xx.h +++ b/src/video/vid_cl54xx.h @@ -1,14 +1,14 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -extern device_t gd5426_vlb_device; -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; \ No newline at end of file +extern const device_t gd5426_vlb_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; \ No newline at end of file diff --git a/src/video/vid_colorplus.c b/src/video/vid_colorplus.c index 6af4e1b81..d03c7d94d 100644 --- a/src/video/vid_colorplus.c +++ b/src/video/vid_colorplus.c @@ -8,13 +8,13 @@ * * Plantronics ColorPlus emulation. * - * Version: @(#)vid_colorplus.c 1.0.7 2017/11/14 + * Version: @(#)vid_colorplus.c 1.0.8 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -385,7 +385,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; @@ -426,7 +426,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, @@ -464,7 +464,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 3213b4edc..07a96ff4f 100644 --- a/src/video/vid_colorplus.h +++ b/src/video/vid_colorplus.h @@ -12,4 +12,4 @@ 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; diff --git a/src/video/vid_compaq_cga.c b/src/video/vid_compaq_cga.c index 17c0dbdef..10c518403 100644 --- a/src/video/vid_compaq_cga.c +++ b/src/video/vid_compaq_cga.c @@ -360,7 +360,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; @@ -432,9 +432,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, @@ -448,7 +448,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 b00e048ca..e6c684d52 100644 --- a/src/video/vid_compaq_cga.h +++ b/src/video/vid_compaq_cga.h @@ -3,8 +3,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 f990c17ce..2d73d46df 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.15 2018/02/01 + * Version: @(#)vid_ega.c 1.0.16 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -989,7 +989,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; @@ -1134,7 +1134,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); @@ -1183,7 +1183,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, @@ -1244,7 +1244,7 @@ static device_config_t ega_config[] = }; -device_t ega_device = +const device_t ega_device = { "EGA", DEVICE_ISA, @@ -1257,7 +1257,7 @@ device_t ega_device = ega_config }; -device_t cpqega_device = +const device_t cpqega_device = { "Compaq EGA", DEVICE_ISA, @@ -1270,7 +1270,7 @@ device_t cpqega_device = ega_config }; -device_t sega_device = +const device_t sega_device = { "SuperEGA", DEVICE_ISA, @@ -1284,7 +1284,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 2d21418be..e5590d052 100644 --- a/src/video/vid_ega.h +++ b/src/video/vid_ega.h @@ -9,7 +9,7 @@ * Emulation of the EGA, Chips & Technologies SuperEGA, and * AX JEGA graphics cards. * - * Version: @(#)vid_ega.h 1.0.6 2018/01/25 + * Version: @(#)vid_ega.h 1.0.7 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -115,9 +115,9 @@ 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) */ diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 6e76d2ecb..1dd4abb31 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.4 2018/02/25 + * Version: @(#)vid_et4000.c 1.0.5 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -160,7 +160,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)); @@ -213,7 +213,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 54daa1dd4..803f84729 100644 --- a/src/video/vid_et4000.h +++ b/src/video/vid_et4000.h @@ -1,4 +1,4 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -extern device_t et4000_device; +extern const device_t et4000_device; diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 3fe4c0399..19bb5c0a8 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.6 2018/02/11 + * Version: @(#)vid_et4000w32.c 1.0.7 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -1190,7 +1190,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)); @@ -1309,7 +1309,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, @@ -1330,7 +1330,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, @@ -1342,7 +1342,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, @@ -1355,7 +1355,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, @@ -1367,7 +1367,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 7abe28038..80a14e5d4 100644 --- a/src/video/vid_et4000w32.h +++ b/src/video/vid_et4000w32.h @@ -1,7 +1,7 @@ #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; diff --git a/src/video/vid_genius.c b/src/video/vid_genius.c index 3b5da4110..a205628ce 100644 --- a/src/video/vid_genius.c +++ b/src/video/vid_genius.c @@ -8,13 +8,13 @@ * * MDSI Genius VHR emulation. * - * Version: @(#)vid_genius.c 1.0.7 2017/11/04 + * Version: @(#)vid_genius.c 1.0.8 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -570,7 +570,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)); @@ -638,7 +638,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 77dce66f0..e1388ec5c 100644 --- a/src/video/vid_genius.h +++ b/src/video/vid_genius.h @@ -1 +1 @@ -extern device_t genius_device; +extern const device_t genius_device; diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index 188e4ea9e..d4ab49af4 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -8,13 +8,13 @@ * * Hercules emulation. * - * Version: @(#)vid_hercules.c 1.0.8 2017/11/14 + * Version: @(#)vid_hercules.c 1.0.9 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -331,7 +331,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)); @@ -391,7 +391,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, @@ -419,7 +419,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 869ff317d..3c145e18f 100644 --- a/src/video/vid_hercules.h +++ b/src/video/vid_hercules.h @@ -1,4 +1,4 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -extern device_t hercules_device; +extern const device_t hercules_device; diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index 282a1bb38..6a657bff7 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -8,13 +8,13 @@ * * Hercules InColor emulation. * - * Version: @(#)vid_herculesplus.c 1.0.6 2017/11/14 + * Version: @(#)vid_herculesplus.c 1.0.7 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -678,7 +678,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)); @@ -729,7 +729,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 377fd4ffd..72b47c35f 100644 --- a/src/video/vid_herculesplus.h +++ b/src/video/vid_herculesplus.h @@ -1,4 +1,4 @@ /* Copyright holders: John Elliott see COPYING for more details */ -extern device_t herculesplus_device; +extern const device_t herculesplus_device; diff --git a/src/video/vid_incolor.c b/src/video/vid_incolor.c index b3a81fca7..1a456f3b5 100644 --- a/src/video/vid_incolor.c +++ b/src/video/vid_incolor.c @@ -8,13 +8,13 @@ * * Hercules InColor emulation. * - * Version: @(#)vid_incolor.c 1.0.7 2017/11/14 + * Version: @(#)vid_incolor.c 1.0.8 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -1025,7 +1025,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)); @@ -1073,7 +1073,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 0e180ab82..d75a97186 100644 --- a/src/video/vid_incolor.h +++ b/src/video/vid_incolor.h @@ -1,4 +1,4 @@ /* Copyright holders: John Elliott see COPYING for more details */ -extern device_t incolor_device; +extern const device_t incolor_device; diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index 655ac231c..9f792207a 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -8,13 +8,13 @@ * * MDA emulation. * - * Version: @(#)vid_mda.c 1.0.9 2017/11/14 + * Version: @(#)vid_mda.c 1.0.10 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -280,7 +280,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)); @@ -340,7 +340,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, @@ -368,7 +368,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 f08e48d03..4e1e78e41 100644 --- a/src/video/vid_mda.h +++ b/src/video/vid_mda.h @@ -1,4 +1,4 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -extern device_t mda_device; +extern const device_t mda_device; diff --git a/src/video/vid_nv_riva128.c b/src/video/vid_nv_riva128.c index 6014bc5f9..9abc94cc0 100644 --- a/src/video/vid_nv_riva128.c +++ b/src/video/vid_nv_riva128.c @@ -8,13 +8,13 @@ * * nVidia RIVA 128 emulation. * - * Version: @(#)vid_nv_riva128.c 1.0.4 2017/11/04 + * Version: @(#)vid_nv_riva128.c 1.0.5 2018/03/18 * * Author: Melissa Goad * Miran Grca, * - * Copyright 2017 Melissa Goad. - * Copyright 2017 Miran Grca. + * Copyright 2015-2018 Melissa Goad. + * Copyright 2015-2018 Miran Grca. */ #include #include @@ -2985,7 +2985,7 @@ void riva128_ptimer_tick(void *p) } -void *riva128_init(device_t *info) +void *riva128_init(const device_t *info) { riva128_t *riva128 = malloc(sizeof(riva128_t)); memset(riva128, 0, sizeof(riva128_t)); @@ -3160,7 +3160,7 @@ void riva128_add_status_info(char *s, int max_len, void *p) svga_add_status_info(s, max_len, &riva128->svga); } -device_config_t riva128_config[] = +const device_config_t riva128_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 4, @@ -3185,7 +3185,7 @@ device_config_t riva128_config[] = }; #if 0 -device_config_t riva128zx_config[] = +const device_config_t riva128zx_config[] = { { .name = "memory", @@ -3221,7 +3221,7 @@ device_config_t riva128zx_config[] = }; #endif -device_t riva128_device = +const device_t riva128_device = { "nVidia RIVA 128", DEVICE_PCI, @@ -3237,7 +3237,7 @@ device_t riva128_device = }; -void *rivatnt_init(device_t *info) +void *rivatnt_init(const device_t *info) { riva128_t *riva128 = malloc(sizeof(riva128_t)); memset(riva128, 0, sizeof(riva128_t)); @@ -3393,7 +3393,7 @@ void rivatnt_add_status_info(char *s, int max_len, void *p) svga_add_status_info(s, max_len, &riva128->svga); } -device_config_t rivatnt_config[] = +const device_config_t rivatnt_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 16, @@ -3417,7 +3417,7 @@ device_config_t rivatnt_config[] = } }; -device_t rivatnt_device = +const device_t rivatnt_device = { "nVidia RIVA TNT", DEVICE_PCI, @@ -3432,7 +3432,7 @@ device_t rivatnt_device = rivatnt_config }; -void *rivatnt2_init(device_t *info) +void *rivatnt2_init(const device_t *info) { riva128_t *riva128 = malloc(sizeof(riva128_t)); memset(riva128, 0, sizeof(riva128_t)); @@ -3601,7 +3601,7 @@ void rivatnt2_add_status_info(char *s, int max_len, void *p) svga_add_status_info(s, max_len, &riva128->svga); } -device_config_t rivatnt2_config[] = +const device_config_t rivatnt2_config[] = { { "model", "Card model", CONFIG_SELECTION, "", 0, @@ -3642,7 +3642,7 @@ device_config_t rivatnt2_config[] = } }; -device_t rivatnt2_device = +const device_t rivatnt2_device = { "nVidia RIVA TNT2", DEVICE_PCI, diff --git a/src/video/vid_nv_riva128.h b/src/video/vid_nv_riva128.h index 5f0f545e5..8c8e2cd6b 100644 --- a/src/video/vid_nv_riva128.h +++ b/src/video/vid_nv_riva128.h @@ -1,3 +1,3 @@ -extern device_t riva128_device; -extern device_t rivatnt_device; -extern device_t rivatnt2_device; +extern const device_t riva128_device; +extern const device_t rivatnt_device; +extern const device_t rivatnt2_device; diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index 027e93b95..15781aa32 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.8 2018/03/02 + * Version: @(#)vid_oak_oti.c 1.0.9 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -218,7 +218,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; @@ -309,7 +309,7 @@ oti067_077_available(void) } -static device_config_t oti067_config[] = +static const device_config_t oti067_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 512, @@ -331,7 +331,7 @@ static device_config_t oti067_config[] = }; -static device_config_t oti077_config[] = +static const device_config_t oti077_config[] = { { "memory", "Memory size", CONFIG_SELECTION, "", 1024, @@ -355,7 +355,7 @@ static device_config_t oti077_config[] = } }; -device_t oti037c_device = +const device_t oti037c_device = { "Oak OTI-037C", DEVICE_ISA, @@ -368,7 +368,7 @@ device_t oti037c_device = oti067_config }; -device_t oti067_device = +const device_t oti067_device = { "Oak OTI-067", DEVICE_ISA, @@ -381,7 +381,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 4652e4436..6a4d3cb1f 100644 --- a/src/video/vid_oak_oti.h +++ b/src/video/vid_oak_oti.h @@ -1,7 +1,7 @@ /* Copyright holders: Sarah Walker, Tenshi see COPYING for more details */ -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; diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index dd96b1884..dda19b26d 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -10,7 +10,7 @@ * PC2086, PC3086 use PVGA1A * MegaPC uses W90C11A * - * Version: @(#)vid_paradise.c 1.0.5 2018/02/03 + * Version: @(#)vid_paradise.c 1.0.5 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -279,7 +279,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; @@ -312,7 +312,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; @@ -347,7 +347,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; @@ -382,7 +382,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); @@ -391,7 +391,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); @@ -401,7 +401,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; @@ -422,7 +422,7 @@ static int paradise_pvga1a_standalone_available(void) return rom_present(L"roms/video/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); @@ -435,7 +435,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); @@ -450,7 +450,7 @@ static int paradise_wd90c11_standalone_available(void) return rom_present(L"roms/video/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; @@ -502,7 +502,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, @@ -515,7 +515,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, @@ -529,7 +529,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, @@ -553,7 +553,7 @@ static device_config_t paradise_pvga1a_config[] = } }; -device_t paradise_pvga1a_device = +const device_t paradise_pvga1a_device = { "Paradise PVGA1A", DEVICE_ISA, @@ -567,7 +567,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, @@ -580,7 +580,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, @@ -594,7 +594,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, @@ -615,7 +615,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 19c34b582..bdc4734aa 100644 --- a/src/video/vid_paradise.h +++ b/src/video/vid_paradise.h @@ -1,9 +1,9 @@ /* Copyright holders: Sarah Walker, Tenshi see COPYING for more details */ -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; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 21034e812..22777421c 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -8,7 +8,7 @@ * * S3 emulation. * - * Version: @(#)vid_s3.c 1.0.6 2018/03/07 + * Version: @(#)vid_s3.c 1.0.7 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -2164,7 +2164,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; @@ -2258,7 +2258,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); @@ -2273,13 +2273,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/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/86c864p.bin"); return s3; @@ -2295,7 +2295,7 @@ static int s3_phoenix_vision864_available(void) return rom_present(L"roms/video/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/86c732p.bin", S3_TRIO32); @@ -2315,7 +2315,7 @@ static int s3_phoenix_trio32_available(void) return rom_present(L"roms/video/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); @@ -2329,13 +2329,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_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/86c764x1.bin"); if (device_get_config_int("memory") == 1) @@ -2343,7 +2343,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) @@ -2351,7 +2351,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/stealt64.bin"); if (device_get_config_int("memory") == 1) @@ -2419,7 +2419,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, @@ -2444,7 +2444,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, @@ -2480,7 +2480,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, @@ -2504,7 +2504,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, @@ -2528,7 +2528,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, @@ -2552,7 +2552,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, @@ -2567,7 +2567,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, @@ -2582,7 +2582,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, @@ -2597,7 +2597,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, @@ -2612,7 +2612,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, @@ -2627,7 +2627,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, @@ -2642,7 +2642,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, @@ -2657,7 +2657,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, @@ -2672,7 +2672,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, @@ -2687,7 +2687,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, @@ -2702,7 +2702,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, @@ -2717,7 +2717,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, @@ -2732,7 +2732,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 071cee218..04888acdb 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/09 + * Version: @(#)vid_s3.h 1.0.2 2018/03/18 * * Author: Sarah Walker, * Miran Grca, @@ -17,17 +17,17 @@ * Copyright 2016-2018 Miran Grca. */ -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; -/* device_t s3_miro_vision964_device; */ +const device_t s3_bahamas64_vlb_device; +const device_t s3_bahamas64_pci_device; +const device_t s3_9fx_vlb_device; +const device_t s3_9fx_pci_device; +const device_t s3_phoenix_trio32_vlb_device; +const device_t s3_phoenix_trio32_pci_device; +const device_t s3_phoenix_trio64_vlb_device; +const device_t s3_phoenix_trio64_onboard_pci_device; +const device_t s3_phoenix_trio64_pci_device; +const device_t s3_phoenix_vision864_pci_device; +const device_t s3_phoenix_vision864_vlb_device; +const device_t s3_diamond_stealth64_pci_device; +const device_t s3_diamond_stealth64_vlb_device; +/* const device_t s3_miro_vision964_device; */ diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 41a1eebe3..5747d1119 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -8,13 +8,13 @@ * * S3 ViRGE emulation. * - * Version: @(#)vid_s3_virge.c 1.0.5 2017/12/28 + * Version: @(#)vid_s3_virge.c 1.0.6 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -3773,7 +3773,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)); @@ -3873,7 +3873,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)); @@ -3972,7 +3972,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)); @@ -4072,12 +4072,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/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/s3virge/86c375_4.bin"); } @@ -4160,7 +4160,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, @@ -4187,7 +4187,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, @@ -4202,7 +4202,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, @@ -4217,7 +4217,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, @@ -4232,7 +4232,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, @@ -4247,7 +4247,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, @@ -4262,7 +4262,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, @@ -4277,7 +4277,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, @@ -4292,7 +4292,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 85389eb40..2d340f649 100644 --- a/src/video/vid_s3_virge.h +++ b/src/video/vid_s3_virge.h @@ -1,11 +1,11 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -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; diff --git a/src/video/vid_t1000.c b/src/video/vid_t1000.c deleted file mode 100644 index a71e10b8e..000000000 --- a/src/video/vid_t1000.c +++ /dev/null @@ -1,721 +0,0 @@ -/* Emulate the Toshiba 1000 plasma display. This display has a fixed 640x200 - * resolution. */ -#include -#include -#include -#include -#include - -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../timer.h" -#include "../cpu/cpu.h" -#include "video.h" -#include "vid_cga.h" -#include "vid_t1000.h" - -#define T1000_XSIZE 640 -#define T1000_YSIZE 200 - -/* Mapping of attributes to colours */ -static uint32_t blue, grey; -static uint8_t boldcols[256]; /* Which attributes use the bold font */ -static uint32_t blinkcols[256][2]; -static uint32_t normcols[256][2]; -static uint8_t language; - -/* Video options set by the motherboard; they will be picked up by the card - * on the next poll. - * - * Bit 1: Danish - * Bit 0: Thin font - */ -static uint8_t st_video_options; -static uint8_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) -{ - st_display_internal = internal; -} - -uint8_t t1000_display_get() -{ - return 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 dispontime, dispofftime; - - int linepos, displine; - int vc; - int dispon; - int vsynctime; - uint8_t video_options; - - uint8_t *vram; -} t1000_t; - - -static void t1000_recalctimings(t1000_t *t1000); -static void t1000_write(uint32_t addr, uint8_t val, void *p); -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) -{ - t1000_t *t1000 = (t1000_t *)p; - switch (addr) - { - /* Emulated CRTC, register select */ - case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: - cga_out(addr, val, &t1000->cga); - break; - - /* Emulated CRTC, value */ - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - /* Register 0x12 controls the attribute mappings for the - * LCD screen. */ - if (t1000->cga.crtcreg == 0x12) - { - t1000->attrmap = val; - t1000_recalcattrs(t1000); - return; - } - cga_out(addr, val, &t1000->cga); - - t1000_recalctimings(t1000); - return; - - /* CGA control register */ - case 0x3D8: - cga_out(addr, val, &t1000->cga); - return; - /* CGA colour register */ - case 0x3D9: - cga_out(addr, val, &t1000->cga); - return; - } -} - -static uint8_t t1000_in(uint16_t addr, void *p) -{ - t1000_t *t1000 = (t1000_t *)p; - uint8_t val; - - switch (addr) - { - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - if (t1000->cga.crtcreg == 0x12) - { - val = t1000->attrmap & 0x0F; - if (t1000->internal) val |= 0x20; /* LCD / CRT */ - return val; - } - } - - return cga_in(addr, &t1000->cga); -} - - - - -static void t1000_write(uint32_t addr, uint8_t val, void *p) -{ - t1000_t *t1000 = (t1000_t *)p; - egawrites++; - -// pclog("CGA_WRITE %04X %02X\n", addr, val); - t1000->vram[addr & 0x3fff] = val; - cycles -= 4; -} - -static uint8_t t1000_read(uint32_t addr, void *p) -{ - t1000_t *t1000 = (t1000_t *)p; - egareads++; - cycles -= 4; - -// pclog("CGA_READ %04X\n", addr); - return t1000->vram[addr & 0x3fff]; -} - - - -static void t1000_recalctimings(t1000_t *t1000) -{ - double disptime; - double _dispontime, _dispofftime; - - if (!t1000->internal) - { - cga_recalctimings(&t1000->cga); - return; - } - disptime = 651; - _dispontime = 640; - _dispofftime = disptime - _dispontime; - t1000->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - t1000->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); -} - -/* Draw a row of text in 80-column mode */ -static void t1000_text_row80(t1000_t *t1000) -{ - uint32_t cols[2]; - int x, c; - uint8_t chr, attr; - int drawcursor; - int cursorline; - int bold; - int blink; - uint16_t addr; - uint8_t sc; - uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; - uint16_t ca = (t1000->cga.crtc[15] | (t1000->cga.crtc[14] << 8)) & 0x3fff; - - sc = (t1000->displine) & 7; - addr = ((ma & ~1) + (t1000->displine >> 3) * 80) * 2; - ma += (t1000->displine >> 3) * 80; - - if ((t1000->cga.crtc[10] & 0x60) == 0x20) - { - cursorline = 0; - } - else - { - cursorline = ((t1000->cga.crtc[10] & 0x0F) <= sc) && - ((t1000->cga.crtc[11] & 0x0F) >= sc); - } - for (x = 0; x < 80; x++) - { - chr = t1000->vram[(addr + 2 * x) & 0x3FFF]; - attr = t1000->vram[(addr + 2 * x + 1) & 0x3FFF]; - drawcursor = ((ma == ca) && cursorline && - (t1000->cga.cgamode & 8) && (t1000->cga.cgablink & 16)); - - blink = ((t1000->cga.cgablink & 16) && (t1000->cga.cgamode & 0x20) && - (attr & 0x80) && !drawcursor); - - if (t1000->video_options & 1) - bold = boldcols[attr] ? chr : chr + 256; - else - bold = boldcols[attr] ? chr + 256 : chr; - if (t1000->video_options & 2) - bold += 512; - - if (t1000->cga.cgamode & 0x20) /* Blink */ - { - cols[1] = blinkcols[attr][1]; - cols[0] = blinkcols[attr][0]; - if (blink) cols[1] = cols[0]; - } - else - { - cols[1] = normcols[attr][1]; - cols[0] = normcols[attr][0]; - } - if (drawcursor) - { - for (c = 0; c < 8; c++) - { - ((uint32_t *)buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey); - } - } - else - { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; - } - ++ma; - } -} - -/* Draw a row of text in 40-column mode */ -static void t1000_text_row40(t1000_t *t1000) -{ - uint32_t cols[2]; - int x, c; - uint8_t chr, attr; - int drawcursor; - int cursorline; - int bold; - int blink; - uint16_t addr; - uint8_t sc; - uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; - uint16_t ca = (t1000->cga.crtc[15] | (t1000->cga.crtc[14] << 8)) & 0x3fff; - - sc = (t1000->displine) & 7; - addr = ((ma & ~1) + (t1000->displine >> 3) * 40) * 2; - ma += (t1000->displine >> 3) * 40; - - if ((t1000->cga.crtc[10] & 0x60) == 0x20) - { - cursorline = 0; - } - else - { - cursorline = ((t1000->cga.crtc[10] & 0x0F) <= sc) && - ((t1000->cga.crtc[11] & 0x0F) >= sc); - } - for (x = 0; x < 40; x++) - { - chr = t1000->vram[(addr + 2 * x) & 0x3FFF]; - attr = t1000->vram[(addr + 2 * x + 1) & 0x3FFF]; - drawcursor = ((ma == ca) && cursorline && - (t1000->cga.cgamode & 8) && (t1000->cga.cgablink & 16)); - - blink = ((t1000->cga.cgablink & 16) && (t1000->cga.cgamode & 0x20) && - (attr & 0x80) && !drawcursor); - - if (t1000->video_options & 1) - bold = boldcols[attr] ? chr : chr + 256; - else - bold = boldcols[attr] ? chr + 256 : chr; - if (t1000->video_options & 2) - bold += 512; - - if (t1000->cga.cgamode & 0x20) /* Blink */ - { - cols[1] = blinkcols[attr][1]; - cols[0] = blinkcols[attr][0]; - if (blink) cols[1] = cols[0]; - } - else - { - cols[1] = normcols[attr][1]; - cols[0] = normcols[attr][0]; - } - if (drawcursor) - { - for (c = 0; c < 8; c++) - { - ((uint32_t *)buffer32->line[t1000->displine])[(x << 4) + c*2] = - ((uint32_t *)buffer32->line[t1000->displine])[(x << 4) + c*2 + 1] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey); - } - } - else - { - for (c = 0; c < 8; c++) - { - ((uint32_t *)buffer32->line[t1000->displine])[(x << 4) + c*2] = - ((uint32_t *)buffer32->line[t1000->displine])[(x << 4) + c*2+1] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - ++ma; - } -} - -/* Draw a line in CGA 640x200 mode */ -static void t1000_cgaline6(t1000_t *t1000) -{ - int x, c; - uint8_t dat; - uint32_t ink = 0; - uint16_t addr; - uint32_t fg = (t1000->cga.cgacol & 0x0F) ? blue : grey; - uint32_t bg = grey; - - uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; - - addr = ((t1000->displine) & 1) * 0x2000 + - (t1000->displine >> 1) * 80 + - ((ma & ~1) << 1); - - for (x = 0; x < 80; x++) - { - dat = t1000->vram[addr & 0x3FFF]; - addr++; - - for (c = 0; c < 8; c++) - { - ink = (dat & 0x80) ? fg : bg; - if (!(t1000->cga.cgamode & 8)) - ink = grey; - ((uint32_t *)buffer32->line[t1000->displine])[x*8+c] = ink; - dat = dat << 1; - } - } -} - -/* 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) -{ - int x, c; - uint8_t dat, pattern; - uint32_t ink0 = 0, ink1 = 0; - uint16_t addr; - - uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; - addr = ((t1000->displine) & 1) * 0x2000 + - (t1000->displine >> 1) * 80 + - ((ma & ~1) << 1); - - for (x = 0; x < 80; x++) - { - dat = t1000->vram[addr & 0x3FFF]; - addr++; - - for (c = 0; c < 4; c++) - { - pattern = (dat & 0xC0) >> 6; - if (!(t1000->cga.cgamode & 8)) pattern = 0; - - switch (pattern & 3) - { - case 0: ink0 = ink1 = grey; break; - case 1: if (t1000->displine & 1) - { - ink0 = grey; ink1 = grey; - } - else - { - ink0 = blue; ink1 = grey; - } - break; - case 2: if (t1000->displine & 1) - { - ink0 = grey; ink1 = blue; - } - else - { - ink0 = blue; ink1 = grey; - } - break; - case 3: ink0 = ink1 = blue; break; - - } - ((uint32_t *)buffer32->line[t1000->displine])[x*8+2*c] = ink0; - ((uint32_t *)buffer32->line[t1000->displine])[x*8+2*c+1] = ink1; - dat = dat << 2; - } - } -} - -static void t1000_poll(void *p) -{ - t1000_t *t1000 = (t1000_t *)p; - - if (t1000->video_options != st_video_options) - { - t1000->video_options = st_video_options; - - /* Set the font used for the external display */ - t1000->cga.fontbase = ((t1000->video_options & 3) * 256); - } - /* Switch between internal plasma and external CRT display. */ - if (st_display_internal != -1 && st_display_internal != t1000->internal) - { - t1000->internal = st_display_internal; - t1000_recalctimings(t1000); - } - if (!t1000->internal) - { - cga_poll(&t1000->cga); - return; - } - - if (!t1000->linepos) - { - t1000->cga.vidtime += t1000->dispofftime; - t1000->cga.cgastat |= 1; - t1000->linepos = 1; - if (t1000->dispon) - { - if (t1000->displine == 0) - { - video_wait_for_buffer(); - } - - /* Graphics */ - if (t1000->cga.cgamode & 0x02) - { - if (t1000->cga.cgamode & 0x10) - t1000_cgaline6(t1000); - else t1000_cgaline4(t1000); - } - else - if (t1000->cga.cgamode & 0x01) /* High-res text */ - { - t1000_text_row80(t1000); - } - else - { - t1000_text_row40(t1000); - } - } - t1000->displine++; - /* Hardcode a fixed refresh rate and VSYNC timing */ - if (t1000->displine == 200) /* Start of VSYNC */ - { - t1000->cga.cgastat |= 8; - t1000->dispon = 0; - } - if (t1000->displine == 216) /* End of VSYNC */ - { - t1000->displine = 0; - t1000->cga.cgastat &= ~8; - t1000->dispon = 1; - } - } - else - { - if (t1000->dispon) - { - t1000->cga.cgastat &= ~1; - } - t1000->cga.vidtime += t1000->dispontime; - t1000->linepos = 0; - - if (t1000->displine == 200) - { - /* Hardcode 640x200 window size */ - if (T1000_XSIZE != xsize || T1000_YSIZE != ysize) - { - xsize = T1000_XSIZE; - ysize = T1000_YSIZE; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize); - } - video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); - - frames++; - /* Fixed 640x200 resolution */ - video_res_x = T1000_XSIZE; - video_res_y = T1000_YSIZE; - - if (t1000->cga.cgamode & 0x02) - { - if (t1000->cga.cgamode & 0x10) - video_bpp = 1; - else video_bpp = 2; - - } - else video_bpp = 0; - t1000->cga.cgablink++; - } - } -} - -static void t1000_recalcattrs(t1000_t *t1000) -{ - int n; - - /* val behaves as follows: - * Bit 0: Attributes 01-06, 08-0E are inverse video - * Bit 1: Attributes 01-06, 08-0E are bold - * Bit 2: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF - * are inverse video - * Bit 3: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF - * are bold */ - - /* Set up colours */ - blue = makecol(0x2D, 0x39, 0x5A); - grey = makecol(0x85, 0xa0, 0xD6); - - /* Initialise the attribute mapping. Start by defaulting everything - * to grey on blue, and with bold set by bit 3 */ - for (n = 0; n < 256; n++) - { - boldcols[n] = (n & 8) != 0; - blinkcols[n][0] = normcols[n][0] = blue; - blinkcols[n][1] = normcols[n][1] = grey; - } - - /* Colours 0x11-0xFF are controlled by bits 2 and 3 of the - * passed value. Exclude x0 and x8, which are always grey on - * blue. */ - for (n = 0x11; n <= 0xFF; n++) - { - if ((n & 7) == 0) continue; - if (t1000->attrmap & 4) /* Inverse */ - { - blinkcols[n][0] = normcols[n][0] = blue; - blinkcols[n][1] = normcols[n][1] = grey; - } - else /* Normal */ - { - blinkcols[n][0] = normcols[n][0] = grey; - blinkcols[n][1] = normcols[n][1] = blue; - } - if (t1000->attrmap & 8) boldcols[n] = 1; /* Bold */ - } - /* Set up the 01-0E range, controlled by bits 0 and 1 of the - * passed value. When blinking is enabled this also affects 81-8E. */ - for (n = 0x01; n <= 0x0E; n++) - { - if (n == 7) continue; - if (t1000->attrmap & 1) - { - blinkcols[n][0] = normcols[n][0] = blue; - blinkcols[n][1] = normcols[n][1] = grey; - blinkcols[n+128][0] = blue; - blinkcols[n+128][1] = grey; - } - else - { - blinkcols[n][0] = normcols[n][0] = grey; - blinkcols[n][1] = normcols[n][1] = blue; - blinkcols[n+128][0] = grey; - blinkcols[n+128][1] = blue; - } - if (t1000->attrmap & 2) boldcols[n] = 1; - } - /* Colours 07 and 0F are always blue on grey. If blinking is - * enabled so are 87 and 8F. */ - for (n = 0x07; n <= 0x0F; n += 8) - { - blinkcols[n][0] = normcols[n][0] = grey; - blinkcols[n][1] = normcols[n][1] = blue; - blinkcols[n+128][0] = grey; - blinkcols[n+128][1] = blue; - } - /* When not blinking, colours 81-8F are always blue on grey. */ - for (n = 0x81; n <= 0x8F; n ++) - { - normcols[n][0] = grey; - normcols[n][1] = blue; - boldcols[n] = (n & 0x08) != 0; - } - - - /* Finally do the ones which are solid grey. These differ between - * the normal and blinking mappings */ - for (n = 0; n <= 0xFF; n += 0x11) - { - normcols[n][0] = normcols[n][1] = grey; - } - /* In the blinking range, 00 11 22 .. 77 and 80 91 A2 .. F7 are grey */ - for (n = 0; n <= 0x77; n += 0x11) - { - blinkcols[n][0] = blinkcols[n][1] = grey; - blinkcols[n+128][0] = blinkcols[n+128][1] = grey; - } -} - - -static void *t1000_init(device_t *info) -{ - t1000_t *t1000 = malloc(sizeof(t1000_t)); - memset(t1000, 0, sizeof(t1000_t)); - cga_init(&t1000->cga); - - t1000->internal = 1; - - /* 16k video RAM */ - t1000->vram = malloc(0x4000); - - timer_add(t1000_poll, &t1000->cga.vidtime, TIMER_ALWAYS_ENABLED, t1000); - - /* Occupy memory between 0xB8000 and 0xBFFFF */ - mem_mapping_add(&t1000->mapping, 0xb8000, 0x8000, t1000_read, NULL, NULL, t1000_write, NULL, NULL, NULL, 0, t1000); - /* Respond to CGA I/O ports */ - io_sethandler(0x03d0, 0x000c, t1000_in, NULL, NULL, t1000_out, NULL, NULL, t1000); - - /* Default attribute mapping is 4 */ - t1000->attrmap = 4; - t1000_recalcattrs(t1000); - - /* Start off in 80x25 text mode */ - t1000->cga.cgastat = 0xF4; - t1000->cga.vram = t1000->vram; - t1000->enabled = 1; - t1000->video_options = 0x01; - language = device_get_config_int("display_language") ? 2 : 0; - return t1000; -} - -static void t1000_close(void *p) -{ - t1000_t *t1000 = (t1000_t *)p; - - free(t1000->vram); - free(t1000); -} - -static void t1000_speed_changed(void *p) -{ - t1000_t *t1000 = (t1000_t *)p; - - t1000_recalctimings(t1000); -} - -static device_config_t t1000_config[] = -{ - { - .name = "display_language", - .description = "Language", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "USA", - .value = 0 - }, - { - .description = "Danish", - .value = 1 - } - }, - .default_int = 0 - }, - { - .type = -1 - } -}; - - -device_t t1000_device = -{ - "Toshiba T1000", - 0, - 0, - t1000_init, - t1000_close, - NULL, - NULL, - t1000_speed_changed, - NULL, - NULL, - t1000_config -}; - - -device_t t1200_device = -{ - "Toshiba T1200", - 0, - 0, - t1000_init, - t1000_close, - NULL, - NULL, - t1000_speed_changed, - NULL, - NULL, - t1000_config -}; diff --git a/src/video/vid_t1000.h b/src/video/vid_t1000.h deleted file mode 100644 index bfd292a5f..000000000 --- a/src/video/vid_t1000.h +++ /dev/null @@ -1,5 +0,0 @@ -extern device_t t1000_device; -extern device_t t1200_device; - -void t1000_video_options_set(uint8_t options); -void t1000_display_set(uint8_t internal); diff --git a/src/video/vid_t3100e.c b/src/video/vid_t3100e.c deleted file mode 100644 index e7ce5e45b..000000000 --- a/src/video/vid_t3100e.c +++ /dev/null @@ -1,726 +0,0 @@ -/* Emulate the Toshiba 3100e plasma display. This display has a fixed 640x400 - * resolution. */ -#include -#include -#include -#include -#include - -#include "../86box.h" -#include "../device.h" -#include "../io.h" -#include "../mem.h" -#include "../timer.h" -#include "../cpu/cpu.h" -#include "video.h" -#include "vid_cga.h" -#include "vid_t3100e.h" - -#define T3100E_XSIZE 640 -#define T3100E_YSIZE 400 - -/* T3100e CRTC regs (from the ROM): - * - * Selecting a character height of 3 seems to be sufficient to convert the - * 640x200 graphics mode to 640x400 (and, by analogy, 320x200 to 320x400). - * - * - * Horiz-----> Vert------> I ch - * 38 28 2D 0A 1F 06 19 1C 02 07 06 07 CO40 - * 71 50 5A 0A 1F 06 19 1C 02 07 06 07 CO80 - * 38 28 2D 0A 7F 06 64 70 02 01 06 07 Graphics - * 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 - */ - -/* Mapping of attributes to colours */ -static uint32_t amber, black; -static uint8_t boldcols[256]; /* Which attributes use the bold font */ -static uint32_t blinkcols[256][2]; -static uint32_t normcols[256][2]; - -/* Video options set by the motherboard; they will be picked up by the card - * on the next poll. - * - * Bit 3: Disable built-in video (for add-on card) - * Bit 2: Thin font - * Bits 0,1: Font set (not currently implemented) - */ -static uint8_t st_video_options; -static uint8_t st_display_internal = -1; - -void t3100e_video_options_set(uint8_t options) -{ - st_video_options = options; -} - -void t3100e_display_set(uint8_t internal) -{ - st_display_internal = internal; -} - -uint8_t t3100e_display_get() -{ - return st_display_internal; -} - - -typedef struct t3100e_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 dispontime, dispofftime; - - int linepos, displine; - int vc; - int dispon; - int vsynctime; - uint8_t video_options; - - uint8_t *vram; -} t3100e_t; - - -void t3100e_recalctimings(t3100e_t *t3100e); -void t3100e_write(uint32_t addr, uint8_t val, void *p); -uint8_t t3100e_read(uint32_t addr, void *p); -void t3100e_recalcattrs(t3100e_t *t3100e); - - -void t3100e_out(uint16_t addr, uint8_t val, void *p) -{ - t3100e_t *t3100e = (t3100e_t *)p; - switch (addr) - { - /* Emulated CRTC, register select */ - case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: - cga_out(addr, val, &t3100e->cga); - break; - - /* Emulated CRTC, value */ - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - /* Register 0x12 controls the attribute mappings for the - * plasma screen. */ - if (t3100e->cga.crtcreg == 0x12) - { - t3100e->attrmap = val; - t3100e_recalcattrs(t3100e); - return; - } - cga_out(addr, val, &t3100e->cga); - - t3100e_recalctimings(t3100e); - return; - - /* CGA control register */ - case 0x3D8: - cga_out(addr, val, &t3100e->cga); - return; - /* CGA colour register */ - case 0x3D9: - cga_out(addr, val, &t3100e->cga); - return; - } -} - -uint8_t t3100e_in(uint16_t addr, void *p) -{ - t3100e_t *t3100e = (t3100e_t *)p; - uint8_t val; - - switch (addr) - { - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - if (t3100e->cga.crtcreg == 0x12) - { - val = t3100e->attrmap & 0x0F; - if (t3100e->internal) val |= 0x30; /* Plasma / CRT */ - return val; - } - } - - return cga_in(addr, &t3100e->cga); -} - - - - -void t3100e_write(uint32_t addr, uint8_t val, void *p) -{ - t3100e_t *t3100e = (t3100e_t *)p; - egawrites++; - -// pclog("CGA_WRITE %04X %02X\n", addr, val); - t3100e->vram[addr & 0x7fff] = val; - cycles -= 4; -} - - - -uint8_t t3100e_read(uint32_t addr, void *p) -{ - t3100e_t *t3100e = (t3100e_t *)p; - egareads++; - cycles -= 4; - -// pclog("CGA_READ %04X\n", addr); - return t3100e->vram[addr & 0x7fff]; -} - - - -void t3100e_recalctimings(t3100e_t *t3100e) -{ - double disptime; - double _dispontime, _dispofftime; - - if (!t3100e->internal) - { - cga_recalctimings(&t3100e->cga); - return; - } - disptime = 651; - _dispontime = 640; - _dispofftime = disptime - _dispontime; - t3100e->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - t3100e->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); -} - - -/* Draw a row of text in 80-column mode */ -void t3100e_text_row80(t3100e_t *t3100e) -{ - uint32_t cols[2]; - int x, c; - uint8_t chr, attr; - int drawcursor; - int cursorline; - int bold; - int blink; - uint16_t addr; - uint8_t sc; - uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff; - uint16_t ca = (t3100e->cga.crtc[15] | (t3100e->cga.crtc[14] << 8)) & 0x7fff; - - sc = (t3100e->displine) & 15; - addr = ((ma & ~1) + (t3100e->displine >> 4) * 80) * 2; - ma += (t3100e->displine >> 4) * 80; - - if ((t3100e->cga.crtc[10] & 0x60) == 0x20) - { - cursorline = 0; - } - else - { - cursorline = ((t3100e->cga.crtc[10] & 0x0F)*2 <= sc) && - ((t3100e->cga.crtc[11] & 0x0F)*2 >= sc); - } - for (x = 0; x < 80; x++) - { - chr = t3100e->vram[(addr + 2 * x) & 0x7FFF]; - attr = t3100e->vram[(addr + 2 * x + 1) & 0x7FFF]; - drawcursor = ((ma == ca) && cursorline && - (t3100e->cga.cgamode & 8) && (t3100e->cga.cgablink & 16)); - - blink = ((t3100e->cga.cgablink & 16) && (t3100e->cga.cgamode & 0x20) && - (attr & 0x80) && !drawcursor); - - if (t3100e->video_options & 4) - bold = boldcols[attr] ? chr + 256 : chr; - else - bold = boldcols[attr] ? chr : chr + 256; - bold += 512 * (t3100e->video_options & 3); - - if (t3100e->cga.cgamode & 0x20) /* Blink */ - { - cols[1] = blinkcols[attr][1]; - cols[0] = blinkcols[attr][0]; - if (blink) cols[1] = cols[0]; - } - else - { - cols[1] = normcols[attr][1]; - cols[0] = normcols[attr][0]; - } - if (drawcursor) - { - for (c = 0; c < 8; c++) - { - ((uint32_t *)buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); - } - } - else - { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; - } - ++ma; - } -} - -/* Draw a row of text in 40-column mode */ -void t3100e_text_row40(t3100e_t *t3100e) -{ - uint32_t cols[2]; - int x, c; - uint8_t chr, attr; - int drawcursor; - int cursorline; - int bold; - int blink; - uint16_t addr; - uint8_t sc; - uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff; - uint16_t ca = (t3100e->cga.crtc[15] | (t3100e->cga.crtc[14] << 8)) & 0x7fff; - - sc = (t3100e->displine) & 15; - addr = ((ma & ~1) + (t3100e->displine >> 4) * 40) * 2; - ma += (t3100e->displine >> 4) * 40; - - if ((t3100e->cga.crtc[10] & 0x60) == 0x20) - { - cursorline = 0; - } - else - { - cursorline = ((t3100e->cga.crtc[10] & 0x0F)*2 <= sc) && - ((t3100e->cga.crtc[11] & 0x0F)*2 >= sc); - } - for (x = 0; x < 40; x++) - { - chr = t3100e->vram[(addr + 2 * x) & 0x7FFF]; - attr = t3100e->vram[(addr + 2 * x + 1) & 0x7FFF]; - drawcursor = ((ma == ca) && cursorline && - (t3100e->cga.cgamode & 8) && (t3100e->cga.cgablink & 16)); - - blink = ((t3100e->cga.cgablink & 16) && (t3100e->cga.cgamode & 0x20) && - (attr & 0x80) && !drawcursor); - - if (t3100e->video_options & 4) - bold = boldcols[attr] ? chr + 256 : chr; - else bold = boldcols[attr] ? chr : chr + 256; - bold += 512 * (t3100e->video_options & 3); - - if (t3100e->cga.cgamode & 0x20) /* Blink */ - { - cols[1] = blinkcols[attr][1]; - cols[0] = blinkcols[attr][0]; - if (blink) cols[1] = cols[0]; - } - else - { - cols[1] = normcols[attr][1]; - cols[0] = normcols[attr][0]; - } - if (drawcursor) - { - for (c = 0; c < 8; c++) - { - ((uint32_t *)buffer32->line[t3100e->displine])[(x << 4) + c*2] = - ((uint32_t *)buffer32->line[t3100e->displine])[(x << 4) + c*2 + 1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); - } - } - else - { - for (c = 0; c < 8; c++) - { - ((uint32_t *)buffer32->line[t3100e->displine])[(x << 4) + c*2] = - ((uint32_t *)buffer32->line[t3100e->displine])[(x << 4) + c*2+1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - ++ma; - } -} - - - - -/* Draw a line in CGA 640x200 or T3100e 640x400 mode */ -void t3100e_cgaline6(t3100e_t *t3100e) -{ - int x, c; - uint8_t dat; - uint32_t ink = 0; - uint16_t addr; - uint32_t fg = (t3100e->cga.cgacol & 0x0F) ? amber : black; - uint32_t bg = black; - - uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff; - - if (t3100e->cga.crtc[9] == 3) /* 640*400 */ - { - addr = ((t3100e->displine) & 1) * 0x2000 + - ((t3100e->displine >> 1) & 1) * 0x4000 + - (t3100e->displine >> 2) * 80 + - ((ma & ~1) << 1); - } - else - { - addr = ((t3100e->displine >> 1) & 1) * 0x2000 + - (t3100e->displine >> 2) * 80 + - ((ma & ~1) << 1); - } - for (x = 0; x < 80; x++) - { - dat = t3100e->vram[addr & 0x7FFF]; - addr++; - - for (c = 0; c < 8; c++) - { - ink = (dat & 0x80) ? fg : bg; - if (!(t3100e->cga.cgamode & 8)) ink = black; - ((uint32_t *)buffer32->line[t3100e->displine])[x*8+c] = ink; - dat = dat << 1; - } - } -} - - -/* 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 */ -void t3100e_cgaline4(t3100e_t *t3100e) -{ - int x, c; - uint8_t dat, pattern; - uint32_t ink0 = 0, ink1 = 0; - uint16_t addr; - - uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff; - if (t3100e->cga.crtc[9] == 3) /* 320*400 undocumented */ - { - addr = ((t3100e->displine) & 1) * 0x2000 + - ((t3100e->displine >> 1) & 1) * 0x4000 + - (t3100e->displine >> 2) * 80 + - ((ma & ~1) << 1); - } - else /* 320*200 */ - { - addr = ((t3100e->displine >> 1) & 1) * 0x2000 + - (t3100e->displine >> 2) * 80 + - ((ma & ~1) << 1); - } - for (x = 0; x < 80; x++) - { - dat = t3100e->vram[addr & 0x7FFF]; - addr++; - - for (c = 0; c < 4; c++) - { - pattern = (dat & 0xC0) >> 6; - if (!(t3100e->cga.cgamode & 8)) pattern = 0; - - switch (pattern & 3) - { - case 0: ink0 = ink1 = black; break; - case 1: if (t3100e->displine & 1) - { - ink0 = black; ink1 = black; - } - else - { - ink0 = amber; ink1 = black; - } - break; - case 2: if (t3100e->displine & 1) - { - ink0 = black; ink1 = amber; - } - else - { - ink0 = amber; ink1 = black; - } - break; - case 3: ink0 = ink1 = amber; break; - - } - ((uint32_t *)buffer32->line[t3100e->displine])[x*8+2*c] = ink0; - ((uint32_t *)buffer32->line[t3100e->displine])[x*8+2*c+1] = ink1; - dat = dat << 2; - } - } -} - - - - - - -void t3100e_poll(void *p) -{ - t3100e_t *t3100e = (t3100e_t *)p; - - if (t3100e->video_options != st_video_options) - { - t3100e->video_options = st_video_options; - - if (t3100e->video_options & 8) /* Disable internal CGA */ - mem_mapping_disable(&t3100e->mapping); - else mem_mapping_enable(&t3100e->mapping); - - /* Set the font used for the external display */ - t3100e->cga.fontbase = (512 * (t3100e->video_options & 3)) - + ((t3100e->video_options & 4) ? 256 : 0); - - } - /* Switch between internal plasma and external CRT display. */ - if (st_display_internal != -1 && st_display_internal != t3100e->internal) - { - t3100e->internal = st_display_internal; - t3100e_recalctimings(t3100e); - } - if (!t3100e->internal) - { - cga_poll(&t3100e->cga); - return; - } - - - if (!t3100e->linepos) - { - t3100e->cga.vidtime += t3100e->dispofftime; - t3100e->cga.cgastat |= 1; - t3100e->linepos = 1; - if (t3100e->dispon) - { - if (t3100e->displine == 0) - { - video_wait_for_buffer(); - } - - /* Graphics */ - if (t3100e->cga.cgamode & 0x02) - { - if (t3100e->cga.cgamode & 0x10) - t3100e_cgaline6(t3100e); - else t3100e_cgaline4(t3100e); - } - else - if (t3100e->cga.cgamode & 0x01) /* High-res text */ - { - t3100e_text_row80(t3100e); - } - else - { - t3100e_text_row40(t3100e); - } - } - t3100e->displine++; - /* Hardcode a fixed refresh rate and VSYNC timing */ - if (t3100e->displine == 400) /* Start of VSYNC */ - { - t3100e->cga.cgastat |= 8; - t3100e->dispon = 0; - } - if (t3100e->displine == 416) /* End of VSYNC */ - { - t3100e->displine = 0; - t3100e->cga.cgastat &= ~8; - t3100e->dispon = 1; - } - } - else - { - if (t3100e->dispon) - { - t3100e->cga.cgastat &= ~1; - } - t3100e->cga.vidtime += t3100e->dispontime; - t3100e->linepos = 0; - - if (t3100e->displine == 400) - { -/* Hardcode 640x400 window size */ - if (T3100E_XSIZE != xsize || T3100E_YSIZE != ysize) - { - xsize = T3100E_XSIZE; - ysize = T3100E_YSIZE; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize); - } - video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); - - frames++; - /* Fixed 640x400 resolution */ - video_res_x = T3100E_XSIZE; - video_res_y = T3100E_YSIZE; - - if (t3100e->cga.cgamode & 0x02) - { - if (t3100e->cga.cgamode & 0x10) - video_bpp = 1; - else video_bpp = 2; - - } - else video_bpp = 0; - t3100e->cga.cgablink++; - } - } -} - - - -void t3100e_recalcattrs(t3100e_t *t3100e) -{ - int n; - - /* val behaves as follows: - * Bit 0: Attributes 01-06, 08-0E are inverse video - * Bit 1: Attributes 01-06, 08-0E are bold - * Bit 2: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF - * are inverse video - * Bit 3: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF - * are bold */ - - /* Set up colours */ - amber = makecol(0xf7, 0x7C, 0x34); - black = makecol(0x17, 0x0C, 0x00); - - /* Initialise the attribute mapping. Start by defaulting everything - * to black on amber, and with bold set by bit 3 */ - for (n = 0; n < 256; n++) - { - boldcols[n] = (n & 8) != 0; - blinkcols[n][0] = normcols[n][0] = amber; - blinkcols[n][1] = normcols[n][1] = black; - } - - /* Colours 0x11-0xFF are controlled by bits 2 and 3 of the - * passed value. Exclude x0 and x8, which are always black on - * amber. */ - for (n = 0x11; n <= 0xFF; n++) - { - if ((n & 7) == 0) continue; - if (t3100e->attrmap & 4) /* Inverse */ - { - blinkcols[n][0] = normcols[n][0] = amber; - blinkcols[n][1] = normcols[n][1] = black; - } - else /* Normal */ - { - blinkcols[n][0] = normcols[n][0] = black; - blinkcols[n][1] = normcols[n][1] = amber; - } - if (t3100e->attrmap & 8) boldcols[n] = 1; /* Bold */ - } - /* Set up the 01-0E range, controlled by bits 0 and 1 of the - * passed value. When blinking is enabled this also affects 81-8E. */ - for (n = 0x01; n <= 0x0E; n++) - { - if (n == 7) continue; - if (t3100e->attrmap & 1) - { - blinkcols[n][0] = normcols[n][0] = amber; - blinkcols[n][1] = normcols[n][1] = black; - blinkcols[n+128][0] = amber; - blinkcols[n+128][1] = black; - } - else - { - blinkcols[n][0] = normcols[n][0] = black; - blinkcols[n][1] = normcols[n][1] = amber; - blinkcols[n+128][0] = black; - blinkcols[n+128][1] = amber; - } - if (t3100e->attrmap & 2) boldcols[n] = 1; - } - /* Colours 07 and 0F are always amber on black. If blinking is - * enabled so are 87 and 8F. */ - for (n = 0x07; n <= 0x0F; n += 8) - { - blinkcols[n][0] = normcols[n][0] = black; - blinkcols[n][1] = normcols[n][1] = amber; - blinkcols[n+128][0] = black; - blinkcols[n+128][1] = amber; - } - /* When not blinking, colours 81-8F are always amber on black. */ - for (n = 0x81; n <= 0x8F; n ++) - { - normcols[n][0] = black; - normcols[n][1] = amber; - boldcols[n] = (n & 0x08) != 0; - } - - - /* Finally do the ones which are solid black. These differ between - * the normal and blinking mappings */ - for (n = 0; n <= 0xFF; n += 0x11) - { - normcols[n][0] = normcols[n][1] = black; - } - /* In the blinking range, 00 11 22 .. 77 and 80 91 A2 .. F7 are black */ - for (n = 0; n <= 0x77; n += 0x11) - { - blinkcols[n][0] = blinkcols[n][1] = black; - blinkcols[n+128][0] = blinkcols[n+128][1] = black; - } -} - - -void *t3100e_init(device_t *info) -{ - t3100e_t *t3100e = malloc(sizeof(t3100e_t)); - memset(t3100e, 0, sizeof(t3100e_t)); - cga_init(&t3100e->cga); - - t3100e->internal = 1; - - /* 32k video RAM */ - t3100e->vram = malloc(0x8000); - - timer_add(t3100e_poll, &t3100e->cga.vidtime, TIMER_ALWAYS_ENABLED, t3100e); - - /* Occupy memory between 0xB8000 and 0xBFFFF */ - mem_mapping_add(&t3100e->mapping, 0xb8000, 0x8000, t3100e_read, NULL, NULL, t3100e_write, NULL, NULL, NULL, 0, t3100e); - /* Respond to CGA I/O ports */ - io_sethandler(0x03d0, 0x000c, t3100e_in, NULL, NULL, t3100e_out, NULL, NULL, t3100e); - - /* Default attribute mapping is 4 */ - t3100e->attrmap = 4; - t3100e_recalcattrs(t3100e); - -/* Start off in 80x25 text mode */ - t3100e->cga.cgastat = 0xF4; - t3100e->cga.vram = t3100e->vram; - t3100e->enabled = 1; - t3100e->video_options = 0xFF; - return t3100e; -} - -void t3100e_close(void *p) -{ - t3100e_t *t3100e = (t3100e_t *)p; - - free(t3100e->vram); - free(t3100e); -} - -void t3100e_speed_changed(void *p) -{ - t3100e_t *t3100e = (t3100e_t *)p; - - t3100e_recalctimings(t3100e); -} - -device_t t3100e_device = -{ - "Toshiba T3100e", - 0, - 0, - t3100e_init, - t3100e_close, - NULL, - NULL, - t3100e_speed_changed, - NULL, - NULL -}; diff --git a/src/video/vid_t3100e.h b/src/video/vid_t3100e.h deleted file mode 100644 index ba0f4aa00..000000000 --- a/src/video/vid_t3100e.h +++ /dev/null @@ -1,4 +0,0 @@ -extern device_t t3100e_device; - -void t3100e_video_options_set(uint8_t options); -void t3100e_display_set(uint8_t internal); diff --git a/src/video/vid_table.c b/src/video/vid_table.c index d52c6d963..38337d5fe 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -76,14 +76,14 @@ 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; } VIDEO_CARD; -static VIDEO_CARD +static const VIDEO_CARD video_cards[] = { { "None", "none", NULL, GFX_NONE }, { "Internal", "internal", NULL, GFX_INTERNAL, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, @@ -222,7 +222,7 @@ video_card_getname(int card) } -device_t * +const device_t * video_card_getdevice(int card) { return(video_cards[card].device); diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 9e5113c7b..bd1846c2c 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -47,7 +47,7 @@ * access size or host data has any affect, but the Windows 3.1 * driver always reads bytes and write words of 0xffff. * - * Version: @(#)vid_tgui9440.c 1.0.4 2018/02/12 + * Version: @(#)vid_tgui9440.c 1.0.5 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -771,7 +771,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)); @@ -809,12 +809,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/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/tgui9440/9440.vbi", TGUI_9440); } @@ -1745,7 +1745,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", @@ -1772,7 +1772,7 @@ static device_config_t tgui9440_config[] = } }; -device_t tgui9400cxi_device = +const device_t tgui9400cxi_device = { "Trident TGUI 9400CXi", DEVICE_VLB, @@ -1787,7 +1787,7 @@ device_t tgui9400cxi_device = tgui9440_config }; -device_t tgui9440_vlb_device = +const device_t tgui9440_vlb_device = { "Trident TGUI 9440 VLB", DEVICE_VLB, @@ -1802,7 +1802,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 bb5c1d439..24208e913 100644 --- a/src/video/vid_tgui9440.h +++ b/src/video/vid_tgui9440.h @@ -1,6 +1,6 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -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; diff --git a/src/video/vid_ti_cf62011.c b/src/video/vid_ti_cf62011.c index 2dc036ce3..cbf3c48b7 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.3 2018/01/21 + * Version: @(#)vid_ti_cf62011.c 1.0.4 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -239,7 +239,7 @@ vid_close(void *priv) static void * -vid_init(device_t *info) +vid_init(const device_t *info) { tivga_t *ti; @@ -271,7 +271,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, @@ -296,7 +296,7 @@ static device_config_t vid_config[] = }; -device_t ti_cf62011_device = { +const device_t ti_cf62011_device = { "TI CF62011 SVGA", 0, 0, @@ -310,7 +310,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 aa82bca5e..185f98511 100644 --- a/src/video/vid_ti_cf62011.h +++ b/src/video/vid_ti_cf62011.h @@ -1,4 +1,4 @@ #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; diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index abc00de10..d5865e013 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.4 2018/02/26 + * Version: @(#)vid_tvga.c 1.0.5 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -292,7 +292,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)); @@ -348,7 +348,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, @@ -373,7 +373,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 2851b9c59..43e1b778b 100644 --- a/src/video/vid_tvga.h +++ b/src/video/vid_tvga.h @@ -1,4 +1,4 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -extern device_t tvga8900d_device; +extern const device_t tvga8900d_device; diff --git a/src/video/vid_vga.c b/src/video/vid_vga.c index 233ab0755..2311f5a00 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.3 2018/02/03 + * Version: @(#)vid_vga.c 1.0.4 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -97,7 +97,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)); @@ -120,7 +120,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)); @@ -147,7 +147,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)); @@ -201,7 +201,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, @@ -215,7 +215,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, @@ -229,7 +229,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 5ee66fc0b..44fa836fb 100644 --- a/src/video/vid_vga.h +++ b/src/video/vid_vga.h @@ -1,6 +1,8 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -extern device_t vga_device; -extern device_t trigem_unk_device; -extern device_t ps1vga_device; +extern const device_t vga_device; +#ifdef DEV_BRANCH +extern const device_t trigem_unk_device; +#endif +extern const device_t ps1vga_device; diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index e3c170614..608708bd1 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -8,12 +8,12 @@ * * Emulation of the 3DFX Voodoo Graphics controller. * - * Version: @(#)vid_voodoo.c 1.0.11 2017/12/28 + * Version: @(#)vid_voodoo.c 1.0.12 2018/03/18 * * Authors: Sarah Walker, * leilei * - * Copyright 2008-2017 Sarah Walker. + * Copyright 2008-2018 Sarah Walker. */ #include #include @@ -7841,7 +7841,7 @@ void voodoo_close(void *p) free(voodoo_set); } -static device_config_t voodoo_config[] = +static const device_config_t voodoo_config[] = { { .name = "type", @@ -7958,7 +7958,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 047978327..9752899f7 100644 --- a/src/video/vid_voodoo.h +++ b/src/video/vid_voodoo.h @@ -1 +1 @@ -extern device_t voodoo_device; +extern const device_t voodoo_device; diff --git a/src/video/vid_wy700.c b/src/video/vid_wy700.c index e0cac8edc..0f93813e8 100644 --- a/src/video/vid_wy700.c +++ b/src/video/vid_wy700.c @@ -8,13 +8,13 @@ * * Wyse-700 emulation. * - * Version: @(#)vid_wy700.c 1.0.6 2017/11/04 + * Version: @(#)vid_wy700.c 1.0.7 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -897,7 +897,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)); @@ -1005,7 +1005,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 71d5063e4..0c8a986fe 100644 --- a/src/video/vid_wy700.h +++ b/src/video/vid_wy700.h @@ -1 +1 @@ -extern device_t wy700_device; +extern const device_t wy700_device; diff --git a/src/video/video.c b/src/video/video.c index 728b9799d..c41a52db9 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.19 2018/03/15 + * Version: @(#)video.c 1.0.20 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, diff --git a/src/video/video.h b/src/video/video.h index 1813e8115..313a06d9d 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.23 2018/03/15 + * Version: @(#)video.h 1.0.24 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -214,7 +214,7 @@ extern void (*video_recalctimings)(void); extern int video_card_available(int card); 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); diff --git a/src/win/win.h b/src/win/win.h index 88a03887a..c909b0829 100644 --- a/src/win/win.h +++ b/src/win/win.h @@ -8,7 +8,7 @@ * * Platform support defintions for Win32. * - * Version: @(#)win.h 1.0.14 2018/01/21 + * Version: @(#)win.h 1.0.15 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -94,7 +94,7 @@ extern void win_mouse_close(void); extern intptr_t fdd_type_to_icon(int type); #ifdef EMU_DEVICE_H -extern uint8_t deviceconfig_open(HWND hwnd, device_t *device); +extern uint8_t deviceconfig_open(HWND hwnd, const device_t *device); #endif extern uint8_t joystickconfig_open(HWND hwnd, int joy_nr, int type); diff --git a/src/win/win_devconf.c b/src/win/win_devconf.c index 72c4f7f9a..d738ab39e 100644 --- a/src/win/win_devconf.c +++ b/src/win/win_devconf.c @@ -8,7 +8,7 @@ * * Windows device configuration dialog implementation. * - * Version: @(#)win_devconf.c 1.0.15 2018/02/25 + * Version: @(#)win_devconf.c 1.0.16 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, @@ -30,7 +30,7 @@ #include -static device_t *config_device; +static const device_t *config_device; static uint8_t deviceconfig_changed = 0; @@ -47,10 +47,10 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) int val_int; int id; int c; - int num; + int num; int changed; - int cid; - device_config_t *config; + int cid; + const device_config_t *config; char s[80]; wchar_t ws[512]; LPTSTR lptsTemp; @@ -66,7 +66,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) @@ -183,7 +183,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) @@ -295,7 +295,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) @@ -375,7 +375,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) { @@ -455,9 +455,9 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) return FALSE; } -uint8_t deviceconfig_open(HWND hwnd, device_t *device) +uint8_t deviceconfig_open(HWND hwnd, const 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_joystick.cpp b/src/win/win_joystick.cpp index 2f14c8169..1cf4e6d13 100644 --- a/src/win/win_joystick.cpp +++ b/src/win/win_joystick.cpp @@ -8,13 +8,13 @@ * * Joystick interface to host device. * - * Version: @(#)win_joystick.cpp 1.0.7 2017/12/15 + * Version: @(#)win_joystick.cpp 1.0.8 2018/03/18 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #define DIRECTINPUT_VERSION 0x0800 #include @@ -25,7 +25,6 @@ #include "../device.h" #include "../plat.h" #include "../game/gameport.h" -#include "../plat_joystick.h" #include "win.h" diff --git a/src/win/win_jsconf.c b/src/win/win_jsconf.c index fe97c5b6c..39a02740b 100644 --- a/src/win/win_jsconf.c +++ b/src/win/win_jsconf.c @@ -12,7 +12,6 @@ #include "../device.h" #include "../game/gameport.h" #include "../plat.h" -#include "../plat_joystick.h" #include "win.h" diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 27359b286..ce9455061 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.43 2018/03/10 + * Version: @(#)win_settings.c 1.0.44 2018/03/18 * * Author: Miran Grca, * @@ -173,7 +173,7 @@ static void win_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); + strcpy(temp_pcap_dev, network_host); temp_net_card = network_card; /* Ports category */ @@ -289,7 +289,7 @@ static int win_settings_changed(void) /* Network category */ i = i || (network_type != temp_net_type); - i = i || strcmp(temp_pcap_dev, network_pcap); + i = i || strcmp(temp_pcap_dev, network_host); i = i || (network_card != temp_net_card); /* Ports category */ @@ -392,8 +392,8 @@ static void win_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_pcap_dev); network_card = temp_net_card; /* Ports category */ @@ -436,28 +436,7 @@ static void win_settings_save(void) /* Mark configuration as changed. */ config_changed = 1; -#if 1 pc_reset_hard_init(); -#else - mem_resize(); - rom_load_bios(romset); - - ui_sb_update_panes(); - - sound_realloc_buffers(); - - pc_reset_hard_init(); - - cpu_set(); - - cpu_update_waitstates(); - - config_save(); - - pc_speed_changed(); - - if (joystick_type != 7) gameport_update_joystick_type(); -#endif } @@ -980,7 +959,7 @@ win_settings_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); @@ -1184,7 +1163,7 @@ win_settings_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; char *s; switch (message) @@ -1256,8 +1235,6 @@ win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (midi_device_available(c)) { - /* midi_dev = midi_device_getdevice(c); */ - if (c == 0) { SendMessage(h, CB_ADDSTRING, 0, (LPARAM)plat_get_string(IDS_2152)); @@ -1606,7 +1583,7 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa int c = 0; int d = 0; LPTSTR lptsTemp; - device_t *scsi_dev; + const device_t *scsi_dev; switch (message) { From ced9cd54095798da94fb652cc2abb8f653337243 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Mar 2018 01:04:32 +0100 Subject: [PATCH 10/39] Committed the LZF files. --- src/floppy/lzf/Changes | 136 + src/floppy/lzf/LICENSE | 27 + src/floppy/lzf/Makefile.in | 66 + src/floppy/lzf/README | 29 + src/floppy/lzf/config.h | 16 + src/floppy/lzf/configure | 7871 +++++++++++++++++++++++++++++++++++ src/floppy/lzf/configure.ac | 25 + src/floppy/lzf/crc32.h | 65 + src/floppy/lzf/install-sh | 251 ++ src/floppy/lzf/lzf.c | 537 +++ src/floppy/lzf/lzf.h | 100 + src/floppy/lzf/lzfP.h | 185 + src/floppy/lzf/lzf_c.c | 293 ++ src/floppy/lzf/lzf_d.c | 185 + 14 files changed, 9786 insertions(+) create mode 100644 src/floppy/lzf/Changes create mode 100644 src/floppy/lzf/LICENSE create mode 100644 src/floppy/lzf/Makefile.in create mode 100644 src/floppy/lzf/README create mode 100644 src/floppy/lzf/config.h create mode 100644 src/floppy/lzf/configure create mode 100644 src/floppy/lzf/configure.ac create mode 100644 src/floppy/lzf/crc32.h create mode 100644 src/floppy/lzf/install-sh create mode 100644 src/floppy/lzf/lzf.c create mode 100644 src/floppy/lzf/lzf.h create mode 100644 src/floppy/lzf/lzfP.h create mode 100644 src/floppy/lzf/lzf_c.c create mode 100644 src/floppy/lzf/lzf_d.c diff --git a/src/floppy/lzf/Changes b/src/floppy/lzf/Changes new file mode 100644 index 000000000..93bd4cb6d --- /dev/null +++ b/src/floppy/lzf/Changes @@ -0,0 +1,136 @@ +3.6 Mon Feb 7 17:37:31 CET 2011 + - fixed hash calculation in C♯ version (Tiago Freitas Leal). + - unroll copy for small sizes, use memcpy for larger sizes, + greatly speeding up decompression in most cases. + - finally disable rep movsb - it's a big loss on modern intel cpus, + and only a small win on amd cpus. + - improve C++ compatibility of the code. + - slightly improve compressor speed. + - halved memory requirements for compressor on 64 bit architectures, + which can improve the speed quite a bit on older cpus. + +3.5 Fri May 1 02:28:42 CEST 2009 + - lzf_compress did sometimes write one octet past the given output + buffer (analyzed and nice testcase by Salvatore Sanfilippo). + +3.4 Tue Sep 2 06:45:00 CEST 2008 + - the fix from 3.3 introduced a compression bug, which is fixed in + this release (which explains the mysterious prerelease...). Thanks + once more to Clément Calmels. + +3.3 Mon Aug 25 03:17:42 CEST 2008 + - lzf_compress could access memory after the given input buffer + when outputting back references. reported with nice testcase + by Clément Calmels. + +3.2 Fri May 9 18:52:23 CEST 2008 + - include a workaround for failing POSIX and real-world compliance + on 64 bit windows (microsoft claims to support POSIX, but is far + from it). (bug found and analysed nicely by John Lilley). + +3.1 Fri Nov 30 11:33:04 CET 2007 + - IMPORTANT BUGFIX: a too long final literal run would corrupt data + in the encoder (this was introduced in 3.0 only, earlier versions + are safe). + +3.0 Tue Nov 13 22:13:09 CET 2007 + - switched to 2-clause bsd with "GPL v2 or any later version" option. + - speed up compression by ~10-15% in common cases + by some manual unrolling. + - import some compiler tricks from JSON::XS, for further speed-ups. + - tune hash functions depending on ULTRA_FAST or VERY_FAST settings. + - for typical binary data (e.g. /bin/bash, memory dumps, + canterbury corpus etc.), speed is now comparable to fastlz, but + with better compression ratio. with ULTRA_FAST, it's typically + 3-15% faster than fastlz while still maintaining a similar ratio. + (amd64 and core 2 duo, ymmv). thanks a lot for the competition :) + - undo inline assembly in compressor, it is no longer helpful. + - no changes to the decompressor. + - use a HLOG of 16 by default now (formerly 15). + +2.1 Fri Nov 2 13:34:42 CET 2007 + - switched to a 2-clause bsd license with GPL exception. + - get rid of memcpy. + - tentatively use rep movsb on x86 and x86_64 (gcc only) for a + moderate speed improvement. + - applied patch by Kein-Hong Man to maske lzf.c compile under + the crippled mingw32 environment. + +2.0 Fri Feb 16 23:11:18 CET 2007 + - replaced lzf demo by industrial-strength lzf utility with behaviour + similar other compression utilities. Thanks for Stefan Traby for + rewriting it! + - fix state arg prototype. + +1.7 Wed Sep 27 17:29:15 CEST 2006 + - remove bogus "unlzf" patch. + note to self: never accept well-meant patches. + - make lzf more robust in presence of padding bytes or sudden eof. + +1.6 Fri Jul 7 17:31:26 CEST 2006 + - the lzf example utility will now uncompress if invoked + as "unlzf" (patch by Scott Feeney). + - add CHECK_INPUT option that adds more checks for input + data validity. + - help applications that do not pass in the correct length + (such as php) by returning either EINVAL or E2BIG. + - default HLOG size is now 15 (cpu caches have increased). + - documentation fixes. + +1.51 Thu Apr 14 22:15:46 CEST 2005 + - incorporated C♯ implementation of both the en- and decoder, + written by "Oren J. Maurice". + You can find it in the cs/ subdirectory. + - make FRST, NEXT IDX overridable if lzf_c.c is directly included + in the code. + +1.5 Tue Mar 8 20:23:23 CET 2005 + - incorporated improvements by Adam D. Moss, + which includes a new VERY_FAST mode which is + a bit slower than ULTRA_FAST but much better, + and enabled it as default. + +1.401 Thu Mar 3 18:00:52 CET 2005 + - use cstring in c++, not string.h. + - change of contact address. + +1.4 Wed Dec 15 08:08:49 CET 2004 + - very very slight tuning of the hashing function. + +1.3 Thu Mar 25 15:41:17 CET 2004 + - changed license of lzf core code to explicitly allow + relicensing under the GPLv2. + - added VPATH support as suggested by Björn Eriksson. + +1.2 Mon Dec 29 13:47:28 CET 2003 + - avoid spurious memory accesses after the to-be-compressed + memory region. originally reported by Michal Zalewski. + - flip LZF_STACK_ARG meaning (to be correct). + +1.1 Tue Dec 23 05:48:32 CET 2003 + - removed #warn directive, it's not worth the hassle. + - add LZF_STACK_ARG and AVOID_ERRNO configurations + for embedded systems. + - make it compile cleanly as c++. + - some small documentation and code fixes. + +1.0 Sun Nov 17 12:37:37 CET 2002 + - slightly better compression ratio, almost unmeasurably + slower. + - some documentation fixes. + +0.4 Thu Jun 13 14:11:10 CEST 2002 + - typoe fix. + - lzf demo program now properly decompresses small files. + - fix another 64 bit issue, found by Laurent Deniel. + +0.3 Tue Jan 16 13:21:14 CET 2001 + - fix silly beginners 32/64 bit mistake. + +0.2 Thu Jan 4 05:56:42 CET 2001 + - now totally independent of autoconfig, for + easy inclusion into other programs. + - much better fine-tuning, faster and better than 0.1. + +0.1 2000 + - initial release. diff --git a/src/floppy/lzf/LICENSE b/src/floppy/lzf/LICENSE new file mode 100644 index 000000000..ee54ff717 --- /dev/null +++ b/src/floppy/lzf/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2000-2009 Marc Alexander Lehmann + +Redistribution and use in source and binary forms, with or without modifica- +tion, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- +CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- +CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- +ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. + +Alternatively, the following files carry an additional notice that +explicitly allows relicensing under the GPLv2: lzf.c lzf.h lzfP.h lzf_c.c +lzf_d.c + diff --git a/src/floppy/lzf/Makefile.in b/src/floppy/lzf/Makefile.in new file mode 100644 index 000000000..3c87d62de --- /dev/null +++ b/src/floppy/lzf/Makefile.in @@ -0,0 +1,66 @@ +VERSION = 3.6 + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@ +bindir = @bindir@ +includedir = @includedir@ + +VPATH = @srcdir@ + +CC = @CC@ +CPPFLAGS = -I. @CPPFLAGS@ +CFLAGS = @CFLAGS@ +LDFLAGS = @LDFLAGS@ +RANLIB = @RANLIB@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +all: Makefile lzf + +clean: + -rm -f *.o *.a lzf bench + +lzf_c.o: lzf_c.c lzfP.h + +lzf_d.o: lzf_d.c lzfP.h + +lzf.o: lzf.c + +lzf: lzf.o liblzf.a + +lzfP.h: lzf.h config.h + +liblzf.a: lzf_c.o lzf_d.o + rm -f $@ + $(AR) rc $@ $^ + $(RANLIB) $@ + +install: all + $(INSTALL) -d $(bindir) + $(INSTALL) -m 755 lzf $(bindir) + $(INSTALL) -d $(includedir) + $(INSTALL_DATA) lzf.h $(includedir) + $(INSTALL) -d $(libdir) + $(INSTALL_DATA) liblzf.a $(libdir) + +dist: + mkdir liblzf-$(VERSION) + tar c LICENSE README Makefile.in config.h.in \ + configure configure.ac install-sh \ + cs/README cs/CLZF.cs \ + lzf.h lzfP.h lzf_c.c lzf_d.c \ + crc32.h lzf.c Changes \ + | tar xpC liblzf-$(VERSION) + -chown -R root.root liblzf-$(VERSION) + chmod -R u=rwX,go=rX liblzf-$(VERSION) + tar cvf - liblzf-$(VERSION) | gzip -9 >liblzf-$(VERSION).tar.gz + rm -rf liblzf-$(VERSION) + ls -l liblzf-$(VERSION).tar.gz + +Makefile: Makefile.in + ./config.status + +bench: Makefile liblzf.a bench.c + $(CC) $(CPPFLAGS) $(CFLAGS) -g -o bench bench.c -L. -llzf + diff --git a/src/floppy/lzf/README b/src/floppy/lzf/README new file mode 100644 index 000000000..0734ebe06 --- /dev/null +++ b/src/floppy/lzf/README @@ -0,0 +1,29 @@ +DESCRIPTION + LZF is an extremely fast (not that much slower than a pure memcpy) + compression algorithm. It is ideal for applications where you want to + save *some* space but not at the cost of speed. It is ideal for + repetitive data as well. The module is self-contained and very small. + + It's written in ISO-C with no external dependencies other than what + C provides and can easily be #include'd into your code, no makefile + changes or library builds requires. + + A C♯ implementation without external dependencies is available, too. + + I do not know for certain whether any patents in any countries apply + to this algorithm, but at the moment it is believed that it is free + from any patents. More importantly, it is also free to use in every + software package (see LICENSE). + + See the lzf.h file for details on how the functions in this + mini-library are to be used. + + NOTE: This package contains a very bare-bones command-line utility + which is neither optimized for speed nor for compression. This library + is really intended to be used inside larger programs. + +AUTHOR + This library was written by Marc Lehmann (See also + http://software.schmorp.de/pkg/liblzf). + + diff --git a/src/floppy/lzf/config.h b/src/floppy/lzf/config.h new file mode 100644 index 000000000..5fd69c6bd --- /dev/null +++ b/src/floppy/lzf/config.h @@ -0,0 +1,16 @@ +/* config.h.in. Generated automatically from configure.in by autoheader 2.13. */ + +/* Define to empty if the keyword does not work. */ +#undef const + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* The number of bytes in a int. */ +#undef SIZEOF_INT + +/* The number of bytes in a long. */ +#undef SIZEOF_LONG + +/* The number of bytes in a short. */ +#undef SIZEOF_SHORT diff --git a/src/floppy/lzf/configure b/src/floppy/lzf/configure new file mode 100644 index 000000000..7a3a2b25c --- /dev/null +++ b/src/floppy/lzf/configure @@ -0,0 +1,7871 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.60. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +# Find out whether ``test -x'' works. Don't use a zero-byte file, as +# systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + as_executable_p="test -x" +else + as_executable_p=: +fi +rm -f conf$$.file + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="lzfP.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#endif +#if HAVE_STDINT_H +# include +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +RANLIB +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +CPP +GREP +EGREP +LIBOBJS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-largefile omit support for large files + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.60 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.60. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +ac_config_headers="$ac_config_headers config.h" + + + +cat >>confdefs.h <<\_ACEOF +#define _GNU_SOURCE 1 +_ACEOF + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5 +echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6; } +if test "${ac_cv_sys_largefile_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sys_largefile_CC=' -n32'; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5 +echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6; } +if test "${ac_cv_sys_file_offset_bits+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + while :; do + ac_cv_sys_file_offset_bits=no + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sys_file_offset_bits=64; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + break +done +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5 +echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6; } +if test "$ac_cv_sys_file_offset_bits" != no; then + +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF + +fi +rm -f conftest* + { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5 +echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; } +if test "${ac_cv_sys_large_files+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + while :; do + ac_cv_sys_large_files=no + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sys_large_files=1; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + break +done +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5 +echo "${ECHO_T}$ac_cv_sys_large_files" >&6; } +if test "$ac_cv_sys_large_files" != no; then + +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF + +fi +rm -f conftest* +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_GREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_GREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_EGREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_EGREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ echo "$as_me:$LINENO: checking for short" >&5 +echo $ECHO_N "checking for short... $ECHO_C" >&6; } +if test "${ac_cv_type_short+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef short ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_short=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_short=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_short" >&5 +echo "${ECHO_T}$ac_cv_type_short" >&6; } + +{ echo "$as_me:$LINENO: checking size of short" >&5 +echo $ECHO_N "checking size of short... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_short+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_short" = yes; then + # The cast to long int works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo= ac_hi= +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_short=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (short) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (short) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef short ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_short=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (short) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (short) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +else + ac_cv_sizeof_short=0 +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5 +echo "${ECHO_T}$ac_cv_sizeof_short" >&6; } +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SHORT $ac_cv_sizeof_short +_ACEOF + + +{ echo "$as_me:$LINENO: checking for int" >&5 +echo $ECHO_N "checking for int... $ECHO_C" >&6; } +if test "${ac_cv_type_int+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef int ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_int=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_int=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 +echo "${ECHO_T}$ac_cv_type_int" >&6; } + +{ echo "$as_me:$LINENO: checking size of int" >&5 +echo $ECHO_N "checking size of int... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_int+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_int" = yes; then + # The cast to long int works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo= ac_hi= +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_int=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (int) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef int ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_int=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (int) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +else + ac_cv_sizeof_int=0 +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 +echo "${ECHO_T}$ac_cv_sizeof_int" >&6; } +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int +_ACEOF + + +{ echo "$as_me:$LINENO: checking for long" >&5 +echo $ECHO_N "checking for long... $ECHO_C" >&6; } +if test "${ac_cv_type_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef long ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_long=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_long=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 +echo "${ECHO_T}$ac_cv_type_long" >&6; } + +{ echo "$as_me:$LINENO: checking size of long" >&5 +echo $ECHO_N "checking size of long... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_long" = yes; then + # The cast to long int works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo= ac_hi= +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_long=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_long=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +else + ac_cv_sizeof_long=0 +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 +echo "${ECHO_T}$ac_cv_sizeof_long" >&6; } +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + + +{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset x; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *ccp; + char **p; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + ccp = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++ccp; + p = (char**) ccp; + ccp = (char const *const *) p; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !x[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_const=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6; } +if test "${ac_cv_c_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_inline=$ac_kw +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +echo "${ECHO_T}$ac_cv_c_inline" >&6; } + + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + + +for ac_header in getopt.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_func in getopt_long +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +if test "$GCC" = yes; then + CFLAGS="$CFLAGS -O3 -funroll-all-loops" +else + { echo "$as_me:$LINENO: result: no gcc" >&5 +echo "${ECHO_T}no gcc" >&6; } +fi + +ac_config_files="$ac_config_files Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +# Find out whether ``test -x'' works. Don't use a zero-byte file, as +# systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + as_executable_p="test -x" +else + as_executable_p=: +fi +rm -f conf$$.file + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.60. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.60, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +RANLIB!$RANLIB$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +CPP!$CPP$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 53; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then replace #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" + ;; + + + esac + +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/src/floppy/lzf/configure.ac b/src/floppy/lzf/configure.ac new file mode 100644 index 000000000..58316a01b --- /dev/null +++ b/src/floppy/lzf/configure.ac @@ -0,0 +1,25 @@ +AC_INIT +AC_CONFIG_SRCDIR([lzfP.h]) + +AC_CONFIG_HEADER(config.h) + +AC_GNU_SOURCE +AC_SYS_LARGEFILE +AC_PROG_CC +AC_PROG_RANLIB +AC_PROG_INSTALL +AC_HEADER_STDC + +AC_C_CONST +AC_C_INLINE +AC_CHECK_HEADERS(getopt.h) +AC_CHECK_FUNCS(getopt_long) + +if test "$GCC" = yes; then + CFLAGS="$CFLAGS -O3 -funroll-all-loops" +else + AC_MSG_RESULT(no gcc) +fi + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/src/floppy/lzf/crc32.h b/src/floppy/lzf/crc32.h new file mode 100644 index 000000000..cf8f6d409 --- /dev/null +++ b/src/floppy/lzf/crc32.h @@ -0,0 +1,65 @@ +#ifndef CRC32_H +#define CRC32_H + +/* crc32 0xdebb20e3 table and supplementary functions. */ + +static const u32 crc_32_tab[] = +{ + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dL +}; + +#define crc32(crc,byte) (crc_32_tab[(u8)(crc) ^ (u8)(byte)] ^ ((crc) >> 8)) + +#endif + diff --git a/src/floppy/lzf/install-sh b/src/floppy/lzf/install-sh new file mode 100644 index 000000000..e9de23842 --- /dev/null +++ b/src/floppy/lzf/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/src/floppy/lzf/lzf.c b/src/floppy/lzf/lzf.c new file mode 100644 index 000000000..bedfdb6fe --- /dev/null +++ b/src/floppy/lzf/lzf.c @@ -0,0 +1,537 @@ +/* + * Copyright (c) 2006 Stefan Traby + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lzf.h" + +#ifdef HAVE_GETOPT_H +# include +#endif + +#define BLOCKSIZE (1024 * 64 - 1) +#define MAX_BLOCKSIZE BLOCKSIZE + +typedef unsigned char u8; + +static off_t nr_read, nr_written; + +static const char *imagename; +static enum { compress, uncompress, lzcat } mode = compress; +static int verbose = 0; +static int force = 0; +static long blocksize = BLOCKSIZE; + +#ifdef HAVE_GETOPT_LONG + + struct option longopts[] = { + {"compress", 0, 0, 'c'}, + {"decompress", 0, 0, 'd'}, + {"uncompress", 0, 0, 'd'}, + {"force", 0, 0, 'f'}, + {"help", 0, 0, 'h'}, + {"verbose", 0, 0, 'v'}, + {"blocksize", 1, 0, 'b'}, + {0, 0, 0, 0} + }; + + static const char *opt = + "-c --compress compress\n" + "-d --decompress decompress\n" + "-f --force force overwrite of output file\n" + "-h --help give this help\n" "-v --verbose verbose mode\n" "-b # --blocksize # set blocksize\n" "\n"; + +#else + + static const char *opt = + "-c compress\n" + "-d decompress\n" + "-f force overwrite of output file\n" + "-h give this help\n" + "-v verbose mode\n" + "-b # set blocksize\n" + "\n"; + +#endif + +static void +usage (int rc) +{ + fprintf (stderr, "\n" + "lzf, a very lightweight compression/decompression utility written by Stefan Traby.\n" + "uses liblzf written by Marc Lehmann You can find more info at\n" + "http://liblzf.plan9.de/\n" + "\n" + "usage: lzf [-dufhvb] [file ...]\n" + " unlzf [file ...]\n" + " lzcat [file ...]\n" + "\n%s", + opt); + + exit (rc); +} + +static inline ssize_t +rread (int fd, void *buf, size_t len) +{ + ssize_t rc = 0, offset = 0; + char *p = buf; + + while (len && (rc = read (fd, &p[offset], len)) > 0) + { + offset += rc; + len -= rc; + } + + nr_read += offset; + + if (rc < 0) + return rc; + + return offset; +} + +/* returns 0 if all written else -1 */ +static inline ssize_t +wwrite (int fd, void *buf, size_t len) +{ + ssize_t rc; + char *b = buf; + size_t l = len; + + while (l) + { + rc = write (fd, b, l); + if (rc < 0) + { + fprintf (stderr, "%s: write error: ", imagename); + perror (""); + return -1; + } + + l -= rc; + b += rc; + } + + nr_written += len; + return 0; +} + +/* + * Anatomy: an lzf file consists of any number of blocks in the following format: + * + * \x00 EOF (optional) + * "ZV\0" 2-byte-usize + * "ZV\1" 2-byte-csize 2-byte-usize + * "ZV\2" 4-byte-crc32-0xdebb20e3 (NYI) + */ + + +#define TYPE0_HDR_SIZE 5 +#define TYPE1_HDR_SIZE 7 +#define MAX_HDR_SIZE 7 +#define MIN_HDR_SIZE 5 + +static int +compress_fd (int from, int to) +{ + ssize_t us, cs, len; + u8 buf1[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; + u8 buf2[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; + u8 *header; + + nr_read = nr_written = 0; + while ((us = rread (from, &buf1[MAX_HDR_SIZE], blocksize)) > 0) + { + cs = lzf_compress (&buf1[MAX_HDR_SIZE], us, &buf2[MAX_HDR_SIZE], us > 4 ? us - 4 : us); + if (cs) + { + header = &buf2[MAX_HDR_SIZE - TYPE1_HDR_SIZE]; + header[0] = 'Z'; + header[1] = 'V'; + header[2] = 1; + header[3] = cs >> 8; + header[4] = cs & 0xff; + header[5] = us >> 8; + header[6] = us & 0xff; + len = cs + TYPE1_HDR_SIZE; + } + else + { // write uncompressed + header = &buf1[MAX_HDR_SIZE - TYPE0_HDR_SIZE]; + header[0] = 'Z'; + header[1] = 'V'; + header[2] = 0; + header[3] = us >> 8; + header[4] = us & 0xff; + len = us + TYPE0_HDR_SIZE; + } + + if (wwrite (to, header, len) == -1) + return -1; + } + + return 0; +} + +static int +uncompress_fd (int from, int to) +{ + u8 header[MAX_HDR_SIZE]; + u8 buf1[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; + u8 buf2[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; + u8 *p; + int l, rd; + ssize_t rc, cs, us, bytes, over = 0; + + nr_read = nr_written = 0; + while (1) + { + rc = rread (from, header + over, MAX_HDR_SIZE - over); + if (rc < 0) + { + fprintf (stderr, "%s: read error: ", imagename); + perror (""); + return -1; + } + + rc += over; + over = 0; + if (!rc || header[0] == 0) + return 0; + + if (rc < MIN_HDR_SIZE || header[0] != 'Z' || header[1] != 'V') + { + fprintf (stderr, "%s: invalid data stream - magic not found or short header\n", imagename); + return -1; + } + + switch (header[2]) + { + case 0: + cs = -1; + us = (header[3] << 8) | header[4]; + p = &header[TYPE0_HDR_SIZE]; + break; + case 1: + if (rc < TYPE1_HDR_SIZE) + { + goto short_read; + } + cs = (header[3] << 8) | header[4]; + us = (header[5] << 8) | header[6]; + p = &header[TYPE1_HDR_SIZE]; + break; + default: + fprintf (stderr, "%s: unknown blocktype\n", imagename); + return -1; + } + + bytes = cs == -1 ? us : cs; + l = &header[rc] - p; + + if (l > 0) + memcpy (buf1, p, l); + + if (l > bytes) + { + over = l - bytes; + memmove (header, &p[bytes], over); + } + + p = &buf1[l]; + rd = bytes - l; + if (rd > 0) + if ((rc = rread (from, p, rd)) != rd) + goto short_read; + + if (cs == -1) + { + if (wwrite (to, buf1, us)) + return -1; + } + else + { + if (lzf_decompress (buf1, cs, buf2, us) != us) + { + fprintf (stderr, "%s: decompress: invalid stream - data corrupted\n", imagename); + return -1; + } + + if (wwrite (to, buf2, us)) + return -1; + } + } + + return 0; + +short_read: + fprintf (stderr, "%s: short data\n", imagename); + return -1; +} + +static int +open_out (const char *name) +{ + int fd; + int m = O_EXCL; + + if (force) + m = 0; + + fd = open (name, O_CREAT | O_WRONLY | O_TRUNC | m, 600); +#if defined(__MINGW32__) + _setmode(fd, _O_BINARY); +#endif + return fd; +} + +static int +compose_name (const char *fname, char *oname) +{ + char *p; + + if (mode == compress) + { + if (strlen (fname) > PATH_MAX - 4) + { + fprintf (stderr, "%s: %s.lzf: name too long", imagename, fname); + return -1; + } + + strcpy (oname, fname); + strcat (oname, ".lzf"); + } + else + { + if (strlen (fname) > PATH_MAX) + { + fprintf (stderr, "%s: %s: name too long\n", imagename, fname); + return -1; + } + + strcpy (oname, fname); + p = &oname[strlen (oname)] - 4; + if (p < oname || strcmp (p, ".lzf")) + { + fprintf (stderr, "%s: %s: unknown suffix\n", imagename, fname); + return -1; + } + + *p = 0; + } + + return 0; +} + +static int +run_file (const char *fname) +{ + int fd, fd2; + int rc; + struct stat mystat; + char oname[PATH_MAX + 1]; + + if (mode != lzcat) + if (compose_name (fname, oname)) + return -1; + +#if !defined(__MINGW32__) + rc = lstat (fname, &mystat); +#else + rc = stat (fname, &mystat); +#endif + fd = open (fname, O_RDONLY); +#if defined(__MINGW32__) + _setmode(fd, _O_BINARY); +#endif + if (rc || fd == -1) + { + fprintf (stderr, "%s: %s: ", imagename, fname); + perror (""); + return -1; + } + + if (!S_ISREG (mystat.st_mode)) + { + fprintf (stderr, "%s: %s: not a regular file.\n", imagename, fname); + close (fd); + return -1; + } + + if (mode == lzcat) + { + rc = uncompress_fd (fd, 1); + close (fd); + return rc; + } + + fd2 = open_out (oname); + if (fd2 == -1) + { + fprintf (stderr, "%s: %s: ", imagename, oname); + perror (""); + close (fd); + return -1; + } + + if (mode == compress) + { + rc = compress_fd (fd, fd2); + if (!rc && verbose) + fprintf (stderr, "%s: %5.1f%% -- replaced with %s\n", + fname, nr_read == 0 ? 0 : 100.0 - nr_written / ((double) nr_read / 100.0), oname); + } + else + { + rc = uncompress_fd (fd, fd2); + if (!rc && verbose) + fprintf (stderr, "%s: %5.1f%% -- replaced with %s\n", + fname, nr_written == 0 ? 0 : 100.0 - nr_read / ((double) nr_written / 100.0), oname); + } + +#if !defined(__MINGW32__) + fchmod (fd2, mystat.st_mode); +#else + chmod (oname, mystat.st_mode); +#endif + close (fd); + close (fd2); + + if (!rc) + unlink (fname); + + return rc; +} + +int +main (int argc, char *argv[]) +{ + char *p = argv[0]; + int optc; + int rc = 0; + + errno = 0; + p = getenv ("LZF_BLOCKSIZE"); + if (p) + { + blocksize = strtoul (p, 0, 0); + if (errno || !blocksize || blocksize > MAX_BLOCKSIZE) + blocksize = BLOCKSIZE; + } + + p = strrchr (argv[0], '/'); + imagename = p ? ++p : argv[0]; + + if (!strncmp (imagename, "un", 2) || !strncmp (imagename, "de", 2)) + mode = uncompress; + + if (strstr (imagename, "cat")) + mode = lzcat; + +#ifdef HAVE_GETOPT_LONG + while ((optc = getopt_long (argc, argv, "cdfhvb:", longopts, 0)) != -1) +#else + while ((optc = getopt (argc, argv, "cdfhvb:")) != -1) +#endif + { + switch (optc) + { + case 'c': + mode = compress; + break; + case 'd': + mode = uncompress; + break; + case 'f': + force = 1; + break; + case 'h': + usage (0); + break; + case 'v': + verbose = 1; + break; + case 'b': + errno = 0; + blocksize = strtoul (optarg, 0, 0); + if (errno || !blocksize || blocksize > MAX_BLOCKSIZE) + blocksize = BLOCKSIZE; + break; + default: + usage (1); + break; + } + } + + if (optind == argc) + { // stdin stdout + if (!force) + { + if ((mode == uncompress || mode == lzcat) && isatty (0)) + { + fprintf (stderr, "%s: compressed data not read from a terminal. Use -f to force decompression.\n", imagename); + exit (1); + } + if (mode == compress && isatty (1)) + { + fprintf (stderr, "%s: compressed data not written to a terminal. Use -f to force compression.\n", imagename); + exit (1); + } + } + + if (mode == compress) + rc = compress_fd (0, 1); + else + rc = uncompress_fd (0, 1); + + exit (rc ? 1 : 0); + } + + while (optind < argc) + rc |= run_file (argv[optind++]); + + exit (rc ? 1 : 0); +} + diff --git a/src/floppy/lzf/lzf.h b/src/floppy/lzf/lzf.h new file mode 100644 index 000000000..919b6e6be --- /dev/null +++ b/src/floppy/lzf/lzf.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2000-2008 Marc Alexander Lehmann + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +#ifndef LZF_H +#define LZF_H + +/*********************************************************************** +** +** lzf -- an extremely fast/free compression/decompression-method +** http://liblzf.plan9.de/ +** +** This algorithm is believed to be patent-free. +** +***********************************************************************/ + +#define LZF_VERSION 0x0105 /* 1.5, API version */ + +/* + * Compress in_len bytes stored at the memory block starting at + * in_data and write the result to out_data, up to a maximum length + * of out_len bytes. + * + * If the output buffer is not large enough or any error occurs return 0, + * otherwise return the number of bytes used, which might be considerably + * more than in_len (but less than 104% of the original size), so it + * makes sense to always use out_len == in_len - 1), to ensure _some_ + * compression, and store the data uncompressed otherwise (with a flag, of + * course. + * + * lzf_compress might use different algorithms on different systems and + * even different runs, thus might result in different compressed strings + * depending on the phase of the moon or similar factors. However, all + * these strings are architecture-independent and will result in the + * original data when decompressed using lzf_decompress. + * + * The buffers must not be overlapping. + * + * If the option LZF_STATE_ARG is enabled, an extra argument must be + * supplied which is not reflected in this header file. Refer to lzfP.h + * and lzf_c.c. + * + */ +unsigned int +lzf_compress (const void *const in_data, unsigned int in_len, + void *out_data, unsigned int out_len); + +/* + * Decompress data compressed with some version of the lzf_compress + * function and stored at location in_data and length in_len. The result + * will be stored at out_data up to a maximum of out_len characters. + * + * If the output buffer is not large enough to hold the decompressed + * data, a 0 is returned and errno is set to E2BIG. Otherwise the number + * of decompressed bytes (i.e. the original length of the data) is + * returned. + * + * If an error in the compressed data is detected, a zero is returned and + * errno is set to EINVAL. + * + * This function is very fast, about as fast as a copying loop. + */ +unsigned int +lzf_decompress (const void *const in_data, unsigned int in_len, + void *out_data, unsigned int out_len); + +#endif + diff --git a/src/floppy/lzf/lzfP.h b/src/floppy/lzf/lzfP.h new file mode 100644 index 000000000..11c965ca3 --- /dev/null +++ b/src/floppy/lzf/lzfP.h @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2000-2007 Marc Alexander Lehmann + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +#ifndef LZFP_h +#define LZFP_h + +#define STANDALONE 1 /* at the moment, this is ok. */ + +#ifndef STANDALONE +# include "lzf.h" +#endif + +/* + * Size of hashtable is (1 << HLOG) * sizeof (char *) + * decompression is independent of the hash table size + * the difference between 15 and 14 is very small + * for small blocks (and 14 is usually a bit faster). + * For a low-memory/faster configuration, use HLOG == 13; + * For best compression, use 15 or 16 (or more, up to 22). + */ +#ifndef HLOG +# define HLOG 16 +#endif + +/* + * Sacrifice very little compression quality in favour of compression speed. + * This gives almost the same compression as the default code, and is + * (very roughly) 15% faster. This is the preferred mode of operation. + */ +#ifndef VERY_FAST +# define VERY_FAST 1 +#endif + +/* + * Sacrifice some more compression quality in favour of compression speed. + * (roughly 1-2% worse compression for large blocks and + * 9-10% for small, redundant, blocks and >>20% better speed in both cases) + * In short: when in need for speed, enable this for binary data, + * possibly disable this for text data. + */ +#ifndef ULTRA_FAST +# define ULTRA_FAST 1 +#endif + +/* + * Unconditionally aligning does not cost very much, so do it if unsure + */ +#ifndef STRICT_ALIGN +# define STRICT_ALIGN !(defined(__i386) || defined (__amd64)) +#endif + +/* + * You may choose to pre-set the hash table (might be faster on some + * modern cpus and large (>>64k) blocks, and also makes compression + * deterministic/repeatable when the configuration otherwise is the same). + */ +#ifndef INIT_HTAB +# define INIT_HTAB 1 +#endif + +/* + * Avoid assigning values to errno variable? for some embedding purposes + * (linux kernel for example), this is necessary. NOTE: this breaks + * the documentation in lzf.h. Avoiding errno has no speed impact. + */ +#ifndef AVOID_ERRNO +# define AVOID_ERRNO 0 +#endif + +/* + * Whether to pass the LZF_STATE variable as argument, or allocate it + * on the stack. For small-stack environments, define this to 1. + * NOTE: this breaks the prototype in lzf.h. + */ +#ifndef LZF_STATE_ARG +# define LZF_STATE_ARG 0 +#endif + +/* + * Whether to add extra checks for input validity in lzf_decompress + * and return EINVAL if the input stream has been corrupted. This + * only shields against overflowing the input buffer and will not + * detect most corrupted streams. + * This check is not normally noticeable on modern hardware + * (<1% slowdown), but might slow down older cpus considerably. + */ +#ifndef CHECK_INPUT +# define CHECK_INPUT 1 +#endif + +/* + * Whether to store pointers or offsets inside the hash table. On + * 64 bit architetcures, pointers take up twice as much space, + * and might also be slower. Default is to autodetect. + */ +/*#define LZF_USER_OFFSETS autodetect */ + +/*****************************************************************************/ +/* nothing should be changed below */ + +#ifdef __cplusplus +# include +# include +using namespace std; +#else +# include +# include +#endif + +#ifndef LZF_USE_OFFSETS +# if defined(_WIN32) +# define LZF_USE_OFFSETS defined(_M_X64) +# else +# if __cplusplus > 199711L +# include +# else +# include +# endif +# define LZF_USE_OFFSETS (UINTPTR_MAX > 0xffffffffU) +# endif +#endif + +typedef unsigned char u8; + +#if LZF_USE_OFFSETS +# define LZF_HSLOT_BIAS ((const u8 *)in_data) + typedef unsigned int LZF_HSLOT; +#else +# define LZF_HSLOT_BIAS 0 + typedef const u8 *LZF_HSLOT; +#endif + +typedef LZF_HSLOT LZF_STATE[1 << (HLOG)]; + +#if !STRICT_ALIGN +/* for unaligned accesses we need a 16 bit datatype. */ +# if USHRT_MAX == 65535 + typedef unsigned short u16; +# elif UINT_MAX == 65535 + typedef unsigned int u16; +# else +# undef STRICT_ALIGN +# define STRICT_ALIGN 1 +# endif +#endif + +#if ULTRA_FAST +# undef VERY_FAST +#endif + +#endif + diff --git a/src/floppy/lzf/lzf_c.c b/src/floppy/lzf/lzf_c.c new file mode 100644 index 000000000..8ba4d0b84 --- /dev/null +++ b/src/floppy/lzf/lzf_c.c @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2000-2010 Marc Alexander Lehmann + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +#include + +#include "lzfP.h" + +#define HSIZE (1 << (HLOG)) + +/* + * don't play with this unless you benchmark! + * the data format is not dependent on the hash function. + * the hash function might seem strange, just believe me, + * it works ;) + */ +#ifndef FRST +# define FRST(p) (((p[0]) << 8) | p[1]) +# define NEXT(v,p) (((v) << 8) | p[2]) +# if ULTRA_FAST +# define IDX(h) ((( h >> (3*8 - HLOG)) - h ) & (HSIZE - 1)) +# elif VERY_FAST +# define IDX(h) ((( h >> (3*8 - HLOG)) - h*5) & (HSIZE - 1)) +# else +# define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1)) +# endif +#endif +/* + * IDX works because it is very similar to a multiplicative hash, e.g. + * ((h * 57321 >> (3*8 - HLOG)) & (HSIZE - 1)) + * the latter is also quite fast on newer CPUs, and compresses similarly. + * + * the next one is also quite good, albeit slow ;) + * (int)(cos(h & 0xffffff) * 1e6) + */ + +#if 0 +/* original lzv-like hash function, much worse and thus slower */ +# define FRST(p) (p[0] << 5) ^ p[1] +# define NEXT(v,p) ((v) << 5) ^ p[2] +# define IDX(h) ((h) & (HSIZE - 1)) +#endif + +#define MAX_LIT (1 << 5) +#define MAX_OFF (1 << 13) +#define MAX_REF ((1 << 8) + (1 << 3)) + +#if __GNUC__ >= 3 +# define expect(expr,value) __builtin_expect ((expr),(value)) +# define inline inline +#else +# define expect(expr,value) (expr) +# define inline static +#endif + +#define expect_false(expr) expect ((expr) != 0, 0) +#define expect_true(expr) expect ((expr) != 0, 1) + +/* + * compressed format + * + * 000LLLLL ; literal, L+1=1..33 octets + * LLLooooo oooooooo ; backref L+1=1..7 octets, o+1=1..4096 offset + * 111ooooo LLLLLLLL oooooooo ; backref L+8 octets, o+1=1..4096 offset + * + */ + +unsigned int +lzf_compress (const void *const in_data, unsigned int in_len, + void *out_data, unsigned int out_len +#if LZF_STATE_ARG + , LZF_STATE htab +#endif + ) +{ +#if !LZF_STATE_ARG + LZF_STATE htab; +#endif + const u8 *ip = (const u8 *)in_data; + u8 *op = (u8 *)out_data; + const u8 *in_end = ip + in_len; + u8 *out_end = op + out_len; + const u8 *ref; + + /* off requires a type wide enough to hold a general pointer difference. + * ISO C doesn't have that (size_t might not be enough and ptrdiff_t only + * works for differences within a single object). We also assume that no + * no bit pattern traps. Since the only platform that is both non-POSIX + * and fails to support both assumptions is windows 64 bit, we make a + * special workaround for it. + */ +#if defined(_WIN32) && defined(_M_X64) + uint64_t off; /* workaround for missing POSIX compliance */ +#else + unsigned long off; +#endif + unsigned int hval; + int lit; + + if (!in_len || !out_len) + return 0; + +#if INIT_HTAB + memset (htab, 0, sizeof (htab)); +#endif + + lit = 0; op++; /* start run */ + + hval = FRST (ip); + while (ip < in_end - 2) + { + LZF_HSLOT *hslot; + + hval = NEXT (hval, ip); + hslot = htab + IDX (hval); + ref = *hslot + LZF_HSLOT_BIAS; *hslot = ip - LZF_HSLOT_BIAS; + + if (1 +#if INIT_HTAB + && ref < ip /* the next test will actually take care of this, but this is faster */ +#endif + && (off = ip - ref - 1) < MAX_OFF + && ref > (u8 *)in_data + && ref[2] == ip[2] +#if STRICT_ALIGN + && ((ref[1] << 8) | ref[0]) == ((ip[1] << 8) | ip[0]) +#else + && *(u16 *)ref == *(u16 *)ip +#endif + ) + { + /* match found at *ref++ */ + unsigned int len = 2; + unsigned int maxlen = in_end - ip - len; + maxlen = maxlen > MAX_REF ? MAX_REF : maxlen; + + if (expect_false (op + 3 + 1 >= out_end)) /* first a faster conservative test */ + if (op - !lit + 3 + 1 >= out_end) /* second the exact but rare test */ + return 0; + + op [- lit - 1] = lit - 1; /* stop run */ + op -= !lit; /* undo run if length is zero */ + + for (;;) + { + if (expect_true (maxlen > 16)) + { + len++; if (ref [len] != ip [len]) break; + len++; if (ref [len] != ip [len]) break; + len++; if (ref [len] != ip [len]) break; + len++; if (ref [len] != ip [len]) break; + + len++; if (ref [len] != ip [len]) break; + len++; if (ref [len] != ip [len]) break; + len++; if (ref [len] != ip [len]) break; + len++; if (ref [len] != ip [len]) break; + + len++; if (ref [len] != ip [len]) break; + len++; if (ref [len] != ip [len]) break; + len++; if (ref [len] != ip [len]) break; + len++; if (ref [len] != ip [len]) break; + + len++; if (ref [len] != ip [len]) break; + len++; if (ref [len] != ip [len]) break; + len++; if (ref [len] != ip [len]) break; + len++; if (ref [len] != ip [len]) break; + } + + do + len++; + while (len < maxlen && ref[len] == ip[len]); + + break; + } + + len -= 2; /* len is now #octets - 1 */ + ip++; + + if (len < 7) + { + *op++ = (off >> 8) + (len << 5); + } + else + { + *op++ = (off >> 8) + ( 7 << 5); + *op++ = len - 7; + } + + *op++ = off; + + lit = 0; op++; /* start run */ + + ip += len + 1; + + if (expect_false (ip >= in_end - 2)) + break; + +#if ULTRA_FAST || VERY_FAST + --ip; +# if VERY_FAST && !ULTRA_FAST + --ip; +# endif + hval = FRST (ip); + + hval = NEXT (hval, ip); + htab[IDX (hval)] = ip - LZF_HSLOT_BIAS; + ip++; + +# if VERY_FAST && !ULTRA_FAST + hval = NEXT (hval, ip); + htab[IDX (hval)] = ip - LZF_HSLOT_BIAS; + ip++; +# endif +#else + ip -= len + 1; + + do + { + hval = NEXT (hval, ip); + htab[IDX (hval)] = ip - LZF_HSLOT_BIAS; + ip++; + } + while (len--); +#endif + } + else + { + /* one more literal byte we must copy */ + if (expect_false (op >= out_end)) + return 0; + + lit++; *op++ = *ip++; + + if (expect_false (lit == MAX_LIT)) + { + op [- lit - 1] = lit - 1; /* stop run */ + lit = 0; op++; /* start run */ + } + } + } + + if (op + 3 > out_end) /* at most 3 bytes can be missing here */ + return 0; + + while (ip < in_end) + { + lit++; *op++ = *ip++; + + if (expect_false (lit == MAX_LIT)) + { + op [- lit - 1] = lit - 1; /* stop run */ + lit = 0; op++; /* start run */ + } + } + + op [- lit - 1] = lit - 1; /* end run */ + op -= !lit; /* undo run if length is zero */ + + return op - (u8 *)out_data; +} + diff --git a/src/floppy/lzf/lzf_d.c b/src/floppy/lzf/lzf_d.c new file mode 100644 index 000000000..8433b8f1f --- /dev/null +++ b/src/floppy/lzf/lzf_d.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2000-2010 Marc Alexander Lehmann + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +#include "lzfP.h" + +#if AVOID_ERRNO +# define SET_ERRNO(n) +#else +# include +# define SET_ERRNO(n) errno = (n) +#endif + +#if USE_REP_MOVSB /* small win on amd, big loss on intel */ +#if (__i386 || __amd64) && __GNUC__ >= 3 +# define lzf_movsb(dst, src, len) \ + asm ("rep movsb" \ + : "=D" (dst), "=S" (src), "=c" (len) \ + : "0" (dst), "1" (src), "2" (len)); +#endif +#endif + +unsigned int +lzf_decompress (const void *const in_data, unsigned int in_len, + void *out_data, unsigned int out_len) +{ + u8 const *ip = (const u8 *)in_data; + u8 *op = (u8 *)out_data; + u8 const *const in_end = ip + in_len; + u8 *const out_end = op + out_len; + + do + { + unsigned int ctrl = *ip++; + + if (ctrl < (1 << 5)) /* literal run */ + { + ctrl++; + + if (op + ctrl > out_end) + { + SET_ERRNO (E2BIG); + return 0; + } + +#if CHECK_INPUT + if (ip + ctrl > in_end) + { + SET_ERRNO (EINVAL); + return 0; + } +#endif + +#ifdef lzf_movsb + lzf_movsb (op, ip, ctrl); +#else + switch (ctrl) + { + case 32: *op++ = *ip++; case 31: *op++ = *ip++; case 30: *op++ = *ip++; case 29: *op++ = *ip++; + case 28: *op++ = *ip++; case 27: *op++ = *ip++; case 26: *op++ = *ip++; case 25: *op++ = *ip++; + case 24: *op++ = *ip++; case 23: *op++ = *ip++; case 22: *op++ = *ip++; case 21: *op++ = *ip++; + case 20: *op++ = *ip++; case 19: *op++ = *ip++; case 18: *op++ = *ip++; case 17: *op++ = *ip++; + case 16: *op++ = *ip++; case 15: *op++ = *ip++; case 14: *op++ = *ip++; case 13: *op++ = *ip++; + case 12: *op++ = *ip++; case 11: *op++ = *ip++; case 10: *op++ = *ip++; case 9: *op++ = *ip++; + case 8: *op++ = *ip++; case 7: *op++ = *ip++; case 6: *op++ = *ip++; case 5: *op++ = *ip++; + case 4: *op++ = *ip++; case 3: *op++ = *ip++; case 2: *op++ = *ip++; case 1: *op++ = *ip++; + } +#endif + } + else /* back reference */ + { + unsigned int len = ctrl >> 5; + + u8 *ref = op - ((ctrl & 0x1f) << 8) - 1; + +#if CHECK_INPUT + if (ip >= in_end) + { + SET_ERRNO (EINVAL); + return 0; + } +#endif + if (len == 7) + { + len += *ip++; +#if CHECK_INPUT + if (ip >= in_end) + { + SET_ERRNO (EINVAL); + return 0; + } +#endif + } + + ref -= *ip++; + + if (op + len + 2 > out_end) + { + SET_ERRNO (E2BIG); + return 0; + } + + if (ref < (u8 *)out_data) + { + SET_ERRNO (EINVAL); + return 0; + } + +#ifdef lzf_movsb + len += 2; + lzf_movsb (op, ref, len); +#else + switch (len) + { + default: + len += 2; + + if (op >= ref + len) + { + /* disjunct areas */ + memcpy (op, ref, len); + op += len; + } + else + { + /* overlapping, use octte by octte copying */ + do + *op++ = *ref++; + while (--len); + } + + break; + + case 9: *op++ = *ref++; + case 8: *op++ = *ref++; + case 7: *op++ = *ref++; + case 6: *op++ = *ref++; + case 5: *op++ = *ref++; + case 4: *op++ = *ref++; + case 3: *op++ = *ref++; + case 2: *op++ = *ref++; + case 1: *op++ = *ref++; + case 0: *op++ = *ref++; /* two octets more */ + *op++ = *ref++; + } +#endif + } + } + while (ip < in_end); + + return op - (u8 *)out_data; +} + From d2b5bf92005594a4fad519d2af9c72722d2dcd76 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Mar 2018 01:36:56 +0100 Subject: [PATCH 11/39] Removed the old LZF files; The 86F handler now only allocates the track surface descriptor data if the inserted image is an 86F and such data is present in the image. --- src/floppy/fdd_86f.c | 59 +- src/lzf/Changes | 136 - src/lzf/LICENSE | 27 - src/lzf/Makefile.in | 66 - src/lzf/README | 29 - src/lzf/config.h | 16 - src/lzf/configure | 7871 ---------------------------------------- src/lzf/configure.ac | 25 - src/lzf/crc32.h | 65 - src/lzf/install-sh | 251 -- src/lzf/lzf.c | 537 --- src/lzf/lzf.h | 100 - src/lzf/lzfP.h | 185 - src/lzf/lzf_c.c | 293 -- src/lzf/lzf_d.c | 185 - src/win/Makefile.mingw | 4 +- 16 files changed, 57 insertions(+), 9792 deletions(-) delete mode 100644 src/lzf/Changes delete mode 100644 src/lzf/LICENSE delete mode 100644 src/lzf/Makefile.in delete mode 100644 src/lzf/README delete mode 100644 src/lzf/config.h delete mode 100644 src/lzf/configure delete mode 100644 src/lzf/configure.ac delete mode 100644 src/lzf/crc32.h delete mode 100644 src/lzf/install-sh delete mode 100644 src/lzf/lzf.c delete mode 100644 src/lzf/lzf.h delete mode 100644 src/lzf/lzfP.h delete mode 100644 src/lzf/lzf_c.c delete mode 100644 src/lzf/lzf_d.c diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 21500c44d..ded25f291 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -10,7 +10,7 @@ * data in the form of FM/MFM-encoded transitions) which also * forms the core of the emulator's floppy disk emulation. * - * Version: @(#)fdd_86f.c 1.0.6 2018/03/16 + * Version: @(#)fdd_86f.c 1.0.7 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -196,9 +196,9 @@ typedef struct { 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 *track_surface_data[2]; uint16_t thin_track_encoded_data[2][2][53048]; - uint16_t thin_track_surface_data[2][2][53048]; + uint16_t *thin_track_surface_data[2][2]; uint16_t side_flags[2]; uint32_t index_hole_pos[2]; uint32_t track_offset[512]; @@ -3455,7 +3455,7 @@ d86f_load(int drive, wchar_t *fn) uint32_t magic = 0; uint32_t len = 0; uint16_t temp = 0; - int i = 0; + int i = 0, j = 0; FILE *tf; d86f_unregister(drive); @@ -3522,6 +3522,17 @@ d86f_load(int drive, wchar_t *fn) } fread(&(dev->disk_flags), 2, 1, dev->f); + + if (d86f_has_surface_desc(drive)) { + for (i = 0; i < 2; i++) + dev->track_surface_data[i] = (uint16_t *) malloc(53048 * sizeof(uint16_t)); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) + dev->thin_track_surface_data[i][j] = (uint16_t *) malloc(53048 * sizeof(uint16_t)); + } + } + dev->is_compressed = (magic == 0x66623638) ? 1 : 0; if ((len < 51052) && !dev->is_compressed) { /* File too small, abort. */ @@ -3752,6 +3763,8 @@ d86f_set_fdc(void *fdc) void d86f_close(int drive) { + int i, j; + wchar_t temp_file_name[2048]; d86f_t *dev = d86f[drive]; @@ -3760,6 +3773,24 @@ d86f_close(int drive) memcpy(temp_file_name, drive ? nvr_path(L"TEMP$$$1.$$$") : nvr_path(L"TEMP$$$0.$$$"), 26); + if (d86f_has_surface_desc(drive)) { + for (i = 0; i < 2; i++) { + if (dev->track_surface_data[i]) { + free(dev->track_surface_data[i]); + dev->track_surface_data[i] = NULL; + } + } + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + if (dev->thin_track_surface_data[i][j]) { + free(dev->thin_track_surface_data[i][j]); + dev->thin_track_surface_data[i][j] = NULL; + } + } + } + } + if (dev->f) { fclose(dev->f); dev->f = NULL; @@ -3792,10 +3823,30 @@ d86f_setup(int drive) void d86f_destroy(int drive) { + int i, j; + d86f_t *dev = d86f[drive]; if (dev == NULL) return; + if (d86f_has_surface_desc(drive)) { + for (i = 0; i < 2; i++) { + if (dev->track_surface_data[i]) { + free(dev->track_surface_data[i]); + dev->track_surface_data[i] = NULL; + } + } + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + if (dev->thin_track_surface_data[i][j]) { + free(dev->thin_track_surface_data[i][j]); + dev->thin_track_surface_data[i][j] = NULL; + } + } + } + } + d86f_destroy_linked_lists(drive, 0); d86f_destroy_linked_lists(drive, 1); diff --git a/src/lzf/Changes b/src/lzf/Changes deleted file mode 100644 index 93bd4cb6d..000000000 --- a/src/lzf/Changes +++ /dev/null @@ -1,136 +0,0 @@ -3.6 Mon Feb 7 17:37:31 CET 2011 - - fixed hash calculation in C♯ version (Tiago Freitas Leal). - - unroll copy for small sizes, use memcpy for larger sizes, - greatly speeding up decompression in most cases. - - finally disable rep movsb - it's a big loss on modern intel cpus, - and only a small win on amd cpus. - - improve C++ compatibility of the code. - - slightly improve compressor speed. - - halved memory requirements for compressor on 64 bit architectures, - which can improve the speed quite a bit on older cpus. - -3.5 Fri May 1 02:28:42 CEST 2009 - - lzf_compress did sometimes write one octet past the given output - buffer (analyzed and nice testcase by Salvatore Sanfilippo). - -3.4 Tue Sep 2 06:45:00 CEST 2008 - - the fix from 3.3 introduced a compression bug, which is fixed in - this release (which explains the mysterious prerelease...). Thanks - once more to Clément Calmels. - -3.3 Mon Aug 25 03:17:42 CEST 2008 - - lzf_compress could access memory after the given input buffer - when outputting back references. reported with nice testcase - by Clément Calmels. - -3.2 Fri May 9 18:52:23 CEST 2008 - - include a workaround for failing POSIX and real-world compliance - on 64 bit windows (microsoft claims to support POSIX, but is far - from it). (bug found and analysed nicely by John Lilley). - -3.1 Fri Nov 30 11:33:04 CET 2007 - - IMPORTANT BUGFIX: a too long final literal run would corrupt data - in the encoder (this was introduced in 3.0 only, earlier versions - are safe). - -3.0 Tue Nov 13 22:13:09 CET 2007 - - switched to 2-clause bsd with "GPL v2 or any later version" option. - - speed up compression by ~10-15% in common cases - by some manual unrolling. - - import some compiler tricks from JSON::XS, for further speed-ups. - - tune hash functions depending on ULTRA_FAST or VERY_FAST settings. - - for typical binary data (e.g. /bin/bash, memory dumps, - canterbury corpus etc.), speed is now comparable to fastlz, but - with better compression ratio. with ULTRA_FAST, it's typically - 3-15% faster than fastlz while still maintaining a similar ratio. - (amd64 and core 2 duo, ymmv). thanks a lot for the competition :) - - undo inline assembly in compressor, it is no longer helpful. - - no changes to the decompressor. - - use a HLOG of 16 by default now (formerly 15). - -2.1 Fri Nov 2 13:34:42 CET 2007 - - switched to a 2-clause bsd license with GPL exception. - - get rid of memcpy. - - tentatively use rep movsb on x86 and x86_64 (gcc only) for a - moderate speed improvement. - - applied patch by Kein-Hong Man to maske lzf.c compile under - the crippled mingw32 environment. - -2.0 Fri Feb 16 23:11:18 CET 2007 - - replaced lzf demo by industrial-strength lzf utility with behaviour - similar other compression utilities. Thanks for Stefan Traby for - rewriting it! - - fix state arg prototype. - -1.7 Wed Sep 27 17:29:15 CEST 2006 - - remove bogus "unlzf" patch. - note to self: never accept well-meant patches. - - make lzf more robust in presence of padding bytes or sudden eof. - -1.6 Fri Jul 7 17:31:26 CEST 2006 - - the lzf example utility will now uncompress if invoked - as "unlzf" (patch by Scott Feeney). - - add CHECK_INPUT option that adds more checks for input - data validity. - - help applications that do not pass in the correct length - (such as php) by returning either EINVAL or E2BIG. - - default HLOG size is now 15 (cpu caches have increased). - - documentation fixes. - -1.51 Thu Apr 14 22:15:46 CEST 2005 - - incorporated C♯ implementation of both the en- and decoder, - written by "Oren J. Maurice". - You can find it in the cs/ subdirectory. - - make FRST, NEXT IDX overridable if lzf_c.c is directly included - in the code. - -1.5 Tue Mar 8 20:23:23 CET 2005 - - incorporated improvements by Adam D. Moss, - which includes a new VERY_FAST mode which is - a bit slower than ULTRA_FAST but much better, - and enabled it as default. - -1.401 Thu Mar 3 18:00:52 CET 2005 - - use cstring in c++, not string.h. - - change of contact address. - -1.4 Wed Dec 15 08:08:49 CET 2004 - - very very slight tuning of the hashing function. - -1.3 Thu Mar 25 15:41:17 CET 2004 - - changed license of lzf core code to explicitly allow - relicensing under the GPLv2. - - added VPATH support as suggested by Björn Eriksson. - -1.2 Mon Dec 29 13:47:28 CET 2003 - - avoid spurious memory accesses after the to-be-compressed - memory region. originally reported by Michal Zalewski. - - flip LZF_STACK_ARG meaning (to be correct). - -1.1 Tue Dec 23 05:48:32 CET 2003 - - removed #warn directive, it's not worth the hassle. - - add LZF_STACK_ARG and AVOID_ERRNO configurations - for embedded systems. - - make it compile cleanly as c++. - - some small documentation and code fixes. - -1.0 Sun Nov 17 12:37:37 CET 2002 - - slightly better compression ratio, almost unmeasurably - slower. - - some documentation fixes. - -0.4 Thu Jun 13 14:11:10 CEST 2002 - - typoe fix. - - lzf demo program now properly decompresses small files. - - fix another 64 bit issue, found by Laurent Deniel. - -0.3 Tue Jan 16 13:21:14 CET 2001 - - fix silly beginners 32/64 bit mistake. - -0.2 Thu Jan 4 05:56:42 CET 2001 - - now totally independent of autoconfig, for - easy inclusion into other programs. - - much better fine-tuning, faster and better than 0.1. - -0.1 2000 - - initial release. diff --git a/src/lzf/LICENSE b/src/lzf/LICENSE deleted file mode 100644 index ee54ff717..000000000 --- a/src/lzf/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2000-2009 Marc Alexander Lehmann - -Redistribution and use in source and binary forms, with or without modifica- -tion, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- -CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- -CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- -ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. - -Alternatively, the following files carry an additional notice that -explicitly allows relicensing under the GPLv2: lzf.c lzf.h lzfP.h lzf_c.c -lzf_d.c - diff --git a/src/lzf/Makefile.in b/src/lzf/Makefile.in deleted file mode 100644 index 3c87d62de..000000000 --- a/src/lzf/Makefile.in +++ /dev/null @@ -1,66 +0,0 @@ -VERSION = 3.6 - -prefix = @prefix@ -exec_prefix = @exec_prefix@ -libdir = @libdir@ -bindir = @bindir@ -includedir = @includedir@ - -VPATH = @srcdir@ - -CC = @CC@ -CPPFLAGS = -I. @CPPFLAGS@ -CFLAGS = @CFLAGS@ -LDFLAGS = @LDFLAGS@ -RANLIB = @RANLIB@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ - -all: Makefile lzf - -clean: - -rm -f *.o *.a lzf bench - -lzf_c.o: lzf_c.c lzfP.h - -lzf_d.o: lzf_d.c lzfP.h - -lzf.o: lzf.c - -lzf: lzf.o liblzf.a - -lzfP.h: lzf.h config.h - -liblzf.a: lzf_c.o lzf_d.o - rm -f $@ - $(AR) rc $@ $^ - $(RANLIB) $@ - -install: all - $(INSTALL) -d $(bindir) - $(INSTALL) -m 755 lzf $(bindir) - $(INSTALL) -d $(includedir) - $(INSTALL_DATA) lzf.h $(includedir) - $(INSTALL) -d $(libdir) - $(INSTALL_DATA) liblzf.a $(libdir) - -dist: - mkdir liblzf-$(VERSION) - tar c LICENSE README Makefile.in config.h.in \ - configure configure.ac install-sh \ - cs/README cs/CLZF.cs \ - lzf.h lzfP.h lzf_c.c lzf_d.c \ - crc32.h lzf.c Changes \ - | tar xpC liblzf-$(VERSION) - -chown -R root.root liblzf-$(VERSION) - chmod -R u=rwX,go=rX liblzf-$(VERSION) - tar cvf - liblzf-$(VERSION) | gzip -9 >liblzf-$(VERSION).tar.gz - rm -rf liblzf-$(VERSION) - ls -l liblzf-$(VERSION).tar.gz - -Makefile: Makefile.in - ./config.status - -bench: Makefile liblzf.a bench.c - $(CC) $(CPPFLAGS) $(CFLAGS) -g -o bench bench.c -L. -llzf - diff --git a/src/lzf/README b/src/lzf/README deleted file mode 100644 index 0734ebe06..000000000 --- a/src/lzf/README +++ /dev/null @@ -1,29 +0,0 @@ -DESCRIPTION - LZF is an extremely fast (not that much slower than a pure memcpy) - compression algorithm. It is ideal for applications where you want to - save *some* space but not at the cost of speed. It is ideal for - repetitive data as well. The module is self-contained and very small. - - It's written in ISO-C with no external dependencies other than what - C provides and can easily be #include'd into your code, no makefile - changes or library builds requires. - - A C♯ implementation without external dependencies is available, too. - - I do not know for certain whether any patents in any countries apply - to this algorithm, but at the moment it is believed that it is free - from any patents. More importantly, it is also free to use in every - software package (see LICENSE). - - See the lzf.h file for details on how the functions in this - mini-library are to be used. - - NOTE: This package contains a very bare-bones command-line utility - which is neither optimized for speed nor for compression. This library - is really intended to be used inside larger programs. - -AUTHOR - This library was written by Marc Lehmann (See also - http://software.schmorp.de/pkg/liblzf). - - diff --git a/src/lzf/config.h b/src/lzf/config.h deleted file mode 100644 index 5fd69c6bd..000000000 --- a/src/lzf/config.h +++ /dev/null @@ -1,16 +0,0 @@ -/* config.h.in. Generated automatically from configure.in by autoheader 2.13. */ - -/* Define to empty if the keyword does not work. */ -#undef const - -/* Define if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* The number of bytes in a int. */ -#undef SIZEOF_INT - -/* The number of bytes in a long. */ -#undef SIZEOF_LONG - -/* The number of bytes in a short. */ -#undef SIZEOF_SHORT diff --git a/src/lzf/configure b/src/lzf/configure deleted file mode 100644 index 7a3a2b25c..000000000 --- a/src/lzf/configure +++ /dev/null @@ -1,7871 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.60. -# -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - - -# PATH needs CR -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -as_nl=' -' -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - { (exit 1); exit 1; } -fi - -# Work around bugs in pre-3.0 UWIN ksh. -for as_var in ENV MAIL MAILPATH -do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# CDPATH. -$as_unset CDPATH - - -if test "x$CONFIG_SHELL" = x; then - if (eval ":") 2>/dev/null; then - as_have_required=yes -else - as_have_required=no -fi - - if test $as_have_required = yes && (eval ": -(as_func_return () { - (exit \$1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = \"\$1\" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test \$exitcode = 0) || { (exit 1); exit 1; } - -( - as_lineno_1=\$LINENO - as_lineno_2=\$LINENO - test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && - test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } -") 2> /dev/null; then - : -else - as_candidate_shells= - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - case $as_dir in - /*) - for as_base in sh bash ksh sh5; do - as_candidate_shells="$as_candidate_shells $as_dir/$as_base" - done;; - esac -done -IFS=$as_save_IFS - - - for as_shell in $as_candidate_shells $SHELL; do - # Try only shells that exist, to save several forks. - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { ("$as_shell") 2> /dev/null <<\_ASEOF -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -: -_ASEOF -}; then - CONFIG_SHELL=$as_shell - as_have_required=yes - if { "$as_shell" 2> /dev/null <<\_ASEOF -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -: -(as_func_return () { - (exit $1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = "$1" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test $exitcode = 0) || { (exit 1); exit 1; } - -( - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } - -_ASEOF -}; then - break -fi - -fi - - done - - if test "x$CONFIG_SHELL" != x; then - for as_var in BASH_ENV ENV - do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - done - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} -fi - - - if test $as_have_required = no; then - echo This script requires a shell more modern than all the - echo shells that I found on your system. Please install a - echo modern shell, or manually run the script under such a - echo shell if you do have one. - { (exit 1); exit 1; } -fi - - -fi - -fi - - - -(eval "as_func_return () { - (exit \$1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = \"\$1\" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test \$exitcode = 0") || { - echo No shell found that supports shell functions. - echo Please tell autoconf@gnu.org about your system, - echo including any error possibly output before this - echo message -} - - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line after each line using $LINENO; the second 'sed' - # does the real work. The second script uses 'N' to pair each - # line-number line with the line containing $LINENO, and appends - # trailing '-' during substitution so that $LINENO is not a special - # case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # scripts with optimization help from Paolo Bonzini. Blame Lee - # E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in --n*) - case `echo 'x\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - *) ECHO_C='\c';; - esac;; -*) - ECHO_N='-n';; -esac - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir -fi -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -# Find out whether ``test -x'' works. Don't use a zero-byte file, as -# systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - as_executable_p="test -x" -else - as_executable_p=: -fi -rm -f conf$$.file - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - - -exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} - -# Identity of this package. -PACKAGE_NAME= -PACKAGE_TARNAME= -PACKAGE_VERSION= -PACKAGE_STRING= -PACKAGE_BUGREPORT= - -ac_unique_file="lzfP.h" -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_STAT_H -# include -#endif -#if STDC_HEADERS -# include -# include -#else -# if HAVE_STDLIB_H -# include -# endif -#endif -#if HAVE_STRING_H -# if !STDC_HEADERS && HAVE_MEMORY_H -# include -# endif -# include -#endif -#if HAVE_STRINGS_H -# include -#endif -#if HAVE_INTTYPES_H -# include -#endif -#if HAVE_STDINT_H -# include -#endif -#if HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='SHELL -PATH_SEPARATOR -PACKAGE_NAME -PACKAGE_TARNAME -PACKAGE_VERSION -PACKAGE_STRING -PACKAGE_BUGREPORT -exec_prefix -prefix -program_transform_name -bindir -sbindir -libexecdir -datarootdir -datadir -sysconfdir -sharedstatedir -localstatedir -includedir -oldincludedir -docdir -infodir -htmldir -dvidir -pdfdir -psdir -libdir -localedir -mandir -DEFS -ECHO_C -ECHO_N -ECHO_T -LIBS -build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -CPPFLAGS -ac_ct_CC -EXEEXT -OBJEXT -RANLIB -INSTALL_PROGRAM -INSTALL_SCRIPT -INSTALL_DATA -CPP -GREP -EGREP -LIBOBJS -LTLIBOBJS' -ac_subst_files='' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -CPPFLAGS -CPP' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - eval enable_$ac_feature=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - eval enable_$ac_feature=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` - eval with_$ac_package=\$ac_optarg ;; - - -without-* | --without-*) - ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` - eval with_$ac_package=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) { echo "$as_me: error: unrecognized option: $ac_option -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 - { (exit 1); exit 1; }; } - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - { echo "$as_me: error: missing argument to $ac_option" >&2 - { (exit 1); exit 1; }; } -fi - -# Be sure to have absolute directory names. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; } -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - { echo "$as_me: error: Working directory cannot be determined" >&2 - { (exit 1); exit 1; }; } -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - { echo "$as_me: error: pwd does not report name of working directory" >&2 - { (exit 1); exit 1; }; } - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$0" || -$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -echo X"$0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 - { (exit 1); exit 1; }; } -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 - { (exit 1); exit 1; }; } - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures this package to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF -_ACEOF -fi - -if test -n "$ac_init_help"; then - - cat <<\_ACEOF - -Optional Features: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-largefile omit support for large files - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CPP C preprocessor - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -configure -generated by GNU Autoconf 2.60 - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by $as_me, which was -generated by GNU Autoconf 2.60. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - echo "PATH: $as_dir" -done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; - 2) - ac_configure_args1="$ac_configure_args1 '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - ac_configure_args="$ac_configure_args '$ac_arg'" - ;; - esac - done -done -$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } -$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - cat <<\_ASBOX -## ---------------- ## -## Cache variables. ## -## ---------------- ## -_ASBOX - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 -echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - *) $as_unset $ac_var ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - cat <<\_ASBOX -## ----------------- ## -## Output variables. ## -## ----------------- ## -_ASBOX - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------------- ## -## File substitutions. ## -## ------------------- ## -_ASBOX - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## -## confdefs.h. ## -## ----------- ## -_ASBOX - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - echo "$as_me: caught signal $ac_signal" - echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer explicitly selected file to automatically selected ones. -if test -n "$CONFIG_SITE"; then - set x "$CONFIG_SITE" -elif test "x$prefix" != xNONE; then - set x "$prefix/share/config.site" "$prefix/etc/config.site" -else - set x "$ac_default_prefix/share/config.site" \ - "$ac_default_prefix/etc/config.site" -fi -shift -for ac_site_file -do - if test -r "$ac_site_file"; then - { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then - { echo "$as_me:$LINENO: loading cache $cache_file" >&5 -echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { echo "$as_me:$LINENO: creating cache $cache_file" >&5 -echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 -echo "$as_me: former value: $ac_old_val" >&2;} - { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 -echo "$as_me: current value: $ac_new_val" >&2;} - ac_cache_corrupted=: - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -echo "$as_me: error: changes in the environment can compromise the build" >&2;} - { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} - { (exit 1); exit 1; }; } -fi - - - - - - - - - - - - - - - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - -ac_config_headers="$ac_config_headers config.h" - - - -cat >>confdefs.h <<\_ACEOF -#define _GNU_SOURCE 1 -_ACEOF - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - -# Provide some information about the compiler. -echo "$as_me:$LINENO: checking for C compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (ac_try="$ac_compiler --version >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler --version >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -v >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler -v >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -V >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler -V >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 -echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } -ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -# -# List of possible output files, starting from the most likely. -# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) -# only as a last resort. b.out is created by i960 compilers. -ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' -# -# The IRIX 6 linker writes into existing files which may not be -# executable, retaining their permissions. Remove them first so a -# subsequent execution test works. -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { (ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: C compiler cannot create executables -See \`config.log' for more details." >&5 -echo "$as_me: error: C compiler cannot create executables -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } -fi - -ac_exeext=$ac_cv_exeext -{ echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6; } - -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } -# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { echo "$as_me:$LINENO: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - fi - fi -fi -{ echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - -rm -f a.out a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } -{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 -echo "${ECHO_T}$cross_compiling" >&6; } - -{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 -echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest$ac_cv_exeext -{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -echo "${ECHO_T}$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 -echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } -if test "${ac_cv_objext+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -echo "${ECHO_T}$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_compiler_gnu=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } -GCC=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - CFLAGS="" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 -echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_c89=$ac_arg -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6; } ;; - xno) - { echo "$as_me:$LINENO: result: unsupported" >&5 -echo "${ECHO_T}unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; -esac - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -# Check whether --enable-largefile was given. -if test "${enable_largefile+set}" = set; then - enableval=$enable_largefile; -fi - -if test "$enable_largefile" != no; then - - { echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5 -echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6; } -if test "${ac_cv_sys_largefile_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_sys_largefile_CC=no - if test "$GCC" != yes; then - ac_save_CC=$CC - while :; do - # IRIX 6.2 and later do not support large files by default, - # so use the C compiler's -n32 option if that helps. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF - rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext - CC="$CC -n32" - rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sys_largefile_CC=' -n32'; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext - break - done - CC=$ac_save_CC - rm -f conftest.$ac_ext - fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5 -echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6; } - if test "$ac_cv_sys_largefile_CC" != no; then - CC=$CC$ac_cv_sys_largefile_CC - fi - - { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5 -echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6; } -if test "${ac_cv_sys_file_offset_bits+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - while :; do - ac_cv_sys_file_offset_bits=no - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#define _FILE_OFFSET_BITS 64 -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sys_file_offset_bits=64; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - break -done -fi -{ echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5 -echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6; } -if test "$ac_cv_sys_file_offset_bits" != no; then - -cat >>confdefs.h <<_ACEOF -#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits -_ACEOF - -fi -rm -f conftest* - { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5 -echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; } -if test "${ac_cv_sys_large_files+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - while :; do - ac_cv_sys_large_files=no - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#define _LARGE_FILES 1 -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sys_large_files=1; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - break -done -fi -{ echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5 -echo "${ECHO_T}$ac_cv_sys_large_files" >&6; } -if test "$ac_cv_sys_large_files" != no; then - -cat >>confdefs.h <<_ACEOF -#define _LARGE_FILES $ac_cv_sys_large_files -_ACEOF - -fi -rm -f conftest* -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - -# Provide some information about the compiler. -echo "$as_me:$LINENO: checking for C compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (ac_try="$ac_compiler --version >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler --version >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -v >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler -v >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -V >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler -V >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_compiler_gnu=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } -GCC=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - CFLAGS="" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 -echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_c89=$ac_arg -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6; } ;; - xno) - { echo "$as_me:$LINENO: result: unsupported" >&5 -echo "${ECHO_T}unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; -esac - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { echo "$as_me:$LINENO: result: $RANLIB" >&5 -echo "${ECHO_T}$RANLIB" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 -echo "${ECHO_T}$ac_ct_RANLIB" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 -echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} - { (exit 1); exit 1; }; } -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 -echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } -if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in - ./ | .// | /cC/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; }; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - done - done - ;; -esac -done -IFS=$as_save_IFS - - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ echo "$as_me:$LINENO: result: $INSTALL" >&5 -echo "${ECHO_T}$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi - -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi - -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ echo "$as_me:$LINENO: result: $CPP" >&5 -echo "${ECHO_T}$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi - -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi - -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : -else - { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&5 -echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 -echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } -if test "${ac_cv_path_GREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Extract the first word of "grep ggrep" to use in msg output -if test -z "$GREP"; then -set dummy grep ggrep; ac_prog_name=$2 -if test "${ac_cv_path_GREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_path_GREP_found=false -# Loop through the user's path and test for each of PROGNAME-LIST -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue - # Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - ac_count=`expr $ac_count + 1` - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - - $ac_path_GREP_found && break 3 - done -done - -done -IFS=$as_save_IFS - - -fi - -GREP="$ac_cv_path_GREP" -if test -z "$GREP"; then - { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 -echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} - { (exit 1); exit 1; }; } -fi - -else - ac_cv_path_GREP=$GREP -fi - - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 -echo "${ECHO_T}$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ echo "$as_me:$LINENO: checking for egrep" >&5 -echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } -if test "${ac_cv_path_EGREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - # Extract the first word of "egrep" to use in msg output -if test -z "$EGREP"; then -set dummy egrep; ac_prog_name=$2 -if test "${ac_cv_path_EGREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_path_EGREP_found=false -# Loop through the user's path and test for each of PROGNAME-LIST -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue - # Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - ac_count=`expr $ac_count + 1` - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - - $ac_path_EGREP_found && break 3 - done -done - -done -IFS=$as_save_IFS - - -fi - -EGREP="$ac_cv_path_EGREP" -if test -z "$EGREP"; then - { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 -echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} - { (exit 1); exit 1; }; } -fi - -else - ac_cv_path_EGREP=$EGREP -fi - - - fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 -echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } -if test "${ac_cv_header_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_header_stdc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_header_stdc=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then - : -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -echo "${ECHO_T}$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -cat >>confdefs.h <<\_ACEOF -#define STDC_HEADERS 1 -_ACEOF - -fi - - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. - - - - - - - - - -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_Header=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_Header=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -{ echo "$as_me:$LINENO: checking for short" >&5 -echo $ECHO_N "checking for short... $ECHO_C" >&6; } -if test "${ac_cv_type_short+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -typedef short ac__type_new_; -int -main () -{ -if ((ac__type_new_ *) 0) - return 0; -if (sizeof (ac__type_new_)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_short=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_type_short=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_short" >&5 -echo "${ECHO_T}$ac_cv_type_short" >&6; } - -{ echo "$as_me:$LINENO: checking size of short" >&5 -echo $ECHO_N "checking size of short... $ECHO_C" >&6; } -if test "${ac_cv_sizeof_short+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$ac_cv_type_short" = yes; then - # The cast to long int works around a bug in the HP C Compiler - # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects - # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. - # This bug is HP SR number 8606223364. - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef short ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef short ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef short ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef short ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo= ac_hi= -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef short ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr '(' $ac_mid ')' + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) ac_cv_sizeof_short=$ac_lo;; -'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (short) -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (short) -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } ;; -esac -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef short ac__type_sizeof_; -static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } -static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if (((long int) (sizeof (ac__type_sizeof_))) < 0) - { - long int i = longval (); - if (i != ((long int) (sizeof (ac__type_sizeof_)))) - return 1; - fprintf (f, "%ld\n", i); - } - else - { - unsigned long int i = ulongval (); - if (i != ((long int) (sizeof (ac__type_sizeof_)))) - return 1; - fprintf (f, "%lu\n", i); - } - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sizeof_short=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -{ { echo "$as_me:$LINENO: error: cannot compute sizeof (short) -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (short) -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.val -else - ac_cv_sizeof_short=0 -fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5 -echo "${ECHO_T}$ac_cv_sizeof_short" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_SHORT $ac_cv_sizeof_short -_ACEOF - - -{ echo "$as_me:$LINENO: checking for int" >&5 -echo $ECHO_N "checking for int... $ECHO_C" >&6; } -if test "${ac_cv_type_int+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -typedef int ac__type_new_; -int -main () -{ -if ((ac__type_new_ *) 0) - return 0; -if (sizeof (ac__type_new_)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_int=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_type_int=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 -echo "${ECHO_T}$ac_cv_type_int" >&6; } - -{ echo "$as_me:$LINENO: checking size of int" >&5 -echo $ECHO_N "checking size of int... $ECHO_C" >&6; } -if test "${ac_cv_sizeof_int+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$ac_cv_type_int" = yes; then - # The cast to long int works around a bug in the HP C Compiler - # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects - # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. - # This bug is HP SR number 8606223364. - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo= ac_hi= -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr '(' $ac_mid ')' + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) ac_cv_sizeof_int=$ac_lo;; -'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (int) -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } ;; -esac -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef int ac__type_sizeof_; -static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } -static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if (((long int) (sizeof (ac__type_sizeof_))) < 0) - { - long int i = longval (); - if (i != ((long int) (sizeof (ac__type_sizeof_)))) - return 1; - fprintf (f, "%ld\n", i); - } - else - { - unsigned long int i = ulongval (); - if (i != ((long int) (sizeof (ac__type_sizeof_)))) - return 1; - fprintf (f, "%lu\n", i); - } - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sizeof_int=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int) -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (int) -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.val -else - ac_cv_sizeof_int=0 -fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 -echo "${ECHO_T}$ac_cv_sizeof_int" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_INT $ac_cv_sizeof_int -_ACEOF - - -{ echo "$as_me:$LINENO: checking for long" >&5 -echo $ECHO_N "checking for long... $ECHO_C" >&6; } -if test "${ac_cv_type_long+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -typedef long ac__type_new_; -int -main () -{ -if ((ac__type_new_ *) 0) - return 0; -if (sizeof (ac__type_new_)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_long=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_type_long=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 -echo "${ECHO_T}$ac_cv_type_long" >&6; } - -{ echo "$as_me:$LINENO: checking size of long" >&5 -echo $ECHO_N "checking size of long... $ECHO_C" >&6; } -if test "${ac_cv_sizeof_long+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$ac_cv_type_long" = yes; then - # The cast to long int works around a bug in the HP C Compiler - # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects - # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. - # This bug is HP SR number 8606223364. - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef long ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef long ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef long ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef long ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo= ac_hi= -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef long ac__type_sizeof_; -int -main () -{ -static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr '(' $ac_mid ')' + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) ac_cv_sizeof_long=$ac_lo;; -'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (long) -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } ;; -esac -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - typedef long ac__type_sizeof_; -static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } -static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if (((long int) (sizeof (ac__type_sizeof_))) < 0) - { - long int i = longval (); - if (i != ((long int) (sizeof (ac__type_sizeof_)))) - return 1; - fprintf (f, "%ld\n", i); - } - else - { - unsigned long int i = ulongval (); - if (i != ((long int) (sizeof (ac__type_sizeof_)))) - return 1; - fprintf (f, "%lu\n", i); - } - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sizeof_long=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long) -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute sizeof (long) -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.val -else - ac_cv_sizeof_long=0 -fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 -echo "${ECHO_T}$ac_cv_sizeof_long" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_LONG $ac_cv_sizeof_long -_ACEOF - - - -{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 -echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } -if test "${ac_cv_c_const+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -/* FIXME: Include the comments suggested by Paul. */ -#ifndef __cplusplus - /* Ultrix mips cc rejects this. */ - typedef int charset[2]; - const charset x; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *ccp; - char **p; - /* NEC SVR4.0.2 mips cc rejects this. */ - struct point {int x, y;}; - static struct point const zero = {0,0}; - /* AIX XL C 1.02.0.0 rejects this. - It does not let you subtract one const X* pointer from another in - an arm of an if-expression whose if-part is not a constant - expression */ - const char *g = "string"; - ccp = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++ccp; - p = (char**) ccp; - ccp = (char const *const *) p; - { /* SCO 3.2v4 cc rejects this. */ - char *t; - char const *s = 0 ? (char *) 0 : (char const *) 0; - - *t++ = 0; - if (s) return 0; - } - { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ - int x[] = {25, 17}; - const int *foo = &x[0]; - ++foo; - } - { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ - typedef const int *iptr; - iptr p = 0; - ++p; - } - { /* AIX XL C 1.02.0.0 rejects this saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; }; - struct s *b; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - if (!foo) return 0; - } - return !x[0] && !zero.x; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_const=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_c_const=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 -echo "${ECHO_T}$ac_cv_c_const" >&6; } -if test $ac_cv_c_const = no; then - -cat >>confdefs.h <<\_ACEOF -#define const -_ACEOF - -fi - -{ echo "$as_me:$LINENO: checking for inline" >&5 -echo $ECHO_N "checking for inline... $ECHO_C" >&6; } -if test "${ac_cv_c_inline+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_c_inline=no -for ac_kw in inline __inline__ __inline; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifndef __cplusplus -typedef int foo_t; -static $ac_kw foo_t static_foo () {return 0; } -$ac_kw foo_t foo () {return 0; } -#endif - -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_inline=$ac_kw -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - test "$ac_cv_c_inline" != no && break -done - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 -echo "${ECHO_T}$ac_cv_c_inline" >&6; } - - -case $ac_cv_c_inline in - inline | yes) ;; - *) - case $ac_cv_c_inline in - no) ac_val=;; - *) ac_val=$ac_cv_c_inline;; - esac - cat >>confdefs.h <<_ACEOF -#ifndef __cplusplus -#define inline $ac_val -#endif -_ACEOF - ;; -esac - - -for ac_header in getopt.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - { echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -else - # Is the header compilable? -{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6; } - -# Is the header present? -{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - - ;; -esac -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -for ac_func in getopt_long -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval echo '${'$as_ac_var'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -if test "$GCC" = yes; then - CFLAGS="$CFLAGS -O3 -funroll-all-loops" -else - { echo "$as_me:$LINENO: result: no gcc" >&5 -echo "${ECHO_T}no gcc" >&6; } -fi - -ac_config_files="$ac_config_files Makefile" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 -echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - *) $as_unset $ac_var ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - test "x$cache_file" != "x/dev/null" && - { echo "$as_me:$LINENO: updating cache $cache_file" >&5 -echo "$as_me: updating cache $cache_file" >&6;} - cat confcache >$cache_file - else - { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 -echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" - ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - - -: ${CONFIG_STATUS=./config.status} -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -echo "$as_me: creating $CONFIG_STATUS" >&6;} -cat >$CONFIG_STATUS <<_ACEOF -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false -SHELL=\${CONFIG_SHELL-$SHELL} -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - - -# PATH needs CR -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -as_nl=' -' -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - { (exit 1); exit 1; } -fi - -# Work around bugs in pre-3.0 UWIN ksh. -for as_var in ENV MAIL MAILPATH -do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# CDPATH. -$as_unset CDPATH - - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line after each line using $LINENO; the second 'sed' - # does the real work. The second script uses 'N' to pair each - # line-number line with the line containing $LINENO, and appends - # trailing '-' during substitution so that $LINENO is not a special - # case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # scripts with optimization help from Paolo Bonzini. Blame Lee - # E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in --n*) - case `echo 'x\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - *) ECHO_C='\c';; - esac;; -*) - ECHO_N='-n';; -esac - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir -fi -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -# Find out whether ``test -x'' works. Don't use a zero-byte file, as -# systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - as_executable_p="test -x" -else - as_executable_p=: -fi -rm -f conf$$.file - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 - -# Save the log message, to keep $[0] and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by $as_me, which was -generated by GNU Autoconf 2.60. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. - -Usage: $0 [OPTIONS] [FILE]... - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Report bugs to ." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF -ac_cs_version="\\ -config.status -configured by $0, generated by GNU Autoconf 2.60, - with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" - -Copyright (C) 2006 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -# If no file are specified by the user, then we need to provide default -# value. By we need to know if files were specified by the user. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - echo "$ac_cs_version"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - CONFIG_FILES="$CONFIG_FILES $ac_optarg" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - { echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) { echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } ;; - - *) ac_config_targets="$ac_config_targets $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF -if \$ac_cs_recheck; then - echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 - CONFIG_SHELL=$SHELL - export CONFIG_SHELL - exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - - *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= - trap 'exit_status=$? - { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status -' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || -{ - echo "$me: cannot create a temporary directory in ." >&2 - { (exit 1); exit 1; } -} - -# -# Set up the sed scripts for CONFIG_FILES section. -# - -# No need to generate the scripts if there are no CONFIG_FILES. -# This happens for instance when ./config.status config.h -if test -n "$CONFIG_FILES"; then - -_ACEOF - - - -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - cat >conf$$subs.sed <<_ACEOF -SHELL!$SHELL$ac_delim -PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim -PACKAGE_NAME!$PACKAGE_NAME$ac_delim -PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim -PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim -PACKAGE_STRING!$PACKAGE_STRING$ac_delim -PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim -exec_prefix!$exec_prefix$ac_delim -prefix!$prefix$ac_delim -program_transform_name!$program_transform_name$ac_delim -bindir!$bindir$ac_delim -sbindir!$sbindir$ac_delim -libexecdir!$libexecdir$ac_delim -datarootdir!$datarootdir$ac_delim -datadir!$datadir$ac_delim -sysconfdir!$sysconfdir$ac_delim -sharedstatedir!$sharedstatedir$ac_delim -localstatedir!$localstatedir$ac_delim -includedir!$includedir$ac_delim -oldincludedir!$oldincludedir$ac_delim -docdir!$docdir$ac_delim -infodir!$infodir$ac_delim -htmldir!$htmldir$ac_delim -dvidir!$dvidir$ac_delim -pdfdir!$pdfdir$ac_delim -psdir!$psdir$ac_delim -libdir!$libdir$ac_delim -localedir!$localedir$ac_delim -mandir!$mandir$ac_delim -DEFS!$DEFS$ac_delim -ECHO_C!$ECHO_C$ac_delim -ECHO_N!$ECHO_N$ac_delim -ECHO_T!$ECHO_T$ac_delim -LIBS!$LIBS$ac_delim -build_alias!$build_alias$ac_delim -host_alias!$host_alias$ac_delim -target_alias!$target_alias$ac_delim -CC!$CC$ac_delim -CFLAGS!$CFLAGS$ac_delim -LDFLAGS!$LDFLAGS$ac_delim -CPPFLAGS!$CPPFLAGS$ac_delim -ac_ct_CC!$ac_ct_CC$ac_delim -EXEEXT!$EXEEXT$ac_delim -OBJEXT!$OBJEXT$ac_delim -RANLIB!$RANLIB$ac_delim -INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim -INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim -INSTALL_DATA!$INSTALL_DATA$ac_delim -CPP!$CPP$ac_delim -GREP!$GREP$ac_delim -EGREP!$EGREP$ac_delim -LIBOBJS!$LIBOBJS$ac_delim -LTLIBOBJS!$LTLIBOBJS$ac_delim -_ACEOF - - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 53; then - break - elif $ac_last_try; then - { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 -echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} - { (exit 1); exit 1; }; } - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` -if test -n "$ac_eof"; then - ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` - ac_eof=`expr $ac_eof + 1` -fi - -cat >>$CONFIG_STATUS <<_ACEOF -cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end -_ACEOF -sed ' -s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g -s/^/s,@/; s/!/@,|#_!!_#|/ -:n -t n -s/'"$ac_delim"'$/,g/; t -s/$/\\/; p -N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n -' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF -:end -s/|#_!!_#|//g -CEOF$ac_eof -_ACEOF - - -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/ -s/:*\${srcdir}:*/:/ -s/:*@srcdir@:*/:/ -s/^\([^=]*=[ ]*\):*/\1/ -s/:*$// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF -fi # test -n "$CONFIG_FILES" - - -for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 -echo "$as_me: error: Invalid tag $ac_tag." >&2;} - { (exit 1); exit 1; }; };; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 -echo "$as_me: error: cannot find input file: $ac_f" >&2;} - { (exit 1); exit 1; }; };; - esac - ac_file_inputs="$ac_file_inputs $ac_f" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input="Generated from "`IFS=: - echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - fi - - case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin";; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - { as_dir="$ac_dir" - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 -echo "$as_me: error: cannot create directory $as_dir" >&2;} - { (exit 1); exit 1; }; }; } - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= - -case `sed -n '/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p -' $ac_file_inputs` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF - sed "$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s&@configure_input@&$configure_input&;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -$ac_datarootdir_hack -" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && - { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&5 -echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&2;} - - rm -f "$tmp/stdin" - case $ac_file in - -) cat "$tmp/out"; rm -f "$tmp/out";; - *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; - esac - ;; - :H) - # - # CONFIG_HEADER - # -_ACEOF - -# Transform confdefs.h into a sed script `conftest.defines', that -# substitutes the proper values into config.h.in to produce config.h. -rm -f conftest.defines conftest.tail -# First, append a space to every undef/define line, to ease matching. -echo 's/$/ /' >conftest.defines -# Then, protect against being on the right side of a sed subst, or in -# an unquoted here document, in config.status. If some macros were -# called several times there might be several #defines for the same -# symbol, which is useless. But do not sort them, since the last -# AC_DEFINE must be honored. -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where -# NAME is the cpp macro being defined, VALUE is the value it is being given. -# PARAMS is the parameter list in the macro definition--in most cases, it's -# just an empty string. -ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' -ac_dB='\\)[ (].*,\\1define\\2' -ac_dC=' ' -ac_dD=' ,' - -uniq confdefs.h | - sed -n ' - t rset - :rset - s/^[ ]*#[ ]*define[ ][ ]*// - t ok - d - :ok - s/[\\&,]/\\&/g - s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p - s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p - ' >>conftest.defines - -# Remove the space that was appended to ease matching. -# Then replace #undef with comments. This is necessary, for -# example, in the case of _POSIX_SOURCE, which is predefined and required -# on some systems where configure will not decide to define it. -# (The regexp can be short, since the line contains either #define or #undef.) -echo 's/ $// -s,^[ #]*u.*,/* & */,' >>conftest.defines - -# Break up conftest.defines: -ac_max_sed_lines=50 - -# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" -# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" -# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" -# et cetera. -ac_in='$ac_file_inputs' -ac_out='"$tmp/out1"' -ac_nxt='"$tmp/out2"' - -while : -do - # Write a here document: - cat >>$CONFIG_STATUS <<_ACEOF - # First, check the format of the line: - cat >"\$tmp/defines.sed" <<\\CEOF -/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def -/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def -b -:def -_ACEOF - sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS - echo 'CEOF - sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS - ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in - sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail - grep . conftest.tail >/dev/null || break - rm -f conftest.defines - mv conftest.tail conftest.defines -done -rm -f conftest.defines conftest.tail - -echo "ac_result=$ac_in" >>$CONFIG_STATUS -cat >>$CONFIG_STATUS <<\_ACEOF - if test x"$ac_file" != x-; then - echo "/* $configure_input */" >"$tmp/config.h" - cat "$ac_result" >>"$tmp/config.h" - if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then - { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 -echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f $ac_file - mv "$tmp/config.h" $ac_file - fi - else - echo "/* $configure_input */" - cat "$ac_result" - fi - rm -f "$tmp/out12" - ;; - - - esac - -done # for ac_tag - - -{ (exit 0); exit 0; } -_ACEOF -chmod +x $CONFIG_STATUS -ac_clean_files=$ac_clean_files_save - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || { (exit 1); exit 1; } -fi - diff --git a/src/lzf/configure.ac b/src/lzf/configure.ac deleted file mode 100644 index 58316a01b..000000000 --- a/src/lzf/configure.ac +++ /dev/null @@ -1,25 +0,0 @@ -AC_INIT -AC_CONFIG_SRCDIR([lzfP.h]) - -AC_CONFIG_HEADER(config.h) - -AC_GNU_SOURCE -AC_SYS_LARGEFILE -AC_PROG_CC -AC_PROG_RANLIB -AC_PROG_INSTALL -AC_HEADER_STDC - -AC_C_CONST -AC_C_INLINE -AC_CHECK_HEADERS(getopt.h) -AC_CHECK_FUNCS(getopt_long) - -if test "$GCC" = yes; then - CFLAGS="$CFLAGS -O3 -funroll-all-loops" -else - AC_MSG_RESULT(no gcc) -fi - -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT diff --git a/src/lzf/crc32.h b/src/lzf/crc32.h deleted file mode 100644 index cf8f6d409..000000000 --- a/src/lzf/crc32.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef CRC32_H -#define CRC32_H - -/* crc32 0xdebb20e3 table and supplementary functions. */ - -static const u32 crc_32_tab[] = -{ - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dL -}; - -#define crc32(crc,byte) (crc_32_tab[(u8)(crc) ^ (u8)(byte)] ^ ((crc) >> 8)) - -#endif - diff --git a/src/lzf/install-sh b/src/lzf/install-sh deleted file mode 100644 index e9de23842..000000000 --- a/src/lzf/install-sh +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5 (mit/util/scripts/install.sh). -# -# Copyright 1991 by the Massachusetts Institute of Technology -# -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation, and that the name of M.I.T. not be used in advertising or -# publicity pertaining to distribution of the software without specific, -# written prior permission. M.I.T. makes no representations about the -# suitability of this software for any purpose. It is provided "as is" -# without express or implied warranty. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - chmodcmd="" - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/src/lzf/lzf.c b/src/lzf/lzf.c deleted file mode 100644 index bedfdb6fe..000000000 --- a/src/lzf/lzf.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Copyright (c) 2006 Stefan Traby - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- - * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- - * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- - * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License ("GPL") version 2 or any later version, - * in which case the provisions of the GPL are applicable instead of - * the above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use your - * version of this file under the BSD license, indicate your decision - * by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file under - * either the BSD or the GPL. - */ - -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "lzf.h" - -#ifdef HAVE_GETOPT_H -# include -#endif - -#define BLOCKSIZE (1024 * 64 - 1) -#define MAX_BLOCKSIZE BLOCKSIZE - -typedef unsigned char u8; - -static off_t nr_read, nr_written; - -static const char *imagename; -static enum { compress, uncompress, lzcat } mode = compress; -static int verbose = 0; -static int force = 0; -static long blocksize = BLOCKSIZE; - -#ifdef HAVE_GETOPT_LONG - - struct option longopts[] = { - {"compress", 0, 0, 'c'}, - {"decompress", 0, 0, 'd'}, - {"uncompress", 0, 0, 'd'}, - {"force", 0, 0, 'f'}, - {"help", 0, 0, 'h'}, - {"verbose", 0, 0, 'v'}, - {"blocksize", 1, 0, 'b'}, - {0, 0, 0, 0} - }; - - static const char *opt = - "-c --compress compress\n" - "-d --decompress decompress\n" - "-f --force force overwrite of output file\n" - "-h --help give this help\n" "-v --verbose verbose mode\n" "-b # --blocksize # set blocksize\n" "\n"; - -#else - - static const char *opt = - "-c compress\n" - "-d decompress\n" - "-f force overwrite of output file\n" - "-h give this help\n" - "-v verbose mode\n" - "-b # set blocksize\n" - "\n"; - -#endif - -static void -usage (int rc) -{ - fprintf (stderr, "\n" - "lzf, a very lightweight compression/decompression utility written by Stefan Traby.\n" - "uses liblzf written by Marc Lehmann You can find more info at\n" - "http://liblzf.plan9.de/\n" - "\n" - "usage: lzf [-dufhvb] [file ...]\n" - " unlzf [file ...]\n" - " lzcat [file ...]\n" - "\n%s", - opt); - - exit (rc); -} - -static inline ssize_t -rread (int fd, void *buf, size_t len) -{ - ssize_t rc = 0, offset = 0; - char *p = buf; - - while (len && (rc = read (fd, &p[offset], len)) > 0) - { - offset += rc; - len -= rc; - } - - nr_read += offset; - - if (rc < 0) - return rc; - - return offset; -} - -/* returns 0 if all written else -1 */ -static inline ssize_t -wwrite (int fd, void *buf, size_t len) -{ - ssize_t rc; - char *b = buf; - size_t l = len; - - while (l) - { - rc = write (fd, b, l); - if (rc < 0) - { - fprintf (stderr, "%s: write error: ", imagename); - perror (""); - return -1; - } - - l -= rc; - b += rc; - } - - nr_written += len; - return 0; -} - -/* - * Anatomy: an lzf file consists of any number of blocks in the following format: - * - * \x00 EOF (optional) - * "ZV\0" 2-byte-usize - * "ZV\1" 2-byte-csize 2-byte-usize - * "ZV\2" 4-byte-crc32-0xdebb20e3 (NYI) - */ - - -#define TYPE0_HDR_SIZE 5 -#define TYPE1_HDR_SIZE 7 -#define MAX_HDR_SIZE 7 -#define MIN_HDR_SIZE 5 - -static int -compress_fd (int from, int to) -{ - ssize_t us, cs, len; - u8 buf1[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; - u8 buf2[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; - u8 *header; - - nr_read = nr_written = 0; - while ((us = rread (from, &buf1[MAX_HDR_SIZE], blocksize)) > 0) - { - cs = lzf_compress (&buf1[MAX_HDR_SIZE], us, &buf2[MAX_HDR_SIZE], us > 4 ? us - 4 : us); - if (cs) - { - header = &buf2[MAX_HDR_SIZE - TYPE1_HDR_SIZE]; - header[0] = 'Z'; - header[1] = 'V'; - header[2] = 1; - header[3] = cs >> 8; - header[4] = cs & 0xff; - header[5] = us >> 8; - header[6] = us & 0xff; - len = cs + TYPE1_HDR_SIZE; - } - else - { // write uncompressed - header = &buf1[MAX_HDR_SIZE - TYPE0_HDR_SIZE]; - header[0] = 'Z'; - header[1] = 'V'; - header[2] = 0; - header[3] = us >> 8; - header[4] = us & 0xff; - len = us + TYPE0_HDR_SIZE; - } - - if (wwrite (to, header, len) == -1) - return -1; - } - - return 0; -} - -static int -uncompress_fd (int from, int to) -{ - u8 header[MAX_HDR_SIZE]; - u8 buf1[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; - u8 buf2[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; - u8 *p; - int l, rd; - ssize_t rc, cs, us, bytes, over = 0; - - nr_read = nr_written = 0; - while (1) - { - rc = rread (from, header + over, MAX_HDR_SIZE - over); - if (rc < 0) - { - fprintf (stderr, "%s: read error: ", imagename); - perror (""); - return -1; - } - - rc += over; - over = 0; - if (!rc || header[0] == 0) - return 0; - - if (rc < MIN_HDR_SIZE || header[0] != 'Z' || header[1] != 'V') - { - fprintf (stderr, "%s: invalid data stream - magic not found or short header\n", imagename); - return -1; - } - - switch (header[2]) - { - case 0: - cs = -1; - us = (header[3] << 8) | header[4]; - p = &header[TYPE0_HDR_SIZE]; - break; - case 1: - if (rc < TYPE1_HDR_SIZE) - { - goto short_read; - } - cs = (header[3] << 8) | header[4]; - us = (header[5] << 8) | header[6]; - p = &header[TYPE1_HDR_SIZE]; - break; - default: - fprintf (stderr, "%s: unknown blocktype\n", imagename); - return -1; - } - - bytes = cs == -1 ? us : cs; - l = &header[rc] - p; - - if (l > 0) - memcpy (buf1, p, l); - - if (l > bytes) - { - over = l - bytes; - memmove (header, &p[bytes], over); - } - - p = &buf1[l]; - rd = bytes - l; - if (rd > 0) - if ((rc = rread (from, p, rd)) != rd) - goto short_read; - - if (cs == -1) - { - if (wwrite (to, buf1, us)) - return -1; - } - else - { - if (lzf_decompress (buf1, cs, buf2, us) != us) - { - fprintf (stderr, "%s: decompress: invalid stream - data corrupted\n", imagename); - return -1; - } - - if (wwrite (to, buf2, us)) - return -1; - } - } - - return 0; - -short_read: - fprintf (stderr, "%s: short data\n", imagename); - return -1; -} - -static int -open_out (const char *name) -{ - int fd; - int m = O_EXCL; - - if (force) - m = 0; - - fd = open (name, O_CREAT | O_WRONLY | O_TRUNC | m, 600); -#if defined(__MINGW32__) - _setmode(fd, _O_BINARY); -#endif - return fd; -} - -static int -compose_name (const char *fname, char *oname) -{ - char *p; - - if (mode == compress) - { - if (strlen (fname) > PATH_MAX - 4) - { - fprintf (stderr, "%s: %s.lzf: name too long", imagename, fname); - return -1; - } - - strcpy (oname, fname); - strcat (oname, ".lzf"); - } - else - { - if (strlen (fname) > PATH_MAX) - { - fprintf (stderr, "%s: %s: name too long\n", imagename, fname); - return -1; - } - - strcpy (oname, fname); - p = &oname[strlen (oname)] - 4; - if (p < oname || strcmp (p, ".lzf")) - { - fprintf (stderr, "%s: %s: unknown suffix\n", imagename, fname); - return -1; - } - - *p = 0; - } - - return 0; -} - -static int -run_file (const char *fname) -{ - int fd, fd2; - int rc; - struct stat mystat; - char oname[PATH_MAX + 1]; - - if (mode != lzcat) - if (compose_name (fname, oname)) - return -1; - -#if !defined(__MINGW32__) - rc = lstat (fname, &mystat); -#else - rc = stat (fname, &mystat); -#endif - fd = open (fname, O_RDONLY); -#if defined(__MINGW32__) - _setmode(fd, _O_BINARY); -#endif - if (rc || fd == -1) - { - fprintf (stderr, "%s: %s: ", imagename, fname); - perror (""); - return -1; - } - - if (!S_ISREG (mystat.st_mode)) - { - fprintf (stderr, "%s: %s: not a regular file.\n", imagename, fname); - close (fd); - return -1; - } - - if (mode == lzcat) - { - rc = uncompress_fd (fd, 1); - close (fd); - return rc; - } - - fd2 = open_out (oname); - if (fd2 == -1) - { - fprintf (stderr, "%s: %s: ", imagename, oname); - perror (""); - close (fd); - return -1; - } - - if (mode == compress) - { - rc = compress_fd (fd, fd2); - if (!rc && verbose) - fprintf (stderr, "%s: %5.1f%% -- replaced with %s\n", - fname, nr_read == 0 ? 0 : 100.0 - nr_written / ((double) nr_read / 100.0), oname); - } - else - { - rc = uncompress_fd (fd, fd2); - if (!rc && verbose) - fprintf (stderr, "%s: %5.1f%% -- replaced with %s\n", - fname, nr_written == 0 ? 0 : 100.0 - nr_read / ((double) nr_written / 100.0), oname); - } - -#if !defined(__MINGW32__) - fchmod (fd2, mystat.st_mode); -#else - chmod (oname, mystat.st_mode); -#endif - close (fd); - close (fd2); - - if (!rc) - unlink (fname); - - return rc; -} - -int -main (int argc, char *argv[]) -{ - char *p = argv[0]; - int optc; - int rc = 0; - - errno = 0; - p = getenv ("LZF_BLOCKSIZE"); - if (p) - { - blocksize = strtoul (p, 0, 0); - if (errno || !blocksize || blocksize > MAX_BLOCKSIZE) - blocksize = BLOCKSIZE; - } - - p = strrchr (argv[0], '/'); - imagename = p ? ++p : argv[0]; - - if (!strncmp (imagename, "un", 2) || !strncmp (imagename, "de", 2)) - mode = uncompress; - - if (strstr (imagename, "cat")) - mode = lzcat; - -#ifdef HAVE_GETOPT_LONG - while ((optc = getopt_long (argc, argv, "cdfhvb:", longopts, 0)) != -1) -#else - while ((optc = getopt (argc, argv, "cdfhvb:")) != -1) -#endif - { - switch (optc) - { - case 'c': - mode = compress; - break; - case 'd': - mode = uncompress; - break; - case 'f': - force = 1; - break; - case 'h': - usage (0); - break; - case 'v': - verbose = 1; - break; - case 'b': - errno = 0; - blocksize = strtoul (optarg, 0, 0); - if (errno || !blocksize || blocksize > MAX_BLOCKSIZE) - blocksize = BLOCKSIZE; - break; - default: - usage (1); - break; - } - } - - if (optind == argc) - { // stdin stdout - if (!force) - { - if ((mode == uncompress || mode == lzcat) && isatty (0)) - { - fprintf (stderr, "%s: compressed data not read from a terminal. Use -f to force decompression.\n", imagename); - exit (1); - } - if (mode == compress && isatty (1)) - { - fprintf (stderr, "%s: compressed data not written to a terminal. Use -f to force compression.\n", imagename); - exit (1); - } - } - - if (mode == compress) - rc = compress_fd (0, 1); - else - rc = uncompress_fd (0, 1); - - exit (rc ? 1 : 0); - } - - while (optind < argc) - rc |= run_file (argv[optind++]); - - exit (rc ? 1 : 0); -} - diff --git a/src/lzf/lzf.h b/src/lzf/lzf.h deleted file mode 100644 index 919b6e6be..000000000 --- a/src/lzf/lzf.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2000-2008 Marc Alexander Lehmann - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- - * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- - * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- - * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License ("GPL") version 2 or any later version, - * in which case the provisions of the GPL are applicable instead of - * the above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use your - * version of this file under the BSD license, indicate your decision - * by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file under - * either the BSD or the GPL. - */ - -#ifndef LZF_H -#define LZF_H - -/*********************************************************************** -** -** lzf -- an extremely fast/free compression/decompression-method -** http://liblzf.plan9.de/ -** -** This algorithm is believed to be patent-free. -** -***********************************************************************/ - -#define LZF_VERSION 0x0105 /* 1.5, API version */ - -/* - * Compress in_len bytes stored at the memory block starting at - * in_data and write the result to out_data, up to a maximum length - * of out_len bytes. - * - * If the output buffer is not large enough or any error occurs return 0, - * otherwise return the number of bytes used, which might be considerably - * more than in_len (but less than 104% of the original size), so it - * makes sense to always use out_len == in_len - 1), to ensure _some_ - * compression, and store the data uncompressed otherwise (with a flag, of - * course. - * - * lzf_compress might use different algorithms on different systems and - * even different runs, thus might result in different compressed strings - * depending on the phase of the moon or similar factors. However, all - * these strings are architecture-independent and will result in the - * original data when decompressed using lzf_decompress. - * - * The buffers must not be overlapping. - * - * If the option LZF_STATE_ARG is enabled, an extra argument must be - * supplied which is not reflected in this header file. Refer to lzfP.h - * and lzf_c.c. - * - */ -unsigned int -lzf_compress (const void *const in_data, unsigned int in_len, - void *out_data, unsigned int out_len); - -/* - * Decompress data compressed with some version of the lzf_compress - * function and stored at location in_data and length in_len. The result - * will be stored at out_data up to a maximum of out_len characters. - * - * If the output buffer is not large enough to hold the decompressed - * data, a 0 is returned and errno is set to E2BIG. Otherwise the number - * of decompressed bytes (i.e. the original length of the data) is - * returned. - * - * If an error in the compressed data is detected, a zero is returned and - * errno is set to EINVAL. - * - * This function is very fast, about as fast as a copying loop. - */ -unsigned int -lzf_decompress (const void *const in_data, unsigned int in_len, - void *out_data, unsigned int out_len); - -#endif - diff --git a/src/lzf/lzfP.h b/src/lzf/lzfP.h deleted file mode 100644 index 11c965ca3..000000000 --- a/src/lzf/lzfP.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2000-2007 Marc Alexander Lehmann - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- - * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- - * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- - * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License ("GPL") version 2 or any later version, - * in which case the provisions of the GPL are applicable instead of - * the above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use your - * version of this file under the BSD license, indicate your decision - * by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file under - * either the BSD or the GPL. - */ - -#ifndef LZFP_h -#define LZFP_h - -#define STANDALONE 1 /* at the moment, this is ok. */ - -#ifndef STANDALONE -# include "lzf.h" -#endif - -/* - * Size of hashtable is (1 << HLOG) * sizeof (char *) - * decompression is independent of the hash table size - * the difference between 15 and 14 is very small - * for small blocks (and 14 is usually a bit faster). - * For a low-memory/faster configuration, use HLOG == 13; - * For best compression, use 15 or 16 (or more, up to 22). - */ -#ifndef HLOG -# define HLOG 16 -#endif - -/* - * Sacrifice very little compression quality in favour of compression speed. - * This gives almost the same compression as the default code, and is - * (very roughly) 15% faster. This is the preferred mode of operation. - */ -#ifndef VERY_FAST -# define VERY_FAST 1 -#endif - -/* - * Sacrifice some more compression quality in favour of compression speed. - * (roughly 1-2% worse compression for large blocks and - * 9-10% for small, redundant, blocks and >>20% better speed in both cases) - * In short: when in need for speed, enable this for binary data, - * possibly disable this for text data. - */ -#ifndef ULTRA_FAST -# define ULTRA_FAST 1 -#endif - -/* - * Unconditionally aligning does not cost very much, so do it if unsure - */ -#ifndef STRICT_ALIGN -# define STRICT_ALIGN !(defined(__i386) || defined (__amd64)) -#endif - -/* - * You may choose to pre-set the hash table (might be faster on some - * modern cpus and large (>>64k) blocks, and also makes compression - * deterministic/repeatable when the configuration otherwise is the same). - */ -#ifndef INIT_HTAB -# define INIT_HTAB 1 -#endif - -/* - * Avoid assigning values to errno variable? for some embedding purposes - * (linux kernel for example), this is necessary. NOTE: this breaks - * the documentation in lzf.h. Avoiding errno has no speed impact. - */ -#ifndef AVOID_ERRNO -# define AVOID_ERRNO 0 -#endif - -/* - * Whether to pass the LZF_STATE variable as argument, or allocate it - * on the stack. For small-stack environments, define this to 1. - * NOTE: this breaks the prototype in lzf.h. - */ -#ifndef LZF_STATE_ARG -# define LZF_STATE_ARG 0 -#endif - -/* - * Whether to add extra checks for input validity in lzf_decompress - * and return EINVAL if the input stream has been corrupted. This - * only shields against overflowing the input buffer and will not - * detect most corrupted streams. - * This check is not normally noticeable on modern hardware - * (<1% slowdown), but might slow down older cpus considerably. - */ -#ifndef CHECK_INPUT -# define CHECK_INPUT 1 -#endif - -/* - * Whether to store pointers or offsets inside the hash table. On - * 64 bit architetcures, pointers take up twice as much space, - * and might also be slower. Default is to autodetect. - */ -/*#define LZF_USER_OFFSETS autodetect */ - -/*****************************************************************************/ -/* nothing should be changed below */ - -#ifdef __cplusplus -# include -# include -using namespace std; -#else -# include -# include -#endif - -#ifndef LZF_USE_OFFSETS -# if defined(_WIN32) -# define LZF_USE_OFFSETS defined(_M_X64) -# else -# if __cplusplus > 199711L -# include -# else -# include -# endif -# define LZF_USE_OFFSETS (UINTPTR_MAX > 0xffffffffU) -# endif -#endif - -typedef unsigned char u8; - -#if LZF_USE_OFFSETS -# define LZF_HSLOT_BIAS ((const u8 *)in_data) - typedef unsigned int LZF_HSLOT; -#else -# define LZF_HSLOT_BIAS 0 - typedef const u8 *LZF_HSLOT; -#endif - -typedef LZF_HSLOT LZF_STATE[1 << (HLOG)]; - -#if !STRICT_ALIGN -/* for unaligned accesses we need a 16 bit datatype. */ -# if USHRT_MAX == 65535 - typedef unsigned short u16; -# elif UINT_MAX == 65535 - typedef unsigned int u16; -# else -# undef STRICT_ALIGN -# define STRICT_ALIGN 1 -# endif -#endif - -#if ULTRA_FAST -# undef VERY_FAST -#endif - -#endif - diff --git a/src/lzf/lzf_c.c b/src/lzf/lzf_c.c deleted file mode 100644 index 8ba4d0b84..000000000 --- a/src/lzf/lzf_c.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (c) 2000-2010 Marc Alexander Lehmann - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- - * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- - * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- - * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License ("GPL") version 2 or any later version, - * in which case the provisions of the GPL are applicable instead of - * the above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use your - * version of this file under the BSD license, indicate your decision - * by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file under - * either the BSD or the GPL. - */ - -#include - -#include "lzfP.h" - -#define HSIZE (1 << (HLOG)) - -/* - * don't play with this unless you benchmark! - * the data format is not dependent on the hash function. - * the hash function might seem strange, just believe me, - * it works ;) - */ -#ifndef FRST -# define FRST(p) (((p[0]) << 8) | p[1]) -# define NEXT(v,p) (((v) << 8) | p[2]) -# if ULTRA_FAST -# define IDX(h) ((( h >> (3*8 - HLOG)) - h ) & (HSIZE - 1)) -# elif VERY_FAST -# define IDX(h) ((( h >> (3*8 - HLOG)) - h*5) & (HSIZE - 1)) -# else -# define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1)) -# endif -#endif -/* - * IDX works because it is very similar to a multiplicative hash, e.g. - * ((h * 57321 >> (3*8 - HLOG)) & (HSIZE - 1)) - * the latter is also quite fast on newer CPUs, and compresses similarly. - * - * the next one is also quite good, albeit slow ;) - * (int)(cos(h & 0xffffff) * 1e6) - */ - -#if 0 -/* original lzv-like hash function, much worse and thus slower */ -# define FRST(p) (p[0] << 5) ^ p[1] -# define NEXT(v,p) ((v) << 5) ^ p[2] -# define IDX(h) ((h) & (HSIZE - 1)) -#endif - -#define MAX_LIT (1 << 5) -#define MAX_OFF (1 << 13) -#define MAX_REF ((1 << 8) + (1 << 3)) - -#if __GNUC__ >= 3 -# define expect(expr,value) __builtin_expect ((expr),(value)) -# define inline inline -#else -# define expect(expr,value) (expr) -# define inline static -#endif - -#define expect_false(expr) expect ((expr) != 0, 0) -#define expect_true(expr) expect ((expr) != 0, 1) - -/* - * compressed format - * - * 000LLLLL ; literal, L+1=1..33 octets - * LLLooooo oooooooo ; backref L+1=1..7 octets, o+1=1..4096 offset - * 111ooooo LLLLLLLL oooooooo ; backref L+8 octets, o+1=1..4096 offset - * - */ - -unsigned int -lzf_compress (const void *const in_data, unsigned int in_len, - void *out_data, unsigned int out_len -#if LZF_STATE_ARG - , LZF_STATE htab -#endif - ) -{ -#if !LZF_STATE_ARG - LZF_STATE htab; -#endif - const u8 *ip = (const u8 *)in_data; - u8 *op = (u8 *)out_data; - const u8 *in_end = ip + in_len; - u8 *out_end = op + out_len; - const u8 *ref; - - /* off requires a type wide enough to hold a general pointer difference. - * ISO C doesn't have that (size_t might not be enough and ptrdiff_t only - * works for differences within a single object). We also assume that no - * no bit pattern traps. Since the only platform that is both non-POSIX - * and fails to support both assumptions is windows 64 bit, we make a - * special workaround for it. - */ -#if defined(_WIN32) && defined(_M_X64) - uint64_t off; /* workaround for missing POSIX compliance */ -#else - unsigned long off; -#endif - unsigned int hval; - int lit; - - if (!in_len || !out_len) - return 0; - -#if INIT_HTAB - memset (htab, 0, sizeof (htab)); -#endif - - lit = 0; op++; /* start run */ - - hval = FRST (ip); - while (ip < in_end - 2) - { - LZF_HSLOT *hslot; - - hval = NEXT (hval, ip); - hslot = htab + IDX (hval); - ref = *hslot + LZF_HSLOT_BIAS; *hslot = ip - LZF_HSLOT_BIAS; - - if (1 -#if INIT_HTAB - && ref < ip /* the next test will actually take care of this, but this is faster */ -#endif - && (off = ip - ref - 1) < MAX_OFF - && ref > (u8 *)in_data - && ref[2] == ip[2] -#if STRICT_ALIGN - && ((ref[1] << 8) | ref[0]) == ((ip[1] << 8) | ip[0]) -#else - && *(u16 *)ref == *(u16 *)ip -#endif - ) - { - /* match found at *ref++ */ - unsigned int len = 2; - unsigned int maxlen = in_end - ip - len; - maxlen = maxlen > MAX_REF ? MAX_REF : maxlen; - - if (expect_false (op + 3 + 1 >= out_end)) /* first a faster conservative test */ - if (op - !lit + 3 + 1 >= out_end) /* second the exact but rare test */ - return 0; - - op [- lit - 1] = lit - 1; /* stop run */ - op -= !lit; /* undo run if length is zero */ - - for (;;) - { - if (expect_true (maxlen > 16)) - { - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - } - - do - len++; - while (len < maxlen && ref[len] == ip[len]); - - break; - } - - len -= 2; /* len is now #octets - 1 */ - ip++; - - if (len < 7) - { - *op++ = (off >> 8) + (len << 5); - } - else - { - *op++ = (off >> 8) + ( 7 << 5); - *op++ = len - 7; - } - - *op++ = off; - - lit = 0; op++; /* start run */ - - ip += len + 1; - - if (expect_false (ip >= in_end - 2)) - break; - -#if ULTRA_FAST || VERY_FAST - --ip; -# if VERY_FAST && !ULTRA_FAST - --ip; -# endif - hval = FRST (ip); - - hval = NEXT (hval, ip); - htab[IDX (hval)] = ip - LZF_HSLOT_BIAS; - ip++; - -# if VERY_FAST && !ULTRA_FAST - hval = NEXT (hval, ip); - htab[IDX (hval)] = ip - LZF_HSLOT_BIAS; - ip++; -# endif -#else - ip -= len + 1; - - do - { - hval = NEXT (hval, ip); - htab[IDX (hval)] = ip - LZF_HSLOT_BIAS; - ip++; - } - while (len--); -#endif - } - else - { - /* one more literal byte we must copy */ - if (expect_false (op >= out_end)) - return 0; - - lit++; *op++ = *ip++; - - if (expect_false (lit == MAX_LIT)) - { - op [- lit - 1] = lit - 1; /* stop run */ - lit = 0; op++; /* start run */ - } - } - } - - if (op + 3 > out_end) /* at most 3 bytes can be missing here */ - return 0; - - while (ip < in_end) - { - lit++; *op++ = *ip++; - - if (expect_false (lit == MAX_LIT)) - { - op [- lit - 1] = lit - 1; /* stop run */ - lit = 0; op++; /* start run */ - } - } - - op [- lit - 1] = lit - 1; /* end run */ - op -= !lit; /* undo run if length is zero */ - - return op - (u8 *)out_data; -} - diff --git a/src/lzf/lzf_d.c b/src/lzf/lzf_d.c deleted file mode 100644 index 8433b8f1f..000000000 --- a/src/lzf/lzf_d.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2000-2010 Marc Alexander Lehmann - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- - * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- - * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- - * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Alternatively, the contents of this file may be used under the terms of - * the GNU General Public License ("GPL") version 2 or any later version, - * in which case the provisions of the GPL are applicable instead of - * the above. If you wish to allow the use of your version of this file - * only under the terms of the GPL and not to allow others to use your - * version of this file under the BSD license, indicate your decision - * by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL. If you do not delete the - * provisions above, a recipient may use your version of this file under - * either the BSD or the GPL. - */ - -#include "lzfP.h" - -#if AVOID_ERRNO -# define SET_ERRNO(n) -#else -# include -# define SET_ERRNO(n) errno = (n) -#endif - -#if USE_REP_MOVSB /* small win on amd, big loss on intel */ -#if (__i386 || __amd64) && __GNUC__ >= 3 -# define lzf_movsb(dst, src, len) \ - asm ("rep movsb" \ - : "=D" (dst), "=S" (src), "=c" (len) \ - : "0" (dst), "1" (src), "2" (len)); -#endif -#endif - -unsigned int -lzf_decompress (const void *const in_data, unsigned int in_len, - void *out_data, unsigned int out_len) -{ - u8 const *ip = (const u8 *)in_data; - u8 *op = (u8 *)out_data; - u8 const *const in_end = ip + in_len; - u8 *const out_end = op + out_len; - - do - { - unsigned int ctrl = *ip++; - - if (ctrl < (1 << 5)) /* literal run */ - { - ctrl++; - - if (op + ctrl > out_end) - { - SET_ERRNO (E2BIG); - return 0; - } - -#if CHECK_INPUT - if (ip + ctrl > in_end) - { - SET_ERRNO (EINVAL); - return 0; - } -#endif - -#ifdef lzf_movsb - lzf_movsb (op, ip, ctrl); -#else - switch (ctrl) - { - case 32: *op++ = *ip++; case 31: *op++ = *ip++; case 30: *op++ = *ip++; case 29: *op++ = *ip++; - case 28: *op++ = *ip++; case 27: *op++ = *ip++; case 26: *op++ = *ip++; case 25: *op++ = *ip++; - case 24: *op++ = *ip++; case 23: *op++ = *ip++; case 22: *op++ = *ip++; case 21: *op++ = *ip++; - case 20: *op++ = *ip++; case 19: *op++ = *ip++; case 18: *op++ = *ip++; case 17: *op++ = *ip++; - case 16: *op++ = *ip++; case 15: *op++ = *ip++; case 14: *op++ = *ip++; case 13: *op++ = *ip++; - case 12: *op++ = *ip++; case 11: *op++ = *ip++; case 10: *op++ = *ip++; case 9: *op++ = *ip++; - case 8: *op++ = *ip++; case 7: *op++ = *ip++; case 6: *op++ = *ip++; case 5: *op++ = *ip++; - case 4: *op++ = *ip++; case 3: *op++ = *ip++; case 2: *op++ = *ip++; case 1: *op++ = *ip++; - } -#endif - } - else /* back reference */ - { - unsigned int len = ctrl >> 5; - - u8 *ref = op - ((ctrl & 0x1f) << 8) - 1; - -#if CHECK_INPUT - if (ip >= in_end) - { - SET_ERRNO (EINVAL); - return 0; - } -#endif - if (len == 7) - { - len += *ip++; -#if CHECK_INPUT - if (ip >= in_end) - { - SET_ERRNO (EINVAL); - return 0; - } -#endif - } - - ref -= *ip++; - - if (op + len + 2 > out_end) - { - SET_ERRNO (E2BIG); - return 0; - } - - if (ref < (u8 *)out_data) - { - SET_ERRNO (EINVAL); - return 0; - } - -#ifdef lzf_movsb - len += 2; - lzf_movsb (op, ref, len); -#else - switch (len) - { - default: - len += 2; - - if (op >= ref + len) - { - /* disjunct areas */ - memcpy (op, ref, len); - op += len; - } - else - { - /* overlapping, use octte by octte copying */ - do - *op++ = *ref++; - while (--len); - } - - break; - - case 9: *op++ = *ref++; - case 8: *op++ = *ref++; - case 7: *op++ = *ref++; - case 6: *op++ = *ref++; - case 5: *op++ = *ref++; - case 4: *op++ = *ref++; - case 3: *op++ = *ref++; - case 2: *op++ = *ref++; - case 1: *op++ = *ref++; - case 0: *op++ = *ref++; /* two octets more */ - *op++ = *ref++; - } -#endif - } - } - while (ip < in_end); - - return op - (u8 *)out_data; -} - diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 46c583632..d0a3383df 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -8,7 +8,7 @@ # # Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.112 2018/03/16 +# Version: @(#)Makefile.mingw 1.0.113 2018/03/18 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -203,7 +203,7 @@ VPATH := $(EXPATH) . cpu \ sound/munt sound/munt/c_interface sound/munt/sha1 \ sound/munt/srchelper \ sound/resid-fp \ - scsi video lzf network network/slirp win + scsi video floppy/lzf network network/slirp win ifeq ($(X64), y) CPP := g++ -m64 CC := gcc -m64 From 895e30bb37b899d3b3e6aff89f90daef403d9e46 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Mar 2018 02:35:11 +0100 Subject: [PATCH 12/39] Various fixes to the IMD loader - 5.25" 2DD IMD images now work correctly in thin track drives; A slight fix to TD0 loading; Ported the small gameport bugfix from VARCem; Disabled CD-ROM logging. --- src/cdrom/cdrom.c | 3 +-- src/floppy/fdd_imd.c | 51 ++++++++++++++++++++++++++++++-------------- src/floppy/fdd_td0.c | 5 +++-- src/game/gameport.c | 4 ++-- 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 437b686cd..6fa7b7e50 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.41 2018/03/18 + * Version: @(#)cdrom.c 1.0.42 2018/03/19 * * Author: Miran Grca, * @@ -332,7 +332,6 @@ static const mode_sense_pages_t cdrom_mode_sense_pages_changeable = static mode_sense_pages_t cdrom_mode_sense_pages_saved[CDROM_NUM]; -#define ENABLE_CDROM_LOG 1 #ifdef ENABLE_CDROM_LOG int cdrom_do_log = ENABLE_CDROM_LOG; #endif diff --git a/src/floppy/fdd_imd.c b/src/floppy/fdd_imd.c index c78e85692..49eca94e4 100644 --- a/src/floppy/fdd_imd.c +++ b/src/floppy/fdd_imd.c @@ -8,7 +8,7 @@ * * Implementation of the IMD floppy image format. * - * Version: @(#)fdd_imd.c 1.0.5 2018/03/17 + * Version: @(#)fdd_imd.c 1.0.6 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -590,6 +590,7 @@ imd_load(int drive, wchar_t *fn) uint32_t raw_tsize = 0; uint32_t minimum_gap3 = 0; uint32_t minimum_gap4 = 0; + uint8_t converted_rate; d86f_unregister(drive); @@ -690,6 +691,7 @@ imd_load(int drive, wchar_t *fn) dev->tracks[track][side].side_flags |= 0x20; if ((dev->tracks[track][side].side_flags & 7) == 1) dev->tracks[track][side].side_flags |= 0x20; + /* pclog("Side flags for (%02i)(%01i): %02X\n", track, side, dev->tracks[track][side].side_flags); */ dev->tracks[track][side].is_present = 1; dev->tracks[track][side].file_offs = (buffer2 - buffer); memcpy(dev->tracks[track][side].params, buffer2, 5); @@ -748,30 +750,45 @@ imd_load(int drive, wchar_t *fn) /* 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 ((dev->tracks[track][side].side_flags == 0x0A) || (dev->tracks[track][side].side_flags == 0x29)) + converted_rate = 2; + else if (dev->tracks[track][side].side_flags == 0x28) + converted_rate = 4; + else + converted_rate = dev->tracks[track][side].side_flags & 0x03; + + if (gap3_sizes[converted_rate][sector_size][track_spt] == 0x00) { 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; + /* 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->tracks[track][side].gap3_len = (raw_tsize - track_total - minimum_gap4 + (mfm ? 146 : 73)) / track_spt; + } else if (gap3_sizes[converted_rate][sector_size][track_spt] != 0x00) + dev->tracks[track][side].gap3_len = gap3_sizes[converted_rate][sector_size][track_spt]; - dev->track_count++; + /* pclog("GAP3 length for (%02i)(%01i): %i bytes\n", track, side, dev->tracks[track][side].gap3_len); */ + + if (track > dev->track_count) + dev->track_count = track; if (last_offset >= fsize) break; } /* If more than 43 tracks, then the tracks are thin (96 tpi). */ + dev->track_count++; dev->track_width = 0; if (dev->track_count > 43) dev->track_width = 1; @@ -780,6 +797,8 @@ imd_load(int drive, wchar_t *fn) if (dev->sides == 2) dev->disk_flags |= 8; + /* pclog("%i tracks, %i sides\n", dev->track_count, dev->sides); */ + /* Attach this format to the D86F engine. */ d86f_handler[drive].disk_flags = disk_flags; d86f_handler[drive].side_flags = side_flags; diff --git a/src/floppy/fdd_td0.c b/src/floppy/fdd_td0.c index b5558437f..8968694c8 100644 --- a/src/floppy/fdd_td0.c +++ b/src/floppy/fdd_td0.c @@ -8,7 +8,7 @@ * * Implementation of the Teledisk floppy image format. * - * Version: @(#)fdd_td0.c 1.0.4 2018/03/17 + * Version: @(#)fdd_td0.c 1.0.5 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -784,7 +784,8 @@ td0_initialize(int drive) track_size += (pre_sector + size + 2); } - track_count = track; + if (track > track_count) + track_count = track; if (track_spt != 255) { dev->track_spt[track][head] = track_spt; diff --git a/src/game/gameport.c b/src/game/gameport.c index c1f06ecb5..1550e4eab 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.3 2018/03/15 + * Version: @(#)gameport.c 1.0.4 2018/03/19 * * Authors: Miran Grca, * Sarah Walker, @@ -193,7 +193,7 @@ gameport_write(uint16_t addr, uint8_t val, void *priv) static uint8_t gameport_read(uint16_t addr, void *priv) { - gameport_t *p = (gameport_t *)p; + gameport_t *p = (gameport_t *)priv; uint8_t ret; timer_clock(); From 089041a5f35c9c4b5e43e5fd3442ff20c8c8a8b2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Mar 2018 03:01:09 +0100 Subject: [PATCH 13/39] The Add Hard Disk and New Floppy Image dialogs now automatically append an extension to the file name when none was given by the user. --- src/win/win_new_floppy.c | 18 +++++++++++++++++- src/win/win_settings.c | 13 ++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/win/win_new_floppy.c b/src/win/win_new_floppy.c index 1d8ed7589..d00d492e3 100644 --- a/src/win/win_new_floppy.c +++ b/src/win/win_new_floppy.c @@ -8,7 +8,7 @@ * * Handle the New Floppy Image dialog. * - * Version: @(#)win_new_floppy.c 1.0.4 2018/03/06 + * Version: @(#)win_new_floppy.c 1.0.5 2018/03/19 * * Authors: Miran Grca, * @@ -556,6 +556,7 @@ NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) int ret; FILE *f; int zip_types; + wchar_t *twcs; switch (message) { case WM_INITDIALOG: @@ -624,6 +625,21 @@ NewFloppyDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) case IDC_CFILE: if (!file_dlg_w(hdlg, plat_get_string(is_zip ? IDS_2176 : IDS_2174), L"", 1)) { + if (!wcschr(wopenfilestring, L'.')) { + if (wcslen(wopenfilestring) && (wcslen(wopenfilestring) <= 256)) { + twcs = &wopenfilestring[wcslen(wopenfilestring)]; + twcs[0] = L'.'; + if (!is_zip && (filterindex == 3)) { + twcs[1] = L'8'; + twcs[2] = L'6'; + twcs[3] = L'f'; + } else { + twcs[1] = L'i'; + twcs[2] = L'm'; + twcs[3] = L'g'; + } + } + } h = GetDlgItem(hdlg, IDC_EDIT_FILE_NAME); f = _wfopen(wopenfilestring, L"rb"); if (f != NULL) { diff --git a/src/win/win_settings.c b/src/win/win_settings.c index ce9455061..6f380a4b9 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.44 2018/03/18 + * Version: @(#)win_settings.c 1.0.45 2018/03/19 * * Author: Miran Grca, * @@ -2740,6 +2740,7 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM uint64_t r = 0; uint8_t channel = 0; uint8_t id = 0, lun = 0; + wchar_t *twcs; switch (message) { @@ -3056,6 +3057,16 @@ hd_add_ok_common: case IDC_CFILE: if (!file_dlg_w(hdlg, plat_get_string(IDS_4106), L"", !(existing & 1))) { + if (!wcschr(wopenfilestring, L'.')) { + if (wcslen(wopenfilestring) && (wcslen(wopenfilestring) <= 256)) { + twcs = &wopenfilestring[wcslen(wopenfilestring)]; + twcs[0] = L'.'; + twcs[1] = L'i'; + twcs[2] = L'm'; + twcs[3] = L'g'; + } + } + if (!(existing & 1)) { f = _wfopen(wopenfilestring, L"rb"); From 473fd383d2b46927c2540fd432dbcd62c531f60b Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Mar 2018 04:19:19 +0100 Subject: [PATCH 14/39] Do not allow mouse capturing if no mouse configured, patch from VARCem; Reimplemented saving of all the non-volatile things of the Toshiba T1000 and T1200; Applied the latest T1200 patch from John Elliott; Applied the latest ATI Korean VGA patch from greatpsycho. --- src/machine/m_xt_t1000.c | 114 +++++++++++++++++++++++++---- src/machine/m_xt_t1000.h | 10 +-- src/mouse.c | 10 +-- src/nvr.c | 16 ++++- src/pc.c | 7 +- src/video/vid_ati28800.c | 139 ++++++++++++++++++++---------------- src/video/vid_svga_render.c | 12 +++- src/video/video.c | 19 +++-- src/video/video.h | 3 +- src/win/win_ui.c | 5 +- 10 files changed, 234 insertions(+), 101 deletions(-) diff --git a/src/machine/m_xt_t1000.c b/src/machine/m_xt_t1000.c index 969329680..02d5e6c48 100644 --- a/src/machine/m_xt_t1000.c +++ b/src/machine/m_xt_t1000.c @@ -51,7 +51,7 @@ * 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/18 + * Version: @(#)m_xt_t1000.c 1.0.4 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -96,6 +96,7 @@ #include "../device.h" #include "../keyboard.h" #include "../lpt.h" +#include "../mem.h" #include "../floppy/fdd.h" #include "../floppy/fdc.h" #include "../game/gameport.h" @@ -141,7 +142,8 @@ typedef struct { mem_mapping_t rom_mapping; /* CONFIG.SYS drive. */ - uint8_t config[160]; + uint8_t t1000_nvram[160]; + uint8_t t1200_nvram[160]; /* System control registers */ uint8_t sys_ctl[16]; @@ -153,6 +155,7 @@ typedef struct { uint8_t nvr_tick; int nvr_addr; uint8_t nvr_active; + mem_mapping_t nvr_mapping; /* T1200 NVRAM mapping */ /* EMS data */ uint8_t ems_reg[4]; @@ -662,7 +665,7 @@ t1000_read_nvram(uint16_t addr, void *priv) switch (addr) { case 0xc2: /* Read next byte from NVRAM */ if (sys->nvr_addr >= 0 && sys->nvr_addr < 160) - tmp = sys->config[sys->nvr_addr]; + tmp = sys->t1000_nvram[sys->nvr_addr]; sys->nvr_addr++; break; @@ -696,9 +699,9 @@ t1000_write_nvram(uint16_t addr, uint8_t val, void *priv) case 0xc1: /* Write next byte to NVRAM */ if (sys->nvr_addr >= 0 && sys->nvr_addr < 160) { - if (sys->config[sys->nvr_addr] != val) + if (sys->t1000_nvram[sys->nvr_addr] != val) nvr_dosave = 1; - sys->config[sys->nvr_addr] = val; + sys->t1000_nvram[sys->nvr_addr] = val; } sys->nvr_addr++; break; @@ -722,6 +725,26 @@ t1000_write_nvram(uint16_t addr, uint8_t val, void *priv) } +static +uint8_t read_t1200_nvram(uint32_t addr, void *priv) +{ + t1000_t *sys = (t1000_t *)priv; + + return sys->t1200_nvram[addr & 0x7FF]; +} + + +static void write_t1200_nvram(uint32_t addr, uint8_t value, void *priv) +{ + t1000_t *sys = (t1000_t *)priv; + + if (sys->t1200_nvram[addr & 0x7FF] != value) + nvr_dosave = 1; + + sys->t1200_nvram[addr & 0x7FF] = value; +} + + /* Port 0xC8 controls the ROM drive */ static uint8_t t1000_read_rom_ctl(uint16_t addr, void *priv) @@ -898,6 +921,12 @@ machine_xt_t1200_init(const machine_t *model) machine_common_init(model); + mem_mapping_add(&t1000.nvr_mapping, + 0x000f0000, 2048, + read_t1200_nvram, NULL, NULL, + write_t1200_nvram, NULL, NULL, + NULL, 0, &t1000); + pit_set_out_func(&pit, 1, pit_refresh_timer_xt); device_add(&keyboard_xt_device); t1000.fdc = device_add(&fdc_xt_device); @@ -918,36 +947,62 @@ t1000_syskey(uint8_t andmask, uint8_t ormask, uint8_t xormask) } -#if 0 -void +static void t1000_configsys_load(void) { FILE *f; - memset(config_sys, 0x1a, sizeof(config_sys)); + memset(t1000.t1000_nvram, 0x1a, sizeof(t1000.t1000_nvram)); f = plat_fopen(nvr_path(L"t1000_config.nvr"), L"rb"); if (f != NULL) { - fread(config_sys, sizeof(config_sys), 1, f); + fread(t1000.t1000_nvram, sizeof(t1000.t1000_nvram), 1, f); fclose(f); } } -void +static void t1000_configsys_save(void) { FILE *f; f = plat_fopen(nvr_path(L"t1000_config.nvr"), L"wb"); if (f != NULL) { - fwrite(config_sys, sizeof(config_sys), 1, f); + fwrite(t1000.t1000_nvram, sizeof(t1000.t1000_nvram), 1, f); + fclose(f); + } +} + + +static void +t1200_state_load(void) +{ + FILE *f; + + memset(t1000.t1200_nvram, 0x1a, sizeof(t1000.t1200_nvram)); + f = plat_fopen(nvr_path(L"t1200_state.nvr"), L"rb"); + if (f != NULL) { + fread(t1000.t1200_nvram, sizeof(t1000.t1200_nvram), 1, f); + fclose(f); + } +} + + +static void +t1200_state_save(void) +{ + FILE *f; + + f = plat_fopen(nvr_path(L"t1200_state.nvr"), L"wb"); + if (f != NULL) { + fwrite(t1000.t1200_nvram, sizeof(t1000.t1200_nvram), 1, f); fclose(f); } } /* All RAM beyond 512k is non-volatile */ -void +static void t1000_emsboard_load(void) { FILE *f; @@ -962,7 +1017,7 @@ t1000_emsboard_load(void) } -void +static void t1000_emsboard_save(void) { FILE *f; @@ -975,4 +1030,35 @@ t1000_emsboard_save(void) } } } -#endif + + +void +t1000_nvr_load(void) +{ + t1000_emsboard_load(); + t1000_configsys_load(); +} + + +void +t1000_nvr_save(void) +{ + t1000_emsboard_save(); + t1000_configsys_save(); +} + + +void +t1200_nvr_load(void) +{ + t1000_emsboard_load(); + t1200_state_load(); +} + + +void +t1200_nvr_save(void) +{ + t1000_emsboard_save(); + t1200_state_save(); +} diff --git a/src/machine/m_xt_t1000.h b/src/machine/m_xt_t1000.h index e2a1ade1f..3a345fcbc 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.3 2018/03/18 + * Version: @(#)m_xt_t1000.h 1.0.4 2018/03/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -49,11 +49,11 @@ extern void t1000_display_set(uint8_t internal); extern void t1000_syskey(uint8_t amask, uint8_t omask, uint8_t xmask); -extern void t1000_configsys_load(void); -extern void t1000_configsys_save(void); +extern void t1000_nvr_load(void); +extern void t1000_nvr_save(void); -extern void t1000_emsboard_load(void); -extern void t1000_emsboard_save(void); +extern void t1200_nvr_load(void); +extern void t1200_nvr_save(void); #endif /*MACHINE_T1000_H*/ diff --git a/src/mouse.c b/src/mouse.c index 0ee64943f..62fd322f7 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.23 2018/03/18 + * Version: @(#)mouse.c 1.0.24 2018/03/19 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -109,7 +109,7 @@ mouse_close(void) void mouse_reset(void) { - if (mouse_curr != NULL) + if ((mouse_curr != NULL) || (mouse_type == MOUSE_TYPE_INTERNAL)) return; /* Mouse already initialized. */ pclog("MOUSE: reset(type=%d, '%s')\n", @@ -142,7 +142,8 @@ mouse_process(void) { static int poll_delay = 2; - if (mouse_curr == NULL) return; + if ((mouse_curr != NULL) || (mouse_type == MOUSE_TYPE_INTERNAL)) + return; if (--poll_delay) return; @@ -192,9 +193,8 @@ mouse_get_from_internal_name(char *s) int c = 0; while (mouse_devices[c].internal_name != NULL) { - if (! strcmp((char *)mouse_devices[c].internal_name, s)) { + if (! strcmp((char *)mouse_devices[c].internal_name, s)) return(c); - } c++; } diff --git a/src/nvr.c b/src/nvr.c index 9eb8db2d5..fccde1882 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -10,7 +10,7 @@ * * NOTE: I should re-do 'intclk' using a TM struct. * - * Version: @(#)nvr.c 1.0.2 2018/03/11 + * Version: @(#)nvr.c 1.0.3 2018/03/19 * * Author: Fred N. van Kempen, * @@ -53,9 +53,13 @@ #include #include #include "86box.h" +#include "device.h" #include "machine/machine.h" +#include "machine/m_xt_t1000.h" +#include "mem.h" #include "pic.h" #include "pit.h" +#include "rom.h" #include "timer.h" #include "plat.h" #include "nvr.h" @@ -234,6 +238,11 @@ nvr_load(void) } } + if (romset == ROM_T1000) + t1000_nvr_load(); + else if (romset == ROM_T1200) + t1200_nvr_load(); + /* Get the local RTC running! */ if (saved_nvr->start != NULL) saved_nvr->start(saved_nvr); @@ -261,6 +270,11 @@ nvr_save(void) } } + if (romset == ROM_T1000) + t1000_nvr_save(); + else if (romset == ROM_T1200) + t1200_nvr_save(); + /* Device is clean again. */ nvr_dosave = 0; diff --git a/src/pc.c b/src/pc.c index fc4b205d9..38595a0da 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.65 2018/03/18 + * Version: @(#)pc.c 1.0.66 2018/03/19 * * Authors: Sarah Walker, * Miran Grca, @@ -127,7 +127,6 @@ int cpu_manufacturer = 0, /* (C) cpu manufacturer */ enable_external_fpu = 0; /* (C) enable external FPU */ int enable_sync = 0; /* (C) enable time sync */ - /* Statistics. */ extern int mmuflush, @@ -652,8 +651,8 @@ again2: ide_init_first(); - device_init(); - + device_init(); + timer_reset(); sound_reset(); diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 1d20906b1..17c6f7b71 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -8,13 +8,15 @@ * * ATI 28800 emulation (VGA Charger and Korean VGA) * - * Version: @(#)vid_ati28800.c 1.0.13 2018/03/18 + * Version: @(#)vid_ati28800.c 1.0.14 2018/03/19 * * Authors: Sarah Walker, * Miran Grca, + * greatpsycho, * * Copyright 2008-2018 Sarah Walker. * Copyright 2016-2018 Miran Grca. + * Copyright 2018 greatpsycho. */ #include #include @@ -60,18 +62,17 @@ typedef struct ati28800_t int index; uint32_t memory; + + uint8_t port_03dd_val; + uint16_t get_korean_font_kind; + int in_get_korean_font_kind_set; + int get_korean_font_enabled; + int get_korean_font_index; + uint16_t get_korean_font_base; + int ksc5601_mode_enabled; } ati28800_t; -uint8_t port_03dd_val; -uint16_t get_korean_font_kind; -int in_get_korean_font_kind_set; -int get_korean_font_enabled; -int get_korean_font_index; -uint16_t get_korean_font_base; -int ksc5601_mode_enabled; - - static void ati28800_out(uint16_t addr, uint8_t val, void *p) { ati28800_t *ati28800 = (ati28800_t *)p; @@ -154,43 +155,53 @@ void ati28800k_out(uint16_t addr, uint8_t val, void *p) case 0x1CF: if(ati28800->index == 0xBF && ((ati28800->regs[0xBF] ^ val) & 0x20)) { - ksc5601_mode_enabled = val & 0x20; + ati28800->ksc5601_mode_enabled = val & 0x20; svga_recalctimings(svga); } ati28800_out(oldaddr, val, p); break; case 0x3DD: - port_03dd_val = val; - if(val == 1) get_korean_font_enabled = 0; - if(in_get_korean_font_kind_set) + ati28800->port_03dd_val = val; + if(val == 1) ati28800->get_korean_font_enabled = 0; + if(ati28800->in_get_korean_font_kind_set) { - get_korean_font_kind = (val << 8) | (get_korean_font_kind & 0xFF); - get_korean_font_enabled = 1; - get_korean_font_index = 0; - in_get_korean_font_kind_set = 0; + ati28800->get_korean_font_kind = (val << 8) | (ati28800->get_korean_font_kind & 0xFF); + ati28800->get_korean_font_enabled = 1; + ati28800->get_korean_font_index = 0; + ati28800->in_get_korean_font_kind_set = 0; } break; case 0x3DE: - in_get_korean_font_kind_set = 0; - switch(port_03dd_val) + ati28800->in_get_korean_font_kind_set = 0; + if(ati28800->get_korean_font_enabled && (ati28800->regs[0xBF] & 0x20)) { - case 0x10: - get_korean_font_base = ((val & 0x7F) << 7) | (get_korean_font_base & 0x7F); - break; - case 8: - get_korean_font_base = (get_korean_font_base & 0x3F80) | (val & 0x7F); - break; - case 1: - get_korean_font_kind = (get_korean_font_kind & 0xFF00) | val; - if(val & 2) in_get_korean_font_kind_set = 1; - break; - default: - break; + if((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) + fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + (ati28800->get_korean_font_base & 0x7F) - 0x20].chr[ati28800->get_korean_font_index] = val; + ati28800->get_korean_font_index++; + ati28800->get_korean_font_index &= 0x1F; } - break; - default: - ati28800_out(oldaddr, val, p); + else + + { + switch(ati28800->port_03dd_val) + { + case 0x10: + ati28800->get_korean_font_base = ((val & 0x7F) << 7) | (ati28800->get_korean_font_base & 0x7F); + break; + case 8: + ati28800->get_korean_font_base = (ati28800->get_korean_font_base & 0x3F80) | (val & 0x7F); + break; + case 1: + ati28800->get_korean_font_kind = (ati28800->get_korean_font_kind & 0xFF00) | val; + if(val & 2) + ati28800->in_get_korean_font_kind_set = 1; + break; + } + break; + } + default: + ati28800_out(oldaddr, val, p); break; } } @@ -213,15 +224,15 @@ static uint8_t ati28800_in(uint16_t addr, void *p) case 0x1cf: switch (ati28800->index) { - case 0xb0: - if (ati28800->memory == 256) - return 0x08; - else if (ati28800->memory == 512) - return 0x10; - else - return 0x18; - break; - + case 0xb0: + if (ati28800->memory == 256) + return 0x08; + else if (ati28800->memory == 512) + return 0x10; + else + return 0x18; + break; + case 0xb7: temp = ati28800->regs[ati28800->index] & ~8; if (ati_eeprom_read(&ati28800->eeprom)) @@ -301,20 +312,24 @@ uint8_t ati28800k_in(uint16_t addr, void *p) switch (addr) { case 0x3DE: - if(get_korean_font_enabled && (ati28800->regs[0xBF] & 0x20)) + if (ati28800->get_korean_font_enabled && (ati28800->regs[0xBF] & 0x20)) { - switch(get_korean_font_kind >> 8) + switch(ati28800->get_korean_font_kind >> 8) { case 4: /* ROM font */ - temp = fontdatksc5601[get_korean_font_base].chr[get_korean_font_index++]; + temp = fontdatksc5601[ati28800->get_korean_font_base].chr[ati28800->get_korean_font_index++]; break; - case 2: /* User defined font - TODO : Should be implemented later */ - temp = 0; + case 2: /* User defined font */ + if((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) + temp = fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + (ati28800->get_korean_font_base & 0x7F) - 0x20].chr[ati28800->get_korean_font_index]; + else + temp = 0xFF; + ati28800->get_korean_font_index++; break; default: break; } - get_korean_font_index &= 0x1F; + ati28800->get_korean_font_index &= 0x1F; } break; default: @@ -378,9 +393,11 @@ static void ati28800_recalctimings(svga_t *svga) void ati28800k_recalctimings(svga_t *svga) { + ati28800_t *ati28800 = (ati28800_t *) svga->p; + ati28800_recalctimings(svga); - if (svga->render == svga_render_text_80 && ksc5601_mode_enabled) + if (svga->render == svga_render_text_80 && ati28800->ksc5601_mode_enabled) { svga->render = svga_render_text_80_ksc5601; } @@ -392,15 +409,15 @@ ati28800k_init(const device_t *info) ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); memset(ati28800, 0, sizeof(ati28800_t)); - ati28800->memory = device_get_config_int("memory"); + ati28800->memory = device_get_config_int("memory"); - port_03dd_val = 0; - get_korean_font_base = 0; - get_korean_font_index = 0; - get_korean_font_enabled = 0; - get_korean_font_kind = 0; - in_get_korean_font_kind_set = 0; - ksc5601_mode_enabled = 0; + ati28800->port_03dd_val = 0; + ati28800->get_korean_font_base = 0; + ati28800->get_korean_font_index = 0; + ati28800->get_korean_font_enabled = 0; + ati28800->get_korean_font_kind = 0; + ati28800->in_get_korean_font_kind_set = 0; + ati28800->ksc5601_mode_enabled = 0; rom_init(&ati28800->bios_rom, BIOS_ATIKOR_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); loadfont(FONT_ATIKOR_PATH, 6); @@ -428,7 +445,7 @@ ati28800_init(const device_t *info) ati = malloc(sizeof(ati28800_t)); memset(ati, 0x00, sizeof(ati28800_t)); - ati->memory = device_get_config_int("memory"); + ati->memory = device_get_config_int("memory"); switch(info->local) { case GFX_VGAWONDERXL: @@ -543,7 +560,7 @@ void ati28800k_add_status_info(char *s, int max_len, void *p) svga_add_status_info(s, max_len, &ati28800->svga); - sprintf(temps, "Korean SVGA mode enabled : %s\n\n", ksc5601_mode_enabled ? "Yes" : "No"); + sprintf(temps, "Korean SVGA mode enabled : %s\n\n", ati28800->ksc5601_mode_enabled ? "Yes" : "No"); strncat(s, temps, max_len); } diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index fcef68564..1a6912782 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -8,7 +8,7 @@ * * SVGA renderers. * - * Version: @(#)vid_svga_render.c 1.0.9 2018/03/15 + * Version: @(#)vid_svga_render.c 1.0.10 2018/03/19 * * Authors: Sarah Walker, * Miran Grca, @@ -311,7 +311,10 @@ void svga_render_text_80_ksc5601(svga_t *svga) if(x + xinc < svga->hdisp && (chr & nextchr & 0x80)) { - dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc]; + if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) + dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc]; + else + dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc]; } else { @@ -358,7 +361,10 @@ void svga_render_text_80_ksc5601(svga_t *svga) } } - dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc + 16]; + if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) + dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc + 16]; + else + dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc + 16]; if (svga->seqregs[1] & 1) { for (xx = 0; xx < 8; xx++) diff --git a/src/video/video.c b/src/video/video.c index c41a52db9..8e7654617 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.20 2018/03/18 + * Version: @(#)video.c 1.0.21 2018/03/19 * * Authors: Sarah Walker, * Miran Grca, @@ -79,7 +79,8 @@ uint8_t fontdat[2048][8]; /* IBM CGA font */ uint8_t fontdatm[2048][16]; /* IBM MDA font */ uint8_t fontdatw[512][32]; /* Wyse700 font */ uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ -dbcs_font_t *fontdatksc5601;; /* Korean KSC-5601 font */ +dbcs_font_t *fontdatksc5601; /* Korean KSC-5601 font */ +dbcs_font_t *fontdatksc5601_user; /* Korean KSC-5601 user defined font */ uint32_t pal_lookup[256]; int xsize = 1, ysize = 1; @@ -661,6 +662,11 @@ video_close(void) free(fontdatksc5601); fontdatksc5601 = NULL; } + + if (fontdatksc5601_user) { + free(fontdatksc5601_user); + fontdatksc5601_user = NULL; + } } @@ -773,12 +779,13 @@ loadfont(wchar_t *s, int format) if (!fontdatksc5601) fontdatksc5601 = malloc(16384 * sizeof(dbcs_font_t)); - for (c=0;c<16384;c++) + if (!fontdatksc5601_user) + fontdatksc5601_user = malloc(192 * sizeof(dbcs_font_t)); + + for (c = 0; c < 16384; c++) { - for (d=0;d<32;d++) - { + for (d = 0; d < 32; d++) fontdatksc5601[c].chr[d]=getc(f); - } } break; } diff --git a/src/video/video.h b/src/video/video.h index 313a06d9d..4bb7e8dc4 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.24 2018/03/18 + * Version: @(#)video.h 1.0.24 2018/03/19 * * Authors: Sarah Walker, * Miran Grca, @@ -176,6 +176,7 @@ extern int fullchange; extern uint8_t fontdat[2048][8]; extern uint8_t fontdatm[2048][16]; extern dbcs_font_t *fontdatksc5601; +extern dbcs_font_t *fontdatksc5601_user; extern uint32_t *video_6to8, *video_15to32, *video_16to32; diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 9e67f7c5a..75c933fb3 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -8,7 +8,7 @@ * * user Interface module for WinAPI on Windows. * - * Version: @(#)win_ui.c 1.0.22 2018/02/15 + * Version: @(#)win_ui.c 1.0.23 2018/03/19 * * Authors: Sarah Walker, * Miran Grca, @@ -1056,6 +1056,9 @@ plat_mouse_capture(int on) { RECT rect; + if (mouse_type == MOUSE_TYPE_NONE) + return; + if (on && !mouse_capture) { /* Enable the in-app mouse. */ GetClipCursor(&oldclip); From 7d070e29307face51ca022613a9873d1f008003b Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Mar 2018 08:01:13 +0100 Subject: [PATCH 15/39] Got RAM usage down slightly further by merging in mode code from VARCem; Fixed the mouse. --- src/cpu/808x.c | 40 +- src/cpu/codegen.h | 38 +- src/disk/hdc.c | 59 +- src/disk/hdc.h | 3 +- src/keyboard.c | 10 +- src/keyboard.h | 6 +- src/keyboard_at.c | 27 +- src/keyboard_xt.c | 4 +- src/lpt.c | 4 +- src/machine/m_olivetti_m24.c | 4 +- src/machine/m_tandy.c | 4 +- src/machine/machine.c | 4 +- src/mem.c | 3536 ++++++++++++++++++---------------- src/mem.h | 387 ++-- src/mouse.c | 4 +- src/pc.c | 6 +- src/sound/snd_lpt_dac.c | 4 +- src/sound/snd_lpt_dac.h | 4 +- src/sound/snd_lpt_dss.c | 2 +- src/sound/snd_lpt_dss.h | 2 +- src/video/vid_table.c | 166 +- 21 files changed, 2321 insertions(+), 1993 deletions(-) diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 146179c73..e95cf1c79 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -1,10 +1,10 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. * - * This file is part of the 86Box distribution. + * This file is part of the VARCem Project. * * 808x CPU emulation. * @@ -18,13 +18,31 @@ * 2 clocks - fetch opcode 1 2 clocks - execute * 2 clocks - fetch opcode 2 etc * - * Version: @(#)808x.c 1.0.10 2017/12/03 + * Version: @(#)808x.c 1.0.2 2018/03/09 * - * Authors: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. */ #include #include @@ -1212,7 +1230,7 @@ void execx86(int cycs) break; case 0x14: /*ADC AL,#8*/ tempw=FETCH(); - setadc8(AL,tempw); + setadc8(AL,tempw & 0xff); AL+=tempw+tempc; cycles-=4; break; @@ -2950,7 +2968,7 @@ void execx86(int cycs) if (temp) { tempw2=tempw%temp; - AH=tempw2; + AH=tempw2 & 0xff; tempw/=temp; AL=tempw&0xFF; } diff --git a/src/cpu/codegen.h b/src/cpu/codegen.h index 99703e370..e613ecbed 100644 --- a/src/cpu/codegen.h +++ b/src/cpu/codegen.h @@ -1,3 +1,39 @@ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the code generator. + * + * Version: @(#)codegen.h 1.0.2 2018/03/14 + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ #ifndef _CODEGEN_H_ #define _CODEGEN_H_ @@ -267,7 +303,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t void codegen_generate_seg_restore(); void codegen_set_op32(); void codegen_flush(); -void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr); +void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr); extern int cpu_block_end; extern uint32_t codegen_endpc; diff --git a/src/disk/hdc.c b/src/disk/hdc.c index 809b82592..f2cb9b2b3 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.11 2018/03/18 + * Version: @(#)hdc.c 1.0.12 2018/03/19 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -72,63 +72,63 @@ static const device_t inthdc_device = { static const struct { - char *name; - char *internal_name; + const char *name; + const char *internal_name; const device_t *device; - int is_mfm; } controllers[] = { { "None", "none", - &null_device, 0 }, + &null_device }, { "Internal Controller", "internal", - &inthdc_device, 0 }, + &inthdc_device }, { "[ISA] [MFM] IBM PC Fixed Disk Adapter", "mfm_xt", - &mfm_xt_xebec_device, 1 }, + &mfm_xt_xebec_device }, { "[ISA] [MFM] DTC-5150X Fixed Disk Adapter", "mfm_dtc5150x", - &mfm_xt_dtc5150x_device, 1 }, + &mfm_xt_dtc5150x_device }, { "[ISA] [MFM] IBM PC/AT Fixed Disk Adapter", "mfm_at", - &mfm_at_wd1003_device, 1 }, + &mfm_at_wd1003_device }, { "[ISA] [ESDI] PC/AT ESDI Fixed Disk Adapter", "esdi_at", - &esdi_at_wd1007vse1_device, 0 }, + &esdi_at_wd1007vse1_device }, { "[ISA] [IDE] PC/AT IDE Adapter", "ide_isa", - &ide_isa_device, 0 }, + &ide_isa_device }, { "[ISA] [IDE] PC/AT IDE Adapter (Dual-Channel)", "ide_isa_2ch", - &ide_isa_2ch_device, 0 }, + &ide_isa_2ch_device }, { "[ISA] [IDE] PC/AT XTIDE", "xtide_at", - &xtide_at_device, 0 }, + &xtide_at_device }, { "[ISA] [IDE] PS/2 AT XTIDE (1.1.5)", "xtide_at_ps2", - &xtide_at_ps2_device, 0 }, + &xtide_at_ps2_device }, { "[ISA] [XT IDE] Acculogic XT IDE", "xtide_acculogic", - &xtide_acculogic_device, 0 }, + &xtide_acculogic_device }, { "[ISA] [XT IDE] PC/XT XTIDE", "xtide", - &xtide_device , 0 }, + &xtide_device }, { "[MCA] [ESDI] IBM PS/2 ESDI Fixed Disk Adapter","esdi_mca", - &esdi_ps2_device, 1 }, + &esdi_ps2_device }, { "[PCI] [IDE] PCI IDE Adapter", "ide_pci", - &ide_pci_device, 0 }, + &ide_pci_device }, { "[PCI] [IDE] PCI IDE Adapter (Dual-Channel)", "ide_pci_2ch", - &ide_pci_2ch_device, 0 }, + &ide_pci_2ch_device }, { "[VLB] [IDE] PC/AT IDE Adapter", "vlb_isa", - &ide_vlb_device, 0 }, + &ide_vlb_device }, { "[VLB] [IDE] PC/AT IDE Adapter (Dual-Channel)", "vlb_isa_2ch", - &ide_vlb_2ch_device, 0 }, + &ide_vlb_2ch_device }, - { "", "", NULL, 0 } + { "", "", + NULL } }; @@ -140,8 +140,8 @@ hdc_init(char *name) pclog("HDC: initializing..\n"); - for (c=0; controllers[c].device; c++) { - if (! strcmp(name, controllers[c].internal_name)) { + for (c = 0; controllers[c].device; c++) { + if (! strcmp(name, (char *) controllers[c].internal_name)) { hdc_current = c; break; } @@ -174,14 +174,14 @@ 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); } @@ -204,10 +204,3 @@ hdc_available(int hdc) { return(device_available(controllers[hdc].device)); } - - -int -hdc_current_is_mfm(void) -{ - return(controllers[hdc_current].is_mfm); -} diff --git a/src/disk/hdc.h b/src/disk/hdc.h index 5f4f9a934..8dd1ac8a5 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.6 2018/03/18 + * Version: @(#)hdc.h 1.0.7 2018/03/19 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -61,7 +61,6 @@ extern char *hdc_get_internal_name(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); #endif /*EMU_HDC_H*/ diff --git a/src/keyboard.c b/src/keyboard.c index 9e50889ae..55fea6571 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -8,15 +8,15 @@ * * General keyboard driver interface. * - * Version: @(#)keyboard.c 1.0.14 2018/02/10 + * Version: @(#)keyboard.c 1.0.15 2018/03/19 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * * Copyright 2008-2018 Sarah Walker. - * Copyright 2016,2018 Miran Grca. - * Copyright 2018 Fred N. van Kempen. + * Copyright 2015-2018 Miran Grca. + * Copyright 2017,2018 Fred N. van Kempen. */ #include #include @@ -61,9 +61,9 @@ keyboard_init(void) void -keyboard_set_table(scancode *ptr) +keyboard_set_table(const scancode *ptr) { - scan_table = ptr; + scan_table = (scancode *) ptr; } diff --git a/src/keyboard.h b/src/keyboard.h index c9d5ebcd4..388f29d10 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -8,7 +8,7 @@ * * Definitions for the keyboard interface. * - * Version: @(#)keyboard.h 1.0.12 2018/03/18 + * Version: @(#)keyboard.h 1.0.13 2018/03/19 * * Authors: Sarah Walker, * Miran Grca, @@ -51,7 +51,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; @@ -73,7 +73,7 @@ extern const device_t keyboard_ps2_quadtel_device; 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 09f255515..87e7af857 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.31 2018/03/18 + * Version: @(#)keyboard_at.c 1.0.32 2018/03/19 * * Authors: Sarah Walker, * Miran Grca, @@ -154,7 +154,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, @@ -189,7 +189,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*/ @@ -319,7 +319,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*/ @@ -449,7 +449,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*/ @@ -598,27 +598,23 @@ kbdlog(const char *fmt, ...) static void kbd_setmap(atkbd_t *kbd) { - scancode *map = NULL; - switch (keyboard_mode & 3) { case 1: default: - map = scancode_set1; + keyboard_set_table(scancode_set1); break; case 2: - map = scancode_set2; + keyboard_set_table(scancode_set2); break; case 3: - map = scancode_set3; + keyboard_set_table(scancode_set3); break; } if (keyboard_mode & 0x20) - map = scancode_set1; - - keyboard_set_table(map); + keyboard_set_table(scancode_set1); } @@ -981,11 +977,6 @@ kbd_cmd_write(atkbd_t *kbd, uint8_t val) kbdlog("ATkbd: mouse interrupt is now %s\n", (val & 0x02) ? "enabled" : "disabled"); } - -#if 0 - /* Reset scancode map. */ - kbd_setmap(kbd); -#endif } diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index 28bd1b645..fe9b162a0 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.10 2018/03/18 + * Version: @(#)keyboard_xt.c 1.0.11 2018/03/19 * * Authors: Sarah Walker, * Miran Grca, @@ -60,7 +60,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} }, diff --git a/src/lpt.c b/src/lpt.c index 4f692a37a..fbd048beb 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -19,7 +19,7 @@ static const struct { const char *name; const char *internal_name; - lpt_device_t *device; + const lpt_device_t *device; } lpt_devices[] = { {"None", "none", NULL}, @@ -60,7 +60,7 @@ void lpt_devices_init() lpt_device_ts[i] = NULL; else { - lpt_device_ts[i] = lpt_devices[c].device; + lpt_device_ts[i] = (lpt_device_t *) lpt_devices[c].device; if (lpt_device_ts[i]) lpt_device_ps[i] = lpt_device_ts[i]->init(); } diff --git a/src/machine/m_olivetti_m24.c b/src/machine/m_olivetti_m24.c index bf6c0ec6f..b8128f25b 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.11 2018/03/18 + * Version: @(#)m_olivetti_m24.c 1.0.12 2018/03/19 * * Authors: Sarah Walker, * Miran Grca, @@ -836,7 +836,7 @@ machine_olim24_init(const machine_t *model) kbd_read, NULL, NULL, kbd_write, NULL, NULL, m24); io_sethandler(0x0064, 1, kbd_read, NULL, NULL, kbd_write, NULL, NULL, m24); - keyboard_set_table(scancode_xt); + keyboard_set_table(scancode_xt); keyboard_send = kbd_adddata_ex; keyboard_scan = 1; timer_add(kbd_poll, &keyboard_delay, TIMER_ALWAYS_ENABLED, m24); diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index a31fffde8..552f23fe9 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.4 2018/03/18 + * Version: @(#)m_tandy.c 1.0.5 2018/03/19 * * Authors: Sarah Walker, * Miran Grca, @@ -121,7 +121,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} }, diff --git a/src/machine/machine.c b/src/machine/machine.c index 4a17cc7ae..b344ddd10 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.31 2018/03/18 + * Version: @(#)machine.c 1.0.32 2018/03/19 * * Authors: Sarah Walker, * Miran Grca, @@ -53,7 +53,7 @@ machine_init(void) PCI = IS_ARCH(machine, MACHINE_PCI); /* Resize the memory. */ - mem_resize(); + mem_reset(); /* Load the machine's ROM BIOS. */ rom_load_bios(romset); diff --git a/src/mem.c b/src/mem.c index cbd3fe165..bd19461f7 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1,1639 +1,1897 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include -#include -#include -#include -#include -#include "86box.h" -#include "cpu/cpu.h" -#include "cpu/x86_ops.h" -#include "cpu/x86.h" -#include "machine/machine.h" -#include "machine/m_xt_xi8088.h" -#include "config.h" -#include "io.h" -#include "mem.h" -#include "rom.h" - -#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 -#endif - - -static uint8_t (*_mem_read_b[0x40000])(uint32_t addr, void *priv); -static uint16_t (*_mem_read_w[0x40000])(uint32_t addr, void *priv); -static uint32_t (*_mem_read_l[0x40000])(uint32_t addr, void *priv); -static void (*_mem_write_b[0x40000])(uint32_t addr, uint8_t val, void *priv); -static void (*_mem_write_w[0x40000])(uint32_t addr, uint16_t val, void *priv); -static void (*_mem_write_l[0x40000])(uint32_t addr, uint32_t val, void *priv); -static uint8_t *_mem_exec[0x40000]; -static void *_mem_priv_r[0x40000]; -static void *_mem_priv_w[0x40000]; -static mem_mapping_t *_mem_mapping_r[0x40000]; -static mem_mapping_t *_mem_mapping_w[0x40000]; -static int _mem_state[0x40000]; - -static mem_mapping_t base_mapping; -static mem_mapping_t ram_remapped_mapping; -static mem_mapping_t ram_split_mapping; -mem_mapping_t ram_low_mapping; -mem_mapping_t ram_high_mapping; -mem_mapping_t ram_mid_mapping; -mem_mapping_t bios_mapping[8]; -mem_mapping_t bios_high_mapping[8]; -mem_mapping_t romext_mapping; - -page_t *pages; -page_t **page_lookup; - -uint8_t *ram; -uint32_t rammask; - -uint32_t pccache; -uint8_t *pccache2; - -int readlookup[256],readlookupp[256]; -uintptr_t *readlookup2; -int readlnext; -int writelookup[256],writelookupp[256]; -uintptr_t *writelookup2; -int writelnext; - -int shadowbios = 0, - shadowbios_write; - -int mem_a20_state; - -unsigned char isram[0x10000]; - -static uint8_t ff_array[0x1000]; - -int mem_size; -uint32_t biosmask; -int readlnum=0,writelnum=0; -int cachesize=256; - -uint8_t *rom; -uint8_t romext[32768]; - -uint32_t ram_mapped_addr[64]; - -int split_mapping_enabled = 0; - - -void resetreadlookup(void) -{ - int c; - memset(readlookup2,0xFF,1024*1024*sizeof(uintptr_t)); - for (c=0;c<256;c++) readlookup[c]=0xFFFFFFFF; - readlnext=0; - memset(writelookup2,0xFF,1024*1024*sizeof(uintptr_t)); - memset(page_lookup, 0, (1 << 20) * sizeof(page_t *)); - for (c=0;c<256;c++) writelookup[c]=0xFFFFFFFF; - writelnext=0; - pccache=0xFFFFFFFF; -} - -int mmuflush=0; -int mmu_perm=4; - -void flushmmucache(void) -{ - int c; - for (c=0;c<256;c++) - { - if (readlookup[c]!=0xFFFFFFFF) - { - readlookup2[readlookup[c]] = -1; - readlookup[c]=0xFFFFFFFF; - } - if (writelookup[c] != 0xFFFFFFFF) - { - page_lookup[writelookup[c]] = NULL; - writelookup2[writelookup[c]] = -1; - writelookup[c] = 0xFFFFFFFF; - } - } - mmuflush++; - pccache=(uint32_t)0xFFFFFFFF; - pccache2=(uint8_t *)0xFFFFFFFF; - -#ifdef USE_DYNAREC - codegen_flush(); -#endif -} - -void flushmmucache_nopc(void) -{ - int c; - for (c=0;c<256;c++) - { - if (readlookup[c]!=0xFFFFFFFF) - { - readlookup2[readlookup[c]] = -1; - readlookup[c]=0xFFFFFFFF; - } - if (writelookup[c] != 0xFFFFFFFF) - { - page_lookup[writelookup[c]] = NULL; - writelookup2[writelookup[c]] = -1; - writelookup[c] = 0xFFFFFFFF; - } - } -} - -void flushmmucache_cr3(void) -{ - int c; - for (c=0;c<256;c++) - { - if (readlookup[c]!=0xFFFFFFFF) - { - readlookup2[readlookup[c]] = -1; - readlookup[c]=0xFFFFFFFF; - } - if (writelookup[c] != 0xFFFFFFFF) - { - page_lookup[writelookup[c]] = NULL; - writelookup2[writelookup[c]] = -1; - writelookup[c] = 0xFFFFFFFF; - } - } -} - -void mem_flush_write_page(uint32_t addr, uint32_t virt) -{ - int c; - page_t *page_target = &pages[addr >> 12]; - - for (c = 0; c < 256; c++) - { - if (writelookup[c] != 0xffffffff) - { - uintptr_t target = (uintptr_t)&ram[(uintptr_t)(addr & ~0xfff) - (virt & ~0xfff)]; - - if (writelookup2[writelookup[c]] == target || page_lookup[writelookup[c]] == page_target) - { - writelookup2[writelookup[c]] = -1; - page_lookup[writelookup[c]] = NULL; - writelookup[c] = 0xffffffff; - } - } - } -} - -extern int output; - -#define mmutranslate_read(addr) mmutranslatereal(addr,0) -#define mmutranslate_write(addr) mmutranslatereal(addr,1) - -int pctrans=0; - -extern uint32_t testr[9]; - -#define rammap(x) ((uint32_t *)(_mem_exec[(x) >> 14]))[((x) >> 2) & 0xfff] - -uint32_t mmutranslatereal(uint32_t addr, int rw) -{ - uint32_t addr2; - uint32_t temp,temp2,temp3; - - if (cpu_state.abrt) - return -1; - addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - temp=temp2=rammap(addr2); - if (!(temp&1)) { - cr2=addr; - temp&=1; - if (CPL==3) temp|=4; - if (rw) temp|=2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - return -1; - } - - if ((temp & 0x80) && (cr4 & CR4_PSE)) { - /*4MB page*/ - if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && ((CPL == 3 && !cpl_override) || cr0 & WP_FLAG))) { - cr2 = addr; - temp &= 1; - if (CPL == 3) - temp |= 4; - if (rw) - temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - - return -1; - } - - mmu_perm = temp & 4; - rammap(addr2) |= 0x20; - - return (temp & ~0x3fffff) + (addr & 0x3fffff); - } - - temp=rammap((temp&~0xFFF)+((addr>>10)&0xFFC)); - temp3=temp&temp2; - if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && ((CPL == 3 && !cpl_override) || cr0&WP_FLAG))) { - cr2=addr; - temp&=1; - if (CPL==3) temp|=4; - if (rw) temp|=2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; - return -1; - } - mmu_perm=temp&4; - rammap(addr2)|=0x20; - rammap((temp2&~0xFFF)+((addr>>10)&0xFFC))|=(rw?0x60:0x20); - - return (temp&~0xFFF)+(addr&0xFFF); -} - -uint32_t mmutranslate_noabrt(uint32_t addr, int rw) -{ - uint32_t addr2; - uint32_t temp,temp2,temp3; - - if (cpu_state.abrt) - return -1; - - addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - temp=temp2=rammap(addr2); - - if (!(temp&1)) - return -1; - - if ((temp & 0x80) && (cr4 & CR4_PSE)) { - /*4MB page*/ - if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (CPL == 3 || cr0 & WP_FLAG))) - return -1; - - return (temp & ~0x3fffff) + (addr & 0x3fffff); - } - - temp=rammap((temp&~0xFFF)+((addr>>10)&0xFFC)); - temp3=temp&temp2; - - if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && (CPL==3 || cr0&WP_FLAG))) - return -1; - - return (temp&~0xFFF)+(addr&0xFFF); -} - -void mmu_invalidate(uint32_t addr) -{ - flushmmucache_cr3(); -} - -uint8_t mem_addr_range_match(uint32_t addr, uint32_t start, uint32_t len) -{ - if (addr < start) - return 0; - else if (addr >= (start + len)) - return 0; - else - return 1; -} - -uint32_t mem_addr_translate(uint32_t addr, uint32_t chunk_start, uint32_t len) -{ - uint32_t mask = len - 1; - return chunk_start + (addr & mask); -} - -void addreadlookup(uint32_t virt, uint32_t phys) -{ - if (virt == 0xffffffff) - return; - - if (readlookup2[virt>>12] != -1) - { - return; - } - - if (readlookup[readlnext]!=0xFFFFFFFF) - { - 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); - - cycles -= 9; -} - -void addwritelookup(uint32_t virt, uint32_t phys) -{ - if (virt == 0xffffffff) - return; - - if (page_lookup[virt >> 12]) - { - return; - } - - if (writelookup[writelnext] != -1) - { - page_lookup[writelookup[writelnext]] = NULL; - writelookup2[writelookup[writelnext]] = -1; - } - -#ifdef USE_DYNAREC - if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3] || (phys & ~0xfff) == recomp_page) -#else - if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3]) -#endif - 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); - - cycles -= 9; -} - -uint8_t *getpccache(uint32_t a) -{ - uint32_t a2; - - a2=a; - - if (a2 < 0x100000 && ram_mapped_addr[a2 >> 14]) - { - a = (ram_mapped_addr[a2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? a2 : (ram_mapped_addr[a2 >> 14] & ~0x3FFF) + (a2 & 0x3FFF); - return &ram[(uintptr_t)(a & 0xFFFFF000) - (uintptr_t)(a2 & ~0xFFF)]; - } - - a2 = a; - - if (cr0>>31) - { - pctrans=1; - a = mmutranslate_read(a); - pctrans=0; - - if (a==0xFFFFFFFF) return ram; - } - a&=rammask; - - if (_mem_exec[a >> 14]) - { - if (_mem_mapping_r[a >> 14]->flags & MEM_MAPPING_ROM) - cpu_prefetch_cycles = cpu_rom_prefetch_cycles; - else - cpu_prefetch_cycles = cpu_mem_prefetch_cycles; - - - return &_mem_exec[a >> 14][(uintptr_t)(a & 0x3000) - (uintptr_t)(a2 & ~0xFFF)]; - } - - pclog("Bad getpccache %08X\n", a); - return &ff_array[0-(uintptr_t)(a2 & ~0xFFF)]; -} - -uint32_t mem_logical_addr; -uint8_t readmembl(uint32_t addr) -{ - mem_logical_addr = addr; - if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) - { - addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3FFF) + (addr & 0x3FFF); - if(addr < mem_size * 1024) return ram[addr]; - return 0xFF; - } - if (cr0 >> 31) - { - addr = mmutranslate_read(addr); - if (addr == 0xFFFFFFFF) return 0xFF; - } - addr &= rammask; - - if (_mem_read_b[addr >> 14]) { - return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); - } - return 0xFF; -} - -void writemembl(uint32_t addr, uint8_t val) -{ - mem_logical_addr = addr; - - if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) - { - addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3FFF) + (addr & 0x3FFF); - if(addr < mem_size * 1024) ram[addr] = val; - return; - } - if (page_lookup[addr>>12]) - { - page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); - return; - } - if (cr0 >> 31) - { - addr = mmutranslate_write(addr); - if (addr == 0xFFFFFFFF) return; - } - addr &= rammask; - - if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); -} - -uint8_t readmemb386l(uint32_t seg, uint32_t addr) -{ - if (seg==-1) - { - x86gpf("NULL segment", 0); - return -1; - } - mem_logical_addr = addr = addr + seg; - if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) - { - addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3FFF) + (addr & 0x3FFF); - if(addr < mem_size * 1024) return ram[addr]; - return 0xFF; - } - - if (cr0 >> 31) - { - addr = mmutranslate_read(addr); - if (addr == 0xFFFFFFFF) return 0xFF; - } - - addr &= rammask; - - if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); - return 0xFF; -} - -void writememb386l(uint32_t seg, uint32_t addr, uint8_t val) -{ - if (seg==-1) - { - x86gpf("NULL segment", 0); - return; - } - - mem_logical_addr = addr = addr + seg; - if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) - { - addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3FFF) + (addr & 0x3FFF); - if(addr < mem_size * 1024) ram[addr] = val; - return; - } - if (page_lookup[addr>>12]) - { - page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); - return; - } - if (cr0 >> 31) - { - addr = mmutranslate_write(addr); - if (addr == 0xFFFFFFFF) return; - } - - addr &= rammask; - - if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); -} - -uint16_t readmemwl(uint32_t seg, uint32_t addr) -{ - uint32_t addr2 = mem_logical_addr = seg + addr; - - if (seg==-1) - { - x86gpf("NULL segment", 0); - return -1; - } - if (addr2 & 1) - { - if (!cpu_cyrix_alignment || (addr2 & 7) == 7) - cycles -= timing_misaligned; - if ((addr2 & 0xFFF) > 0xFFE) - { - if (cr0 >> 31) - { - if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff; - if (mmutranslate_read(addr2+1) == 0xffffffff) return 0xffff; - } - if (is386) return readmemb386l(seg,addr)|(readmemb386l(seg,addr+1)<<8); - else return readmembl(seg+addr)|(readmembl(seg+addr+1)<<8); - } - else if (readlookup2[addr2 >> 12] != -1) - return *(uint16_t *)(readlookup2[addr2 >> 12] + addr2); - } - if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) - { - addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF); - if(addr < mem_size * 1024) return *((uint16_t *)&ram[addr]); - return 0xFFFF; - } - if (cr0>>31) - { - addr2 = mmutranslate_read(addr2); - if (addr2==0xFFFFFFFF) return 0xFFFF; - } - - addr2 &= rammask; - - if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]); - - if (_mem_read_b[addr2 >> 14]) - { - if (AT) return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[(addr2 + 1) >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14]) << 8); - else return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[(seg + ((addr + 1) & 0xffff)) >> 14](seg + ((addr + 1) & 0xffff), _mem_priv_r[addr2 >> 14]) << 8); - } - return 0xffff; -} - -void writememwl(uint32_t seg, uint32_t addr, uint16_t val) -{ - uint32_t addr2 = mem_logical_addr = seg + addr; - - if (seg==-1) - { - x86gpf("NULL segment", 0); - return; - } - if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) - { - addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF); - if(addr < mem_size * 1024) *((uint16_t *)&ram[addr]) = val; - return; - } - - if (addr2 & 1) - { - if (!cpu_cyrix_alignment || (addr2 & 7) == 7) - cycles -= timing_misaligned; - if ((addr2 & 0xFFF) > 0xFFE) - { - if (cr0 >> 31) - { - if (mmutranslate_write(addr2) == 0xffffffff) return; - if (mmutranslate_write(addr2+1) == 0xffffffff) return; - } - if (is386) - { - writememb386l(seg,addr,val); - writememb386l(seg,addr+1,val>>8); - } - else - { - writemembl(seg+addr,val); - writemembl(seg+addr+1,val>>8); - } - return; - } - else if (writelookup2[addr2 >> 12] != -1) - { - *(uint16_t *)(writelookup2[addr2 >> 12] + addr2) = val; - return; - } - } - - if (page_lookup[addr2>>12]) - { - page_lookup[addr2>>12]->write_w(addr2, val, page_lookup[addr2>>12]); - return; - } - if (cr0>>31) - { - addr2 = mmutranslate_write(addr2); - if (addr2==0xFFFFFFFF) return; - } - - addr2 &= rammask; - -/* if (addr2 >= 0xa0000 && addr2 < 0xc0000) - pclog("writememwl %08X %02X\n", addr2, val);*/ - - if (_mem_write_w[addr2 >> 14]) - { - _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - return; - } - - if (_mem_write_b[addr2 >> 14]) - { - _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_b[(addr2 + 1) >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]); - return; - } -} - -uint32_t readmemll(uint32_t seg, uint32_t addr) -{ - uint32_t addr2 = mem_logical_addr = seg + addr; - - if (seg==-1) - { - x86gpf("NULL segment", 0); - return -1; - } - - if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) - { - addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF); - if(addr < mem_size * 1024) return *((uint32_t *)&ram[addr]); - return 0xFFFFFFFF; - } - - if (addr2 & 3) - { - if (!cpu_cyrix_alignment || (addr2 & 7) > 4) - cycles -= timing_misaligned; - if ((addr2&0xFFF)>0xFFC) - { - if (cr0>>31) - { - if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; - if (mmutranslate_read(addr2+3) == 0xffffffff) return 0xffffffff; - } - return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16); - } - else if (readlookup2[addr2 >> 12] != -1) - return *(uint32_t *)(readlookup2[addr2 >> 12] + addr2); - } - - if (cr0>>31) - { - addr2 = mmutranslate_read(addr2); - if (addr2==0xFFFFFFFF) return 0xFFFFFFFF; - } - - addr2&=rammask; - - if (_mem_read_l[addr2 >> 14]) return _mem_read_l[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]); - - if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_w[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14]) << 16); - - if (_mem_read_b[addr2 >> 14]) return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[addr2 >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14]) << 8) | (_mem_read_b[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14]) << 16) | (_mem_read_b[addr2 >> 14](addr2 + 3, _mem_priv_r[addr2 >> 14]) << 24); - - return 0xffffffff; -} - -void writememll(uint32_t seg, uint32_t addr, uint32_t val) -{ - uint32_t addr2 = mem_logical_addr = seg + addr; - - if (seg==-1) - { - x86gpf("NULL segment", 0); - return; - } - if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) - { - addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF); - if(addr < mem_size * 1024) *((uint32_t *)&ram[addr]) = val; - return; - } - if (addr2 & 3) - { - if (!cpu_cyrix_alignment || (addr2 & 7) > 4) - cycles -= timing_misaligned; - if ((addr2 & 0xFFF) > 0xFFC) - { - if (cr0>>31) - { - if (mmutranslate_write(addr2) == 0xffffffff) return; - if (mmutranslate_write(addr2+3) == 0xffffffff) return; - } - writememwl(seg,addr,val); - writememwl(seg,addr+2,val>>16); - return; - } - else if (writelookup2[addr2 >> 12] != -1) - { - *(uint32_t *)(writelookup2[addr2 >> 12] + addr2) = val; - return; - } - } - if (page_lookup[addr2>>12]) - { - page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); - return; - } - if (cr0>>31) - { - addr2 = mmutranslate_write(addr2); - if (addr2==0xFFFFFFFF) return; - } - - addr2&=rammask; - - if (_mem_write_l[addr2 >> 14]) - { - _mem_write_l[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - return; - } - if (_mem_write_w[addr2 >> 14]) - { - _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); - return; - } - if (_mem_write_b[addr2 >> 14]) - { - _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv_w[addr2 >> 14]); - return; - } -} - -uint64_t readmemql(uint32_t seg, uint32_t addr) -{ - uint32_t addr2 = mem_logical_addr = seg + addr; - - if (seg==-1) - { - x86gpf("NULL segment", 0); - return -1; - } - - if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) - { - addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF); - if(addr < mem_size * 1024) return *((uint64_t *)&ram[addr]); - return -1; - } - - if (addr2 & 7) - { - cycles -= timing_misaligned; - if ((addr2 & 0xFFF) > 0xFF8) - { - if (cr0>>31) - { - if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; - if (mmutranslate_read(addr2+7) == 0xffffffff) return 0xffffffff; - } - return readmemll(seg,addr)|((uint64_t)readmemll(seg,addr+4)<<32); - } - else if (readlookup2[addr2 >> 12] != -1) - return *(uint64_t *)(readlookup2[addr2 >> 12] + addr2); - } - - if (cr0>>31) - { - addr2 = mmutranslate_read(addr2); - if (addr2==0xFFFFFFFF) return -1; - } - - addr2&=rammask; - - if (_mem_read_l[addr2 >> 14]) - return _mem_read_l[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | - ((uint64_t)_mem_read_l[addr2 >> 14](addr2 + 4, _mem_priv_r[addr2 >> 14]) << 32); - - return readmemll(seg,addr) | ((uint64_t)readmemll(seg,addr+4)<<32); -} - -void writememql(uint32_t seg, uint32_t addr, uint64_t val) -{ - uint32_t addr2 = mem_logical_addr = seg + addr; - - if (seg==-1) - { - x86gpf("NULL segment", 0); - return; - } - if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) - { - addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF); - if(addr < mem_size * 1024) *((uint64_t *)&ram[addr]) = val; - return; - } - if (addr2 & 7) - { - cycles -= timing_misaligned; - if ((addr2 & 0xFFF) > 0xFF8) - { - if (cr0>>31) - { - if (mmutranslate_write(addr2) == 0xffffffff) return; - if (mmutranslate_write(addr2+7) == 0xffffffff) return; - } - writememll(seg, addr, val); - writememll(seg, addr+4, val >> 32); - return; - } - else if (writelookup2[addr2 >> 12] != -1) - { - *(uint64_t *)(writelookup2[addr2 >> 12] + addr2) = val; - return; - } - } - if (page_lookup[addr2>>12]) - { - page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); - page_lookup[addr2>>12]->write_l(addr2 + 4, val >> 32, page_lookup[addr2>>12]); - return; - } - if (cr0>>31) - { - addr2 = mmutranslate_write(addr2); - if (addr2==0xFFFFFFFF) return; - } - - addr2&=rammask; - - if (_mem_write_l[addr2 >> 14]) - { - _mem_write_l[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_l[addr2 >> 14](addr2+4, val >> 32, _mem_priv_w[addr2 >> 14]); - return; - } - if (_mem_write_w[addr2 >> 14]) - { - _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); - _mem_write_w[addr2 >> 14](addr2 + 4, val >> 32, _mem_priv_w[addr2 >> 14]); - _mem_write_w[addr2 >> 14](addr2 + 6, val >> 48, _mem_priv_w[addr2 >> 14]); - return; - } - if (_mem_write_b[addr2 >> 14]) - { - _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 4, val >> 32, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 5, val >> 40, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 6, val >> 48, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 7, val >> 56, _mem_priv_w[addr2 >> 14]); - return; - } -} - -uint8_t mem_readb_phys(uint32_t addr) -{ - mem_logical_addr = 0xffffffff; - - if (_mem_read_b[addr >> 14]) - return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); - - return 0xff; -} - -/* Version of mem_readby_phys that doesn't go through the CPU paging mechanism. */ -uint8_t mem_readb_phys_dma(uint32_t addr) -{ - /* mem_logical_addr = 0xffffffff; */ - - if (_mem_exec[addr >> 14]) - return _mem_exec[addr >> 14][addr & 0x3fff]; - else if (_mem_read_b[addr >> 14]) - return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); - else - return 0xff; -} - -uint16_t mem_readw_phys(uint32_t addr) -{ - mem_logical_addr = 0xffffffff; - - if (_mem_read_w[addr >> 14]) - return _mem_read_w[addr >> 14](addr, _mem_priv_r[addr >> 14]); - - return 0xff; -} - -void mem_writeb_phys(uint32_t addr, uint8_t val) -{ - mem_logical_addr = 0xffffffff; - - if (_mem_write_b[addr >> 14]) - _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); -} - -/* Version of mem_readby_phys that doesn't go through the CPU paging mechanism. */ -void mem_writeb_phys_dma(uint32_t addr, uint8_t val) -{ - /* mem_logical_addr = 0xffffffff; */ - - if (_mem_exec[addr >> 14]) - _mem_exec[addr >> 14][addr & 0x3fff] = val; - else if (_mem_write_b[addr >> 14]) - _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); -} - -void mem_writew_phys(uint32_t addr, uint16_t val) -{ - mem_logical_addr = 0xffffffff; - - if (_mem_write_w[addr >> 14]) - _mem_write_w[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); -} - -uint8_t mem_read_ram(uint32_t addr, void *priv) -{ - addreadlookup(mem_logical_addr, addr); - return ram[addr]; -} -uint16_t mem_read_ramw(uint32_t addr, void *priv) -{ - addreadlookup(mem_logical_addr, addr); - return *(uint16_t *)&ram[addr]; -} -uint32_t mem_read_raml(uint32_t addr, void *priv) -{ - addreadlookup(mem_logical_addr, addr); - return *(uint32_t *)&ram[addr]; -} - -void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) -{ -#ifdef USE_DYNAREC - if (val != p->mem[addr & 0xfff] || codegen_in_recompile) -#else - if (val != p->mem[addr & 0xfff]) -#endif - { - uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; - p->mem[addr & 0xfff] = val; - } -} -void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) -{ -#ifdef USE_DYNAREC - if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) -#else - if (val != *(uint16_t *)&p->mem[addr & 0xfff]) -#endif - { - uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - if ((addr & 0xf) == 0xf) - mask |= (mask << 1); - p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; - *(uint16_t *)&p->mem[addr & 0xfff] = val; - } -} -void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) -{ -#ifdef USE_DYNAREC - if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) -#else - if (val != *(uint32_t *)&p->mem[addr & 0xfff]) -#endif - { - uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - if ((addr & 0xf) >= 0xd) - mask |= (mask << 1); - p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; - *(uint32_t *)&p->mem[addr & 0xfff] = val; - } -} - -void mem_write_ram(uint32_t addr, uint8_t val, void *priv) -{ - addwritelookup(mem_logical_addr, addr); - mem_write_ramb_page(addr, val, &pages[addr >> 12]); -} -void mem_write_ramw(uint32_t addr, uint16_t val, void *priv) -{ - addwritelookup(mem_logical_addr, addr); - mem_write_ramw_page(addr, val, &pages[addr >> 12]); -} -void mem_write_raml(uint32_t addr, uint32_t val, void *priv) -{ - addwritelookup(mem_logical_addr, addr); - mem_write_raml_page(addr, val, &pages[addr >> 12]); -} - - -uint8_t mem_read_bios(uint32_t addr, void *priv) -{ - return rom[addr & biosmask]; -} -uint16_t mem_read_biosw(uint32_t addr, void *priv) -{ - return *(uint16_t *)&rom[addr & biosmask]; -} -uint32_t mem_read_biosl(uint32_t addr, void *priv) -{ - return *(uint32_t *)&rom[addr & biosmask]; -} - -uint8_t mem_read_romext(uint32_t addr, void *priv) -{ - return romext[addr & 0x7fff]; -} -uint16_t mem_read_romextw(uint32_t addr, void *priv) -{ - uint16_t *p = (uint16_t *)&romext[addr & 0x7fff]; - return *p; -} -uint32_t mem_read_romextl(uint32_t addr, void *priv) -{ - uint32_t *p = (uint32_t *)&romext[addr & 0x7fff]; - return *p; -} - -void mem_write_null(uint32_t addr, uint8_t val, void *p) -{ -} -void mem_write_nullw(uint32_t addr, uint16_t val, void *p) -{ -} -void mem_write_nulll(uint32_t addr, uint32_t val, void *p) -{ -} - -void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) -{ - start_addr &= ~PAGE_MASK_MASK; - end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; - - for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) - { - uint64_t mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - - pages[start_addr >> 12].dirty_mask[(start_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; - } -} - -static __inline int mem_mapping_read_allowed(uint32_t flags, int state) -{ - switch (state & MEM_READ_MASK) - { - case MEM_READ_ANY: - return 1; - case MEM_READ_EXTERNAL: - return !(flags & MEM_MAPPING_INTERNAL); - case MEM_READ_INTERNAL: - return !(flags & MEM_MAPPING_EXTERNAL); - default: - fatal("mem_mapping_read_allowed : bad state %x\n", state); - return 0; - } -} - -static __inline int mem_mapping_write_allowed(uint32_t flags, int state) -{ - switch (state & MEM_WRITE_MASK) - { - case MEM_WRITE_DISABLED: - return 0; - case MEM_WRITE_ANY: - return 1; - case MEM_WRITE_EXTERNAL: - return !(flags & MEM_MAPPING_INTERNAL); - case MEM_WRITE_INTERNAL: - return !(flags & MEM_MAPPING_EXTERNAL); - default: - fatal("mem_mapping_write_allowed : bad state %x\n", state); - return 0; - } -} - -static void mem_mapping_recalc(uint64_t base, uint64_t size) -{ - uint64_t c; - mem_mapping_t *mapping = base_mapping.next; - - if (!size) - return; - /*Clear out old mappings*/ - for (c = base; c < base + size; c += 0x4000) - { - _mem_read_b[c >> 14] = NULL; - _mem_read_w[c >> 14] = NULL; - _mem_read_l[c >> 14] = NULL; - _mem_priv_r[c >> 14] = NULL; - _mem_mapping_r[c >> 14] = NULL; - _mem_write_b[c >> 14] = NULL; - _mem_write_w[c >> 14] = NULL; - _mem_write_l[c >> 14] = NULL; - _mem_priv_w[c >> 14] = NULL; - _mem_mapping_w[c >> 14] = NULL; - } - - /*Walk mapping list*/ - while (mapping != NULL) - { - /*In range?*/ - if (mapping->enable && (uint64_t)mapping->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)mapping->base + (uint64_t)mapping->size) > (uint64_t)base) - { - uint64_t start = (mapping->base < base) ? mapping->base : base; - uint64_t end = (((uint64_t)mapping->base + (uint64_t)mapping->size) < (base + size)) ? ((uint64_t)mapping->base + (uint64_t)mapping->size) : (base + size); - if (start < mapping->base) - start = mapping->base; - - for (c = start; c < end; c += 0x4000) - { - if ((mapping->read_b || mapping->read_w || mapping->read_l) && - mem_mapping_read_allowed(mapping->flags, _mem_state[c >> 14])) - { - _mem_read_b[c >> 14] = mapping->read_b; - _mem_read_w[c >> 14] = mapping->read_w; - _mem_read_l[c >> 14] = mapping->read_l; - if (mapping->exec) - _mem_exec[c >> 14] = mapping->exec + (c - mapping->base); - else - _mem_exec[c >> 14] = NULL; - _mem_priv_r[c >> 14] = mapping->p; - _mem_mapping_r[c >> 14] = mapping; - } - if ((mapping->write_b || mapping->write_w || mapping->write_l) && - mem_mapping_write_allowed(mapping->flags, _mem_state[c >> 14])) - { - _mem_write_b[c >> 14] = mapping->write_b; - _mem_write_w[c >> 14] = mapping->write_w; - _mem_write_l[c >> 14] = mapping->write_l; - _mem_priv_w[c >> 14] = mapping->p; - _mem_mapping_w[c >> 14] = mapping; - } - } - } - mapping = mapping->next; - } - flushmmucache_cr3(); -} - -void mem_mapping_add(mem_mapping_t *mapping, - uint32_t base, - uint32_t size, - uint8_t (*read_b)(uint32_t addr, void *p), - uint16_t (*read_w)(uint32_t addr, void *p), - uint32_t (*read_l)(uint32_t addr, void *p), - void (*write_b)(uint32_t addr, uint8_t val, void *p), - void (*write_w)(uint32_t addr, uint16_t val, void *p), - void (*write_l)(uint32_t addr, uint32_t val, void *p), - uint8_t *exec, - uint32_t flags, - void *p) -{ - mem_mapping_t *dest = &base_mapping; - - /*Add mapping to the end of the list*/ - while (dest->next) - dest = dest->next; - dest->next = mapping; - mapping->prev = dest; - - if (size) - mapping->enable = 1; - else - mapping->enable = 0; - mapping->base = base; - mapping->size = size; - mapping->read_b = read_b; - mapping->read_w = read_w; - mapping->read_l = read_l; - mapping->write_b = write_b; - mapping->write_w = write_w; - mapping->write_l = write_l; - mapping->exec = exec; - mapping->flags = flags; - mapping->p = p; - mapping->next = NULL; - - mem_mapping_recalc(mapping->base, mapping->size); -} - -void mem_mapping_set_handler(mem_mapping_t *mapping, - uint8_t (*read_b)(uint32_t addr, void *p), - uint16_t (*read_w)(uint32_t addr, void *p), - uint32_t (*read_l)(uint32_t addr, void *p), - void (*write_b)(uint32_t addr, uint8_t val, void *p), - void (*write_w)(uint32_t addr, uint16_t val, void *p), - void (*write_l)(uint32_t addr, uint32_t val, void *p)) -{ - mapping->read_b = read_b; - mapping->read_w = read_w; - mapping->read_l = read_l; - mapping->write_b = write_b; - mapping->write_w = write_w; - mapping->write_l = write_l; - - mem_mapping_recalc(mapping->base, mapping->size); -} - -void mem_mapping_set_addr(mem_mapping_t *mapping, uint32_t base, uint32_t size) -{ - /*Remove old mapping*/ - mapping->enable = 0; - mem_mapping_recalc(mapping->base, mapping->size); - - /*Set new mapping*/ - mapping->enable = 1; - mapping->base = base; - mapping->size = size; - - mem_mapping_recalc(mapping->base, mapping->size); -} - -void mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec) -{ - mapping->exec = exec; - - mem_mapping_recalc(mapping->base, mapping->size); -} - -void mem_mapping_set_p(mem_mapping_t *mapping, void *p) -{ - mapping->p = p; -} - -void mem_mapping_disable(mem_mapping_t *mapping) -{ - mapping->enable = 0; - - mem_mapping_recalc(mapping->base, mapping->size); -} - -void mem_mapping_enable(mem_mapping_t *mapping) -{ - mapping->enable = 1; - - mem_mapping_recalc(mapping->base, mapping->size); -} - -void mem_set_mem_state(uint32_t base, uint32_t size, int state) -{ - uint32_t c; - - for (c = 0; c < size; c += 0x4000) - _mem_state[(c + base) >> 14] = state; - - mem_mapping_recalc(base, size); -} - -void mem_add_bios() -{ - if (AT || (romset == ROM_XI8088 && xi8088_bios_128kb())) - { - mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, 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, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, 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, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[1], (AT && cpu_16bitbus) ? 0xfe4000 : 0xfffe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[2], (AT && cpu_16bitbus) ? 0xfe8000 : 0xfffe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[3], (AT && cpu_16bitbus) ? 0xfec000 : 0xfffec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[4], (AT && cpu_16bitbus) ? 0xff0000 : 0xffff0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[5], (AT && cpu_16bitbus) ? 0xff4000 : 0xffff4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[6], (AT && cpu_16bitbus) ? 0xff8000 : 0xffff8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[7], (AT && cpu_16bitbus) ? 0xffc000 : 0xffffc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), MEM_MAPPING_ROM, 0); -} - -int mem_a20_key = 0, mem_a20_alt = 0; -int mem_a20_state = 0; - -void mem_a20_init(void) -{ - if (AT) { - rammask = cpu_16bitbus ? 0xefffff : 0xffefffff; - flushmmucache(); - mem_a20_state = mem_a20_key | mem_a20_alt; - } else { - rammask = 0xfffff; - flushmmucache(); - mem_a20_key = mem_a20_alt = mem_a20_state = 0; - } -} - -void mem_destroy_pages(void) -{ - if (pages) { - free(pages); - pages = NULL; - } -} - -void mem_resize_pages(void) -{ - int total_size, c; - - mem_destroy_pages(); - - if (AT) { - if (cpu_16bitbus) - total_size = 4096; - else { - total_size = (mem_size + 384) >> 2; - if ((total_size << 2) < (mem_size + 384)) - total_size++; - if (total_size < 4096) - total_size = 4096; - } - } else - total_size = 256; - - pages = malloc(total_size * sizeof(page_t)); - - memset(pages, 0, total_size * sizeof(page_t)); - - for (c = 0; c < total_size; c++) - { - pages[c].mem = &ram[c << 12]; - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; - } -} - -void mem_init(void) -{ - int c; - - split_mapping_enabled = 0; - - /* Always allocate the full 16 MB memory space if memory size is smaller, - we'll need this for stupid things like the PS/2 split mapping. */ - if (mem_size < 16384) { - ram = malloc(16384 * 1024); - memset(ram, 0, 16384 * 1024); - } else { - ram = malloc((mem_size + 384) * 1024); /* 386 extra kB for top remapping */ - memset(ram, 0, (mem_size + 384) * 1024); - } - - readlookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); - writelookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); - rom = NULL; - biosmask = 0xffff; - - memset(ram_mapped_addr, 0, 64 * sizeof(uint32_t)); - - page_lookup = malloc((1 << 20) * sizeof(page_t *)); - memset(page_lookup, 0, (1 << 20) * sizeof(page_t *)); - - mem_resize_pages(); - - memset(isram, 0, sizeof(isram)); - for (c = 0; c < (mem_size / 64); c++) - { - isram[c] = 1; - if ((c >= 0xa && c <= 0xf) || (cpu_16bitbus && c >= 0xfe && c <= 0xff)) - isram[c] = 0; - } - - memset(_mem_read_b, 0, sizeof(_mem_read_b)); - memset(_mem_read_w, 0, sizeof(_mem_read_w)); - memset(_mem_read_l, 0, sizeof(_mem_read_l)); - memset(_mem_write_b, 0, sizeof(_mem_write_b)); - memset(_mem_write_w, 0, sizeof(_mem_write_w)); - memset(_mem_write_l, 0, sizeof(_mem_write_l)); - memset(_mem_exec, 0, sizeof(_mem_exec)); - - memset(ff_array, 0xff, sizeof(ff_array)); - - memset(&base_mapping, 0, sizeof(base_mapping)); - - memset(_mem_state, 0, sizeof(_mem_state)); - - mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - - mem_mapping_add(&ram_low_mapping, 0x00000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram, MEM_MAPPING_INTERNAL, NULL); - if (mem_size > 1024) { - if(cpu_16bitbus && mem_size > 16256) - { - mem_set_mem_state(0x100000, (16256 - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_high_mapping, 0x100000, ((16256 - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); - } - else - { - mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); - } - } - if (mem_size > 768) - mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); - - if (romset == ROM_IBMPS1_2011) - mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL); - - mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 384 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + (1 << 20), MEM_MAPPING_INTERNAL, NULL); - mem_mapping_disable(&ram_remapped_mapping); - - mem_mapping_add(&ram_split_mapping, mem_size * 1024, 384 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + (1 << 20), MEM_MAPPING_INTERNAL, NULL); - mem_mapping_disable(&ram_split_mapping); - - mem_a20_init(); -} - -static void mem_remap_top(int max_size) -{ - int c; - - if (mem_size > 640) - { - uint32_t start = (mem_size >= 1024) ? mem_size : 1024; - int size = mem_size - 640; - if (size > max_size) - size = max_size; - - for (c = (start / 64); c < ((start + size - 1) / 64); c++) - { - isram[c] = 1; - } - - mem_set_mem_state(start * 1024, size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024); - mem_mapping_set_exec(&ram_split_mapping, ram + (start * 1024)); - - flushmmucache(); - } -} - -void mem_remap_top_256k() -{ - mem_remap_top(256); -} - -void mem_remap_top_384k() -{ - mem_remap_top(384); -} - -void mem_resize() -{ - int c; - - split_mapping_enabled = 0; - - free(ram); - - /* Always allocate the full 16 MB memory space if memory size is smaller, - we'll need this for stupid things like the PS/2 split mapping. */ - if (mem_size < 16384) { - ram = malloc(16384 * 1024); - memset(ram, 0, 16384 * 1024); - } else { - ram = malloc((mem_size + 384) * 1024); /* 386 extra kB for top remapping */ - memset(ram, 0, (mem_size + 384) * 1024); - } - - memset(isram, 0, sizeof(isram)); - for (c = 0; c < (mem_size / 64); c++) - { - isram[c] = 1; - if ((c >= 0xa && c <= 0xf) || (cpu_16bitbus && c >= 0xfe && c <= 0xff)) - isram[c] = 0; - } - - mem_resize_pages(); - - memset(_mem_read_b, 0, sizeof(_mem_read_b)); - memset(_mem_read_w, 0, sizeof(_mem_read_w)); - memset(_mem_read_l, 0, sizeof(_mem_read_l)); - memset(_mem_write_b, 0, sizeof(_mem_write_b)); - memset(_mem_write_w, 0, sizeof(_mem_write_w)); - memset(_mem_write_l, 0, sizeof(_mem_write_l)); - memset(_mem_exec, 0, sizeof(_mem_exec)); - - memset(&base_mapping, 0, sizeof(base_mapping)); - - memset(_mem_state, 0, sizeof(_mem_state)); - - mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - - mem_mapping_add(&ram_low_mapping, 0x00000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram, MEM_MAPPING_INTERNAL, NULL); - if (mem_size > 1024) { - if(cpu_16bitbus && mem_size > 16256) - { - mem_set_mem_state(0x100000, (16256 - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_high_mapping, 0x100000, ((16256 - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); - } - else - { - mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); - } - } - if (mem_size > 768) - mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); - - if (romset == ROM_IBMPS1_2011) - mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL); - - mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 384 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + (1 << 20), MEM_MAPPING_INTERNAL, NULL); - mem_mapping_disable(&ram_remapped_mapping); - - mem_mapping_add(&ram_split_mapping, mem_size * 1024, 384 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + (1 << 20), MEM_MAPPING_INTERNAL, NULL); - mem_mapping_disable(&ram_split_mapping); - - mem_a20_init(); -} - -void mem_reset_page_blocks() -{ - int c; - - if (!pages) - return; - - for (c = 0; c < ((mem_size * 1024) >> 12); c++) - { - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; - pages[c].block[0] = pages[c].block[1] = pages[c].block[2] = pages[c].block[3] = NULL; - pages[c].block_2[0] = pages[c].block_2[1] = pages[c].block_2[2] = pages[c].block_2[3] = NULL; - } -} - - -static int port_92_reg = 0; - -void mem_a20_recalc(void) -{ - int state; - - if (!AT) { - rammask = 0xfffff; - flushmmucache(); - mem_a20_key = mem_a20_alt = mem_a20_state = 0; - return; - } - - state = mem_a20_key | mem_a20_alt; - if (state && !mem_a20_state) - { - rammask = (AT && cpu_16bitbus) ? 0xffffff : 0xffffffff; - flushmmucache(); - } - else if (!state && mem_a20_state) - { - rammask = (AT && cpu_16bitbus) ? 0xefffff : 0xffefffff; - flushmmucache(); - } - mem_a20_state = state; -} - - -uint8_t port_92_read(uint16_t port, void *priv) -{ - return port_92_reg; -} - - -void port_92_write(uint16_t port, uint8_t val, void *priv) -{ - if ((mem_a20_alt ^ val) & 2) - { - mem_a20_alt = (val & 2); - mem_a20_recalc(); - } - - if ((~port_92_reg & val) & 1) - { - softresetx86(); - cpu_set_edx(); - } - - port_92_reg = val; -} - - -void port_92_clear_reset(void) -{ - port_92_reg &= 2; -} - -void port_92_add(void) -{ - io_sethandler(0x0092, 0x0001, port_92_read, NULL, NULL, port_92_write, NULL, NULL, NULL); -} - -void port_92_remove(void) -{ - io_removehandler(0x0092, 0x0001, port_92_read, NULL, NULL, port_92_write, NULL, NULL, NULL); -} - -void port_92_reset(void) -{ - port_92_reg = 0; - mem_a20_alt = 0; - mem_a20_recalc(); - flushmmucache(); -} - -uint32_t get_phys_virt,get_phys_phys; +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Memory handling and MMU. + * + * NOTE: Experimenting with dynamically allocated lookup tables; + * the DYNAMIC_TABLES=1 enables this. Will eventually go + * away, either way... + * + * Version: @(#)mem.c 1.0.9 2018/03/19 + * + * Authors: Fred N. van Kempen, + * Miran Grca, + * Sarah Walker, + * + * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ +#include +#include +#include +#include +#include +#include "86box.h" +#include "cpu/cpu.h" +#include "cpu/x86_ops.h" +#include "cpu/x86.h" +#include "machine/machine.h" +#include "machine/m_xt_xi8088.h" +#include "config.h" +#include "io.h" +#include "mem.h" +#include "rom.h" +#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 +#endif + + +#define FIXME 0 +#define DYNAMIC_TABLES 0 /* experimental */ + + +mem_mapping_t ram_low_mapping; +mem_mapping_t ram_high_mapping; +mem_mapping_t ram_mid_mapping; +mem_mapping_t bios_mapping[8]; +mem_mapping_t bios_high_mapping[8]; +mem_mapping_t romext_mapping; + +page_t *pages, /* RAM page table */ + **page_lookup; /* pagetable lookup */ +uint32_t pages_sz; /* #pages in table */ + +uint8_t isram[0x10000]; + +uint8_t *ram; /* the virtual RAM */ +uint32_t rammask; + +uint8_t *rom; /* the virtual ROM */ +uint8_t romext[32768]; +uint32_t biosmask; + +uint32_t pccache; +uint8_t *pccache2; + +int readlnext; +int readlookup[256], + readlookupp[256]; +uintptr_t *readlookup2; +int writelnext; +int writelookup[256], + writelookupp[256]; +uintptr_t *writelookup2; + +uint32_t mem_logical_addr; + +int shadowbios = 0, + shadowbios_write; +int readlnum = 0, + writelnum = 0; +int pctrans = 0; +int cachesize = 256; + +uint32_t ram_mapped_addr[64]; + +uint32_t get_phys_virt, + get_phys_phys; + +int mem_a20_key = 0, + mem_a20_alt = 0, + mem_a20_state = 0; + +int mmuflush = 0; +int mmu_perm = 4; + + +/* FIXME: re-do this with a 'mem_ops' struct. */ +static uint8_t (*_mem_read_b[0x40000])(uint32_t addr, void *priv); +static uint16_t (*_mem_read_w[0x40000])(uint32_t addr, void *priv); +static uint32_t (*_mem_read_l[0x40000])(uint32_t addr, void *priv); +static void (*_mem_write_b[0x40000])(uint32_t addr, uint8_t val, void *priv); +static void (*_mem_write_w[0x40000])(uint32_t addr, uint16_t val, void *priv); +static void (*_mem_write_l[0x40000])(uint32_t addr, uint32_t val, void *priv); +static uint8_t *_mem_exec[0x40000]; +static void *_mem_priv_r[0x40000]; +static void *_mem_priv_w[0x40000]; +static mem_mapping_t *_mem_mapping_r[0x40000]; +static mem_mapping_t *_mem_mapping_w[0x40000]; +static int _mem_state[0x40000]; + +static mem_mapping_t base_mapping; +static mem_mapping_t ram_remapped_mapping; + +#if FIXME +static uint8_t ff_array[0x1000]; +#else +static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; +#endif + +static int port_92_reg = 0; + + +void +resetreadlookup(void) +{ + int c; + + /* This is NULL after app startup, when mem_init() has not yet run. */ +#if DYNAMIC_TABLES +pclog("MEM: reset_lookup: pages=%08lx, lookup=%08lx, pages_sz=%i\n", pages, page_lookup, pages_sz); +#endif + + /* Initialize the page lookup table. */ +#if DYNAMIC_TABLES + memset(page_lookup, 0x00, pages_sz*sizeof(page_t *)); +#else + memset(page_lookup, 0x00, (1<<20)*sizeof(page_t *)); +#endif + + /* Initialize the tables for lower (<= 1024K) RAM. */ + for (c = 0; c < 256; c++) { + readlookup[c] = 0xffffffff; + writelookup[c] = 0xffffffff; + } + + /* Initialize the tables for high (> 1024K) RAM. */ +#if DYNAMIC_TABLES + memset(readlookup2, 0xff, pages_sz*sizeof(uintptr_t)); + memset(writelookup2, 0xff, pages_sz*sizeof(uintptr_t)); +#else + memset(readlookup2, 0xff, (1<<20)*sizeof(uintptr_t)); + memset(writelookup2, 0xff, (1<<20)*sizeof(uintptr_t)); +#endif + + readlnext = 0; + writelnext = 0; + pccache = 0xffffffff; +} + + +void +flushmmucache(void) +{ + int c; + + for (c = 0; c < 256; c++) { + if (readlookup[c] != 0xffffffff) { + readlookup2[readlookup[c]] = -1; + readlookup[c] = 0xffffffff; + } + if (writelookup[c] != 0xffffffff) { + page_lookup[writelookup[c]] = NULL; + writelookup2[writelookup[c]] = -1; + writelookup[c] = 0xffffffff; + } + } + mmuflush++; + + pccache = (uint32_t)0xffffffff; + pccache2 = (uint8_t *)0xffffffff; + +#ifdef USE_DYNAREC + codegen_flush(); +#endif +} + + +void +flushmmucache_nopc(void) +{ + int c; + + for (c = 0; c < 256; c++) { + if (readlookup[c] != 0xffffffff) { + readlookup2[readlookup[c]] = -1; + readlookup[c] = 0xffffffff; + } + if (writelookup[c] != 0xffffffff) { + page_lookup[writelookup[c]] = NULL; + writelookup2[writelookup[c]] = -1; + writelookup[c] = 0xffffffff; + } + } +} + + +void +flushmmucache_cr3(void) +{ + int c; + + for (c = 0; c < 256; c++) { + if (readlookup[c] != 0xffffffff) { + readlookup2[readlookup[c]] = -1; + readlookup[c] = 0xffffffff; + } + if (writelookup[c] != 0xffffffff) { + page_lookup[writelookup[c]] = NULL; + writelookup2[writelookup[c]] = -1; + writelookup[c] = 0xffffffff; + } + } +} + + +void +mem_flush_write_page(uint32_t addr, uint32_t virt) +{ + page_t *page_target = &pages[addr >> 12]; + int c; + + for (c = 0; c < 256; c++) { + if (writelookup[c] != 0xffffffff) { + uintptr_t target = (uintptr_t)&ram[(uintptr_t)(addr & ~0xfff) - (virt & ~0xfff)]; + + if (writelookup2[writelookup[c]] == target || page_lookup[writelookup[c]] == page_target) { + writelookup2[writelookup[c]] = -1; + page_lookup[writelookup[c]] = NULL; + writelookup[c] = 0xffffffff; + } + } + } +} + + +#define mmutranslate_read(addr) mmutranslatereal(addr,0) +#define mmutranslate_write(addr) mmutranslatereal(addr,1) +#define rammap(x) ((uint32_t *)(_mem_exec[(x) >> 14]))[((x) >> 2) & 0xfff] + +uint32_t +mmutranslatereal(uint32_t addr, int rw) +{ + uint32_t temp,temp2,temp3; + uint32_t addr2; + + if (cpu_state.abrt) return -1; + + addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); + temp = temp2 = rammap(addr2); + if (! (temp&1)) { + cr2 = addr; + temp &= 1; + if (CPL == 3) temp |= 4; + if (rw) temp |= 2; + cpu_state.abrt = ABRT_PF; + abrt_error = temp; + return -1; + } + + if ((temp & 0x80) && (cr4 & CR4_PSE)) { + /*4MB page*/ + if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && ((CPL == 3 && !cpl_override) || cr0 & WP_FLAG))) { + cr2 = addr; + temp &= 1; + if (CPL == 3) + temp |= 4; + if (rw) + temp |= 2; + cpu_state.abrt = ABRT_PF; + abrt_error = temp; + + return -1; + } + + mmu_perm = temp & 4; + rammap(addr2) |= 0x20; + + return (temp & ~0x3fffff) + (addr & 0x3fffff); + } + + temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc)); + temp3 = temp & temp2; + if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && ((CPL == 3 && !cpl_override) || cr0&WP_FLAG))) { + cr2 = addr; + temp &= 1; + if (CPL == 3) temp |= 4; + if (rw) temp |= 2; + cpu_state.abrt = ABRT_PF; + abrt_error = temp; + return -1; + } + + mmu_perm = temp & 4; + rammap(addr2) |= 0x20; + rammap((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) |= (rw?0x60:0x20); + + return (temp&~0xfff)+(addr&0xfff); +} + + +uint32_t +mmutranslate_noabrt(uint32_t addr, int rw) +{ + uint32_t temp,temp2,temp3; + uint32_t addr2; + + if (cpu_state.abrt) + return -1; + + addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); + temp = temp2 = rammap(addr2); + + if (! (temp & 1)) + return -1; + + if ((temp & 0x80) && (cr4 & CR4_PSE)) { + /*4MB page*/ + if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (CPL == 3 || cr0 & WP_FLAG))) + return -1; + + return (temp & ~0x3fffff) + (addr & 0x3fffff); + } + + temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc)); + temp3 = temp & temp2; + + if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && (CPL==3 || cr0&WP_FLAG))) + return -1; + + return (temp & ~0xfff) + (addr & 0xfff); +} + + +void +mmu_invalidate(uint32_t addr) +{ + flushmmucache_cr3(); +} + + +uint8_t +mem_addr_range_match(uint32_t addr, uint32_t start, uint32_t len) +{ + if (addr < start) + return 0; + else if (addr >= (start + len)) + return 0; + else + return 1; +} + + +uint32_t +mem_addr_translate(uint32_t addr, uint32_t chunk_start, uint32_t len) +{ + uint32_t mask = len - 1; + + return chunk_start + (addr & mask); +} + + +void +addreadlookup(uint32_t virt, uint32_t phys) +{ + if (virt == 0xffffffff) return; + + if (readlookup2[virt>>12] != -1) return; + + if (readlookup[readlnext] != 0xffffffff) + 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); + + cycles -= 9; +} + + +void +addwritelookup(uint32_t virt, uint32_t phys) +{ + if (virt == 0xffffffff) return; + + if (page_lookup[virt >> 12]) return; + + if (writelookup[writelnext] != -1) { + page_lookup[writelookup[writelnext]] = NULL; + writelookup2[writelookup[writelnext]] = -1; + } + +#ifdef USE_DYNAREC + if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3] || (phys & ~0xfff) == recomp_page) +#else + if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3]) +#endif + 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); + + cycles -= 9; +} + + +uint8_t * +getpccache(uint32_t a) +{ + uint32_t a2; + + a2 = a; + + if (a2 < 0x100000 && ram_mapped_addr[a2 >> 14]) { + a = (ram_mapped_addr[a2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? a2 : (ram_mapped_addr[a2 >> 14] & ~0x3FFF) + (a2 & 0x3FFF); + return &ram[(uintptr_t)(a & 0xFFFFF000) - (uintptr_t)(a2 & ~0xFFF)]; + } + + a2 = a; + + if (cr0 >> 31) { + pctrans=1; + a = mmutranslate_read(a); + pctrans = 0; + + if (a == 0xffffffff) return ram; + } + a &= rammask; + + if (_mem_exec[a >> 14]) { + if (_mem_mapping_r[a >> 14]->flags & MEM_MAPPING_ROM) + cpu_prefetch_cycles = cpu_rom_prefetch_cycles; + else + cpu_prefetch_cycles = cpu_mem_prefetch_cycles; + + return &_mem_exec[a >> 14][(uintptr_t)(a & 0x3000) - (uintptr_t)(a2 & ~0xfff)]; + } + + pclog("Bad getpccache %08X\n", a); + +#if FIXME + return &ff_array[0-(uintptr_t)(a2 & ~0xfff)]; +#else + return (uint8_t *)&ff_pccache; +#endif +} + + +uint8_t +readmembl(uint32_t addr) +{ + mem_logical_addr = addr; + + if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) { + addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff); + if(addr < mem_size * 1024) return ram[addr]; + return 0xff; + } + + if (cr0 >> 31) { + addr = mmutranslate_read(addr); + if (addr == 0xffffffff) return 0xff; + } + addr &= rammask; + + if (_mem_read_b[addr >> 14]) + return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); + + return 0xff; +} + + +void +writemembl(uint32_t addr, uint8_t val) +{ + mem_logical_addr = addr; + + if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) { + addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff); + if (addr < mem_size * 1024) + ram[addr] = val; + return; + } + + if (page_lookup[addr>>12]) { + page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); + + return; + } + + if (cr0 >> 31) { + addr = mmutranslate_write(addr); + if (addr == 0xffffffff) return; + } + addr &= rammask; + + if (_mem_write_b[addr >> 14]) + _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); +} + + +uint8_t +readmemb386l(uint32_t seg, uint32_t addr) +{ + if (seg == -1) { + x86gpf("NULL segment", 0); + + return -1; + } + + mem_logical_addr = addr = addr + seg; + if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) { + addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff); + if (addr < mem_size * 1024) + return ram[addr]; + return 0xff; + } + + if (cr0 >> 31) { + addr = mmutranslate_read(addr); + if (addr == 0xffffffff) + return 0xff; + } + + addr &= rammask; + + if (_mem_read_b[addr >> 14]) + return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); + + return 0xff; +} + + +void +writememb386l(uint32_t seg, uint32_t addr, uint8_t val) +{ + if (seg == -1) { + x86gpf("NULL segment", 0); + return; + } + + mem_logical_addr = addr = addr + seg; + if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) { + addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3fff) + (addr & 0x3fff); + if (addr < mem_size * 1024) + ram[addr] = val; + return; + } + + if (page_lookup[addr>>12]) { + page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); + + return; + } + + if (cr0 >> 31) { + addr = mmutranslate_write(addr); + if (addr == 0xffffffff) return; + } + + addr &= rammask; + + if (_mem_write_b[addr >> 14]) + _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); +} + + +uint16_t +readmemwl(uint32_t seg, uint32_t addr) +{ + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (seg == -1) { + x86gpf("NULL segment", 0); + return -1; + } + + if (addr2 & 1) { + if (!cpu_cyrix_alignment || (addr2 & 7) == 7) + cycles -= timing_misaligned; + if ((addr2 & 0xFFF) > 0xffe) { + if (cr0 >> 31) { + if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff; + if (mmutranslate_read(addr2+1) == 0xffffffff) return 0xffff; + } + if (is386) return readmemb386l(seg,addr)|(readmemb386l(seg,addr+1)<<8); + else return readmembl(seg+addr)|(readmembl(seg+addr+1)<<8); + } + else if (readlookup2[addr2 >> 12] != -1) + return *(uint16_t *)(readlookup2[addr2 >> 12] + addr2); + } + + if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) { + addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff); + if (addr < mem_size * 1024) + return *((uint16_t *)&ram[addr]); + return 0xffff; + } + + if (cr0 >> 31) { + addr2 = mmutranslate_read(addr2); + if (addr2 == 0xffffffff) + return 0xFFFF; + } + + addr2 &= rammask; + + if (_mem_read_w[addr2 >> 14]) + return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]); + + if (_mem_read_b[addr2 >> 14]) { + if (AT) + return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[(addr2 + 1) >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14]) << 8); + else + return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[(seg + ((addr + 1) & 0xffff)) >> 14](seg + ((addr + 1) & 0xffff), _mem_priv_r[addr2 >> 14]) << 8); + } + + return 0xffff; +} + + +void +writememwl(uint32_t seg, uint32_t addr, uint16_t val) +{ + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (seg == -1) { + x86gpf("NULL segment", 0); + return; + } + + if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) { + addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff); + if (addr < mem_size * 1024) + *((uint16_t *)&ram[addr]) = val; + return; + } + + if (addr2 & 1) { + if (!cpu_cyrix_alignment || (addr2 & 7) == 7) + cycles -= timing_misaligned; + if ((addr2 & 0xFFF) > 0xffe) { + if (cr0 >> 31) { + if (mmutranslate_write(addr2) == 0xffffffff) return; + if (mmutranslate_write(addr2+1) == 0xffffffff) return; + } + if (is386) { + writememb386l(seg,addr,val); + writememb386l(seg,addr+1,val>>8); + } else { + writemembl(seg+addr,val); + writemembl(seg+addr+1,val>>8); + } + return; + } else if (writelookup2[addr2 >> 12] != -1) { + *(uint16_t *)(writelookup2[addr2 >> 12] + addr2) = val; + return; + } + } + + if (page_lookup[addr2>>12]) { + page_lookup[addr2>>12]->write_w(addr2, val, page_lookup[addr2>>12]); + return; + } + + if (cr0 >> 31) { + addr2 = mmutranslate_write(addr2); + if (addr2 == 0xffffffff) return; + } + + addr2 &= rammask; + +#if 0 + if (addr2 >= 0xa0000 && addr2 < 0xc0000) + pclog("writememwl %08X %02X\n", addr2, val); +#endif + + if (_mem_write_w[addr2 >> 14]) { + _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); + return; + } + + if (_mem_write_b[addr2 >> 14]) { + _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); + _mem_write_b[(addr2 + 1) >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]); + return; + } +} + + +uint32_t +readmemll(uint32_t seg, uint32_t addr) +{ + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (seg == -1) { + x86gpf("NULL segment", 0); + return -1; + } + + if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) { + addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff); + if (addr < mem_size * 1024) + return *((uint32_t *)&ram[addr]); + return 0xffffffff; + } + + if (addr2 & 3) { + if (!cpu_cyrix_alignment || (addr2 & 7) > 4) + cycles -= timing_misaligned; + if ((addr2 & 0xfff) > 0xffc) { + if (cr0 >> 31) { + if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; + if (mmutranslate_read(addr2+3) == 0xffffffff) return 0xffffffff; + } + return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16); + } else if (readlookup2[addr2 >> 12] != -1) + return *(uint32_t *)(readlookup2[addr2 >> 12] + addr2); + } + + if (cr0 >> 31) { + addr2 = mmutranslate_read(addr2); + if (addr2 == 0xffffffff) + return 0xffffffff; + } + + addr2 &= rammask; + + if (_mem_read_l[addr2 >> 14]) + return _mem_read_l[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]); + + if (_mem_read_w[addr2 >> 14]) + return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_w[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14]) << 16); + + if (_mem_read_b[addr2 >> 14]) + return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[addr2 >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14]) << 8) | (_mem_read_b[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14]) << 16) | (_mem_read_b[addr2 >> 14](addr2 + 3, _mem_priv_r[addr2 >> 14]) << 24); + + return 0xffffffff; +} + + +void +writememll(uint32_t seg, uint32_t addr, uint32_t val) +{ + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (seg == -1) { + x86gpf("NULL segment", 0); + return; + } + + if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) { + addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff); + if (addr < mem_size * 1024) + *((uint32_t *)&ram[addr]) = val; + return; + } + + if (addr2 & 3) { + if (!cpu_cyrix_alignment || (addr2 & 7) > 4) + cycles -= timing_misaligned; + if ((addr2 & 0xfff) > 0xffc) { + if (cr0 >> 31) { + if (mmutranslate_write(addr2) == 0xffffffff) return; + if (mmutranslate_write(addr2+3) == 0xffffffff) return; + } + writememwl(seg,addr,val); + writememwl(seg,addr+2,val>>16); + return; + } else if (writelookup2[addr2 >> 12] != -1) { + *(uint32_t *)(writelookup2[addr2 >> 12] + addr2) = val; + return; + } + } + + if (page_lookup[addr2>>12]) { + page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); + return; + } + + if (cr0 >> 31) { + addr2 = mmutranslate_write(addr2); + if (addr2 == 0xffffffff) return; + } + + addr2 &= rammask; + + if (_mem_write_l[addr2 >> 14]) { + _mem_write_l[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); + return; + } + if (_mem_write_w[addr2 >> 14]) { + _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); + _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); + return; + } + if (_mem_write_b[addr2 >> 14]) { + _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv_w[addr2 >> 14]); + return; + } +} + + +uint64_t +readmemql(uint32_t seg, uint32_t addr) +{ + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (seg == -1) { + x86gpf("NULL segment", 0); + return -1; + } + + if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) { + addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff); + if (addr < mem_size * 1024) + return *((uint64_t *)&ram[addr]); + return -1; + } + + if (addr2 & 7) { + cycles -= timing_misaligned; + if ((addr2 & 0xfff) > 0xff8) { + if (cr0 >> 31) { + if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; + if (mmutranslate_read(addr2+7) == 0xffffffff) return 0xffffffff; + } + return readmemll(seg,addr)|((uint64_t)readmemll(seg,addr+4)<<32); + } else if (readlookup2[addr2 >> 12] != -1) + return *(uint64_t *)(readlookup2[addr2 >> 12] + addr2); + } + + if (cr0 >> 31) { + addr2 = mmutranslate_read(addr2); + if (addr2 == 0xffffffff) + return -1; + } + + addr2 &= rammask; + + if (_mem_read_l[addr2 >> 14]) + return _mem_read_l[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | + ((uint64_t)_mem_read_l[addr2 >> 14](addr2 + 4, _mem_priv_r[addr2 >> 14]) << 32); + + return readmemll(seg,addr) | ((uint64_t)readmemll(seg,addr+4)<<32); +} + + +void +writememql(uint32_t seg, uint32_t addr, uint64_t val) +{ + uint32_t addr2 = mem_logical_addr = seg + addr; + + if (seg == -1) { + x86gpf("NULL segment", 0); + return; + } + + if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) { + addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3fff) + (addr2 & 0x3fff); + if (addr < mem_size * 1024) + *((uint64_t *)&ram[addr]) = val; + return; + } + + if (addr2 & 7) { + cycles -= timing_misaligned; + if ((addr2 & 0xfff) > 0xff8) { + if (cr0 >> 31) { + if (mmutranslate_write(addr2) == 0xffffffff) return; + if (mmutranslate_write(addr2+7) == 0xffffffff) return; + } + writememll(seg, addr, val); + writememll(seg, addr+4, val >> 32); + return; + } else if (writelookup2[addr2 >> 12] != -1) { + *(uint64_t *)(writelookup2[addr2 >> 12] + addr2) = val; + return; + } + } + + if (page_lookup[addr2>>12]) { + page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); + page_lookup[addr2>>12]->write_l(addr2 + 4, val >> 32, page_lookup[addr2>>12]); + return; + } + + if (cr0 >> 31) { + addr2 = mmutranslate_write(addr2); + if (addr2 == 0xffffffff) return; + } + + addr2 &= rammask; + + if (_mem_write_l[addr2 >> 14]) { + _mem_write_l[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); + _mem_write_l[addr2 >> 14](addr2+4, val >> 32, _mem_priv_w[addr2 >> 14]); + return; + } + if (_mem_write_w[addr2 >> 14]) { + _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); + _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); + _mem_write_w[addr2 >> 14](addr2 + 4, val >> 32, _mem_priv_w[addr2 >> 14]); + _mem_write_w[addr2 >> 14](addr2 + 6, val >> 48, _mem_priv_w[addr2 >> 14]); + return; + } + if (_mem_write_b[addr2 >> 14]) { + _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 4, val >> 32, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 5, val >> 40, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 6, val >> 48, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 7, val >> 56, _mem_priv_w[addr2 >> 14]); + return; + } +} + + +uint8_t +mem_readb_phys(uint32_t addr) +{ + mem_logical_addr = 0xffffffff; + + if (_mem_read_b[addr >> 14]) + return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); + + return 0xff; +} + + +/* + * Version of mem_readby_phys that doesn't go through + * the CPU paging mechanism. + */ +uint8_t +mem_readb_phys_dma(uint32_t addr) +{ +#if 0 + mem_logical_addr = 0xffffffff; +#endif + + if (_mem_exec[addr >> 14]) + return _mem_exec[addr >> 14][addr & 0x3fff]; + else if (_mem_read_b[addr >> 14]) + return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); + else + return 0xff; +} + + +uint16_t +mem_readw_phys(uint32_t addr) +{ + mem_logical_addr = 0xffffffff; + + if (_mem_read_w[addr >> 14]) + return _mem_read_w[addr >> 14](addr, _mem_priv_r[addr >> 14]); + + return 0xff; +} + + +void +mem_writeb_phys(uint32_t addr, uint8_t val) +{ + mem_logical_addr = 0xffffffff; + + if (_mem_write_b[addr >> 14]) + _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); +} + + +/* + * Version of mem_readby_phys that doesn't go through + * the CPU paging mechanism. + */ +void +mem_writeb_phys_dma(uint32_t addr, uint8_t val) +{ +#if 0 + mem_logical_addr = 0xffffffff; +#endif + + if (_mem_exec[addr >> 14]) + _mem_exec[addr >> 14][addr & 0x3fff] = val; + else if (_mem_write_b[addr >> 14]) + _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); +} + + +void +mem_writew_phys(uint32_t addr, uint16_t val) +{ + mem_logical_addr = 0xffffffff; + + if (_mem_write_w[addr >> 14]) + _mem_write_w[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); +} + + +uint8_t +mem_read_ram(uint32_t addr, void *priv) +{ + addreadlookup(mem_logical_addr, addr); + + return ram[addr]; +} + + +uint16_t +mem_read_ramw(uint32_t addr, void *priv) +{ + addreadlookup(mem_logical_addr, addr); + + return *(uint16_t *)&ram[addr]; +} + + +uint32_t +mem_read_raml(uint32_t addr, void *priv) +{ + addreadlookup(mem_logical_addr, addr); + + return *(uint32_t *)&ram[addr]; +} + + +void +mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) +{ +#ifdef USE_DYNAREC + if (val != p->mem[addr & 0xfff] || codegen_in_recompile) { +#else + if (val != p->mem[addr & 0xfff]) { +#endif + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + p->mem[addr & 0xfff] = val; + } +} + + +void +mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) +{ +#ifdef USE_DYNAREC + if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { +#else + if (val != *(uint16_t *)&p->mem[addr & 0xfff]) { +#endif + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + if ((addr & 0xf) == 0xf) + mask |= (mask << 1); + p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + *(uint16_t *)&p->mem[addr & 0xfff] = val; + } +} + + +void +mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) +{ +#ifdef USE_DYNAREC + if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { +#else + if (val != *(uint32_t *)&p->mem[addr & 0xfff]) { +#endif + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + if ((addr & 0xf) >= 0xd) + mask |= (mask << 1); + p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + *(uint32_t *)&p->mem[addr & 0xfff] = val; + } +} + + +void +mem_write_ram(uint32_t addr, uint8_t val, void *priv) +{ + addwritelookup(mem_logical_addr, addr); + mem_write_ramb_page(addr, val, &pages[addr >> 12]); +} + + +void +mem_write_ramw(uint32_t addr, uint16_t val, void *priv) +{ + addwritelookup(mem_logical_addr, addr); + mem_write_ramw_page(addr, val, &pages[addr >> 12]); +} + + +void +mem_write_raml(uint32_t addr, uint32_t val, void *priv) +{ + addwritelookup(mem_logical_addr, addr); + mem_write_raml_page(addr, val, &pages[addr >> 12]); +} + + +uint8_t +mem_read_bios(uint32_t addr, void *priv) +{ + return rom[addr & biosmask]; +} + + +uint16_t +mem_read_biosw(uint32_t addr, void *priv) +{ + return *(uint16_t *)&rom[addr & biosmask]; +} + + +uint32_t +mem_read_biosl(uint32_t addr, void *priv) +{ + return *(uint32_t *)&rom[addr & biosmask]; +} + + +uint8_t +mem_read_romext(uint32_t addr, void *priv) +{ + return romext[addr & 0x7fff]; +} + + +uint16_t +mem_read_romextw(uint32_t addr, void *priv) +{ + uint16_t *p = (uint16_t *)&romext[addr & 0x7fff]; + + return *p; +} + + +uint32_t +mem_read_romextl(uint32_t addr, void *priv) +{ + uint32_t *p = (uint32_t *)&romext[addr & 0x7fff]; + + return *p; +} + + +void +mem_write_null(uint32_t addr, uint8_t val, void *p) +{ +} + + +void +mem_write_nullw(uint32_t addr, uint16_t val, void *p) +{ +} + + +void +mem_write_nulll(uint32_t addr, uint32_t val, void *p) +{ +} + + +void +mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) +{ + start_addr &= ~PAGE_MASK_MASK; + end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; + + for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) { + uint64_t mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + + pages[start_addr >> 12].dirty_mask[(start_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + } +} + + +static __inline int +mem_mapping_read_allowed(uint32_t flags, int state) +{ + switch (state & MEM_READ_MASK) { + case MEM_READ_ANY: + return 1; + + case MEM_READ_EXTERNAL: + return !(flags & MEM_MAPPING_INTERNAL); + + case MEM_READ_INTERNAL: + return !(flags & MEM_MAPPING_EXTERNAL); + + default: + fatal("mem_mapping_read_allowed : bad state %x\n", state); + } + + return 0; +} + + +static __inline int +mem_mapping_write_allowed(uint32_t flags, int state) +{ + switch (state & MEM_WRITE_MASK) { + case MEM_WRITE_DISABLED: + return 0; + case MEM_WRITE_ANY: + return 1; + case MEM_WRITE_EXTERNAL: + return !(flags & MEM_MAPPING_INTERNAL); + case MEM_WRITE_INTERNAL: + return !(flags & MEM_MAPPING_EXTERNAL); + default: + fatal("mem_mapping_write_allowed : bad state %x\n", state); + } + + return 0; +} + + +static void +mem_mapping_recalc(uint64_t base, uint64_t size) +{ + mem_mapping_t *mapping = base_mapping.next; + uint64_t c; + + if (! size) return; + + /* Clear out old mappings. */ + for (c = base; c < base + size; c += 0x4000) { + _mem_read_b[c >> 14] = NULL; + _mem_read_w[c >> 14] = NULL; + _mem_read_l[c >> 14] = NULL; + _mem_priv_r[c >> 14] = NULL; + _mem_mapping_r[c >> 14] = NULL; + _mem_write_b[c >> 14] = NULL; + _mem_write_w[c >> 14] = NULL; + _mem_write_l[c >> 14] = NULL; + _mem_priv_w[c >> 14] = NULL; + _mem_mapping_w[c >> 14] = NULL; + } + + /* Walk mapping list. */ + while (mapping != NULL) { + /*In range?*/ + if (mapping->enable && (uint64_t)mapping->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)mapping->base + (uint64_t)mapping->size) > (uint64_t)base) { + uint64_t start = (mapping->base < base) ? mapping->base : base; + uint64_t end = (((uint64_t)mapping->base + (uint64_t)mapping->size) < (base + size)) ? ((uint64_t)mapping->base + (uint64_t)mapping->size) : (base + size); + if (start < mapping->base) + start = mapping->base; + + for (c = start; c < end; c += 0x4000) { + if ((mapping->read_b || mapping->read_w || mapping->read_l) && + mem_mapping_read_allowed(mapping->flags, _mem_state[c >> 14])) { + _mem_read_b[c >> 14] = mapping->read_b; + _mem_read_w[c >> 14] = mapping->read_w; + _mem_read_l[c >> 14] = mapping->read_l; + if (mapping->exec) + _mem_exec[c >> 14] = mapping->exec + (c - mapping->base); + else + _mem_exec[c >> 14] = NULL; + _mem_priv_r[c >> 14] = mapping->p; + _mem_mapping_r[c >> 14] = mapping; + } + if ((mapping->write_b || mapping->write_w || mapping->write_l) && + mem_mapping_write_allowed(mapping->flags, _mem_state[c >> 14])) { + _mem_write_b[c >> 14] = mapping->write_b; + _mem_write_w[c >> 14] = mapping->write_w; + _mem_write_l[c >> 14] = mapping->write_l; + _mem_priv_w[c >> 14] = mapping->p; + _mem_mapping_w[c >> 14] = mapping; + } + } + } + mapping = mapping->next; + } + + flushmmucache_cr3(); +} + + +void +mem_mapping_add(mem_mapping_t *mapping, + uint32_t base, + uint32_t size, + uint8_t (*read_b)(uint32_t addr, void *p), + uint16_t (*read_w)(uint32_t addr, void *p), + uint32_t (*read_l)(uint32_t addr, void *p), + void (*write_b)(uint32_t addr, uint8_t val, void *p), + void (*write_w)(uint32_t addr, uint16_t val, void *p), + void (*write_l)(uint32_t addr, uint32_t val, void *p), + uint8_t *exec, + uint32_t flags, + void *p) +{ + mem_mapping_t *dest = &base_mapping; + + /* Add mapping to the end of the list.*/ + while (dest->next) + dest = dest->next; + dest->next = mapping; + mapping->prev = dest; + + if (size) + mapping->enable = 1; + else + mapping->enable = 0; + mapping->base = base; + mapping->size = size; + mapping->read_b = read_b; + mapping->read_w = read_w; + mapping->read_l = read_l; + mapping->write_b = write_b; + mapping->write_w = write_w; + mapping->write_l = write_l; + mapping->exec = exec; + mapping->flags = flags; + mapping->p = p; + mapping->next = NULL; + + mem_mapping_recalc(mapping->base, mapping->size); +} + + +void +mem_mapping_set_handler(mem_mapping_t *mapping, + uint8_t (*read_b)(uint32_t addr, void *p), + uint16_t (*read_w)(uint32_t addr, void *p), + uint32_t (*read_l)(uint32_t addr, void *p), + void (*write_b)(uint32_t addr, uint8_t val, void *p), + void (*write_w)(uint32_t addr, uint16_t val, void *p), + void (*write_l)(uint32_t addr, uint32_t val, void *p)) +{ + mapping->read_b = read_b; + mapping->read_w = read_w; + mapping->read_l = read_l; + mapping->write_b = write_b; + mapping->write_w = write_w; + mapping->write_l = write_l; + + mem_mapping_recalc(mapping->base, mapping->size); +} + + +void +mem_mapping_set_addr(mem_mapping_t *mapping, uint32_t base, uint32_t size) +{ + /* Remove old mapping. */ + mapping->enable = 0; + mem_mapping_recalc(mapping->base, mapping->size); + + /* Set new mapping. */ + mapping->enable = 1; + mapping->base = base; + mapping->size = size; + + mem_mapping_recalc(mapping->base, mapping->size); +} + + +void +mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec) +{ + mapping->exec = exec; + + mem_mapping_recalc(mapping->base, mapping->size); +} + + +void +mem_mapping_set_p(mem_mapping_t *mapping, void *p) +{ + mapping->p = p; +} + + +void +mem_mapping_disable(mem_mapping_t *mapping) +{ + mapping->enable = 0; + + mem_mapping_recalc(mapping->base, mapping->size); +} + + +void +mem_mapping_enable(mem_mapping_t *mapping) +{ + mapping->enable = 1; + + mem_mapping_recalc(mapping->base, mapping->size); +} + + +void +mem_set_mem_state(uint32_t base, uint32_t size, int state) +{ + uint32_t c; + + for (c = 0; c < size; c += 0x4000) + _mem_state[(c + base) >> 14] = state; + + mem_mapping_recalc(base, size); +} + + +void +mem_add_bios(void) +{ + if (AT || (romset == ROM_XI8088 && xi8088_bios_128kb())) { + mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom,MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom + (0x4000 & biosmask), + MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom + (0x8000 & biosmask), + MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + 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, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom + (0x10000 & biosmask), + MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom + (0x14000 & biosmask), + MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom + (0x18000 & biosmask), + MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + 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, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom, MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[1], + (AT && cpu_16bitbus) ? 0xfe4000 : 0xfffe4000, 0x04000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom + (0x4000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[2], + (AT && cpu_16bitbus) ? 0xfe8000 : 0xfffe8000, 0x04000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom + (0x8000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[3], + (AT && cpu_16bitbus) ? 0xfec000 : 0xfffec000, 0x04000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom + (0xc000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[4], + (AT && cpu_16bitbus) ? 0xff0000 : 0xffff0000, 0x04000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom + (0x10000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[5], + (AT && cpu_16bitbus) ? 0xff4000 : 0xffff4000, 0x04000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom + (0x14000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[6], + (AT && cpu_16bitbus) ? 0xff8000 : 0xffff8000, 0x04000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom + (0x18000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[7], + (AT && cpu_16bitbus) ? 0xffc000 : 0xffffc000, 0x04000, + mem_read_bios,mem_read_biosw,mem_read_biosl, + mem_write_null,mem_write_nullw,mem_write_nulll, + rom + (0x1c000 & biosmask), MEM_MAPPING_ROM, 0); +} + + +void +mem_a20_init(void) +{ + if (AT) { + rammask = cpu_16bitbus ? 0xefffff : 0xffefffff; + flushmmucache(); + mem_a20_state = mem_a20_key | mem_a20_alt; + } else { + rammask = 0xfffff; + flushmmucache(); + mem_a20_key = mem_a20_alt = mem_a20_state = 0; + } +} + + +/* Reset the memory state. */ +void +mem_reset(void) +{ + uint32_t c, m; + + /* Free the ROM memory and reset size mask. */ + if (rom != NULL) { + free(rom); + rom = NULL; + } + biosmask = 0xffff; + + /* + * Always allocate the full 16 MB memory space if memory size + * is smaller, we'll need this for stupid things like the PS/2 + * split mapping. + */ + if (mem_size < 16384) + m = 1024UL * 16384; + else + m = 1024UL * (mem_size + 384); /* 386 extra kB for top remapping */ + if (ram != NULL) { + free(ram); + ram = NULL; + } + ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ + memset(ram, 0x00, m); + + /* + * Allocate the page table based on how much RAM we have. + * We re-allocate the table on each (hard) reset, as the + * memory amount could have changed. + */ + 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; + } + + /* + * Allocate and initialize the (new) page table. + * We only do this if the size of the page table has changed. + */ +#if DYNAMIC_TABLES +pclog("MEM: reset: previous pages=%08lx, pages_sz=%i\n", pages, pages_sz); +#endif + if (pages_sz != m) { + pages_sz = m; + if (pages) { + free(pages); + pages = NULL; + } + pages = (page_t *)malloc(m*sizeof(page_t)); +#if DYNAMIC_TABLES +pclog("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); +#endif + +#if DYNAMIC_TABLES + /* Allocate the (new) lookup tables. */ + if (page_lookup != NULL) free(page_lookup); + page_lookup = (page_t **)malloc(pages_sz*sizeof(page_t *)); + + if (readlookup2 != NULL) free(readlookup2); + readlookup2 = malloc(pages_sz*sizeof(uintptr_t)); + + if (writelookup2 != NULL) free(writelookup2); + writelookup2 = malloc(pages_sz*sizeof(uintptr_t)); + +#endif + } + +#if DYNAMIC_TABLES + memset(page_lookup, 0x00, pages_sz * sizeof(page_t *)); +#else + memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *)); +#endif + + memset(pages, 0x00, pages_sz*sizeof(page_t)); + + for (c=0; c= 0xa && c <= 0xf) || + (cpu_16bitbus && c >= 0xfe && c <= 0xff)) + isram[c] = 0; + } + + memset(_mem_read_b, 0x00, sizeof(_mem_read_b)); + memset(_mem_read_w, 0x00, sizeof(_mem_read_w)); + memset(_mem_read_l, 0x00, sizeof(_mem_read_l)); + memset(_mem_write_b, 0x00, sizeof(_mem_write_b)); + memset(_mem_write_w, 0x00, sizeof(_mem_write_w)); + memset(_mem_write_l, 0x00, sizeof(_mem_write_l)); + memset(_mem_exec, 0x00, sizeof(_mem_exec)); + + memset(&base_mapping, 0x00, sizeof(base_mapping)); + + memset(_mem_state, 0x00, sizeof(_mem_state)); + + mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state(0x0c0000, 0x40000, + MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + + mem_mapping_add(&ram_low_mapping, 0x00000, + (mem_size > 640) ? 0xa0000 : mem_size * 1024, + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram, MEM_MAPPING_INTERNAL, NULL); + + if (mem_size > 1024) { + if (cpu_16bitbus && mem_size > 16256) { + mem_set_mem_state(0x100000, (16256 - 1024) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, + ((16256 - 1024) * 1024), + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } else { + mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, + ((mem_size - 1024) * 1024), + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } + } + + if (mem_size > 768) + mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); + + if (romset == ROM_IBMPS1_2011) + mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, + mem_read_romext,mem_read_romextw,mem_read_romextl, + NULL,NULL, NULL, romext, 0, NULL); + + mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 384 * 1024, + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + (1 << 20), MEM_MAPPING_INTERNAL, NULL); + mem_mapping_disable(&ram_remapped_mapping); + + mem_a20_init(); +} + + +void +mem_init(void) +{ + /* Perform a one-time init. */ + ram = rom = NULL; + pages = NULL; +#if DYNAMIC_TABLES + page_lookup = NULL; + readlookup2 = NULL; + writelookup2 = NULL; + +#else + /* Allocate the lookup tables. */ + page_lookup = (page_t **)malloc((1<<20)*sizeof(page_t *)); + + readlookup2 = malloc((1<<20)*sizeof(uintptr_t)); + + writelookup2 = malloc((1<<20)*sizeof(uintptr_t)); +#endif + + memset(ram_mapped_addr, 0x00, 64 * sizeof(uint32_t)); + +#if FIXME + memset(ff_array, 0xff, sizeof(ff_array)); +#endif + + /* Reset the memory state. */ + mem_reset(); +} + + +static void +mem_remap_top(int max_size) +{ + int c; + + if (mem_size > 640) { + uint32_t start = (mem_size >= 1024) ? mem_size : 1024; + int size = mem_size - 640; + if (size > max_size) + size = max_size; + + for (c = (start / 64); c < ((start + size - 1) / 64); c++) + isram[c] = 1; + + mem_set_mem_state(start * 1024, size * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_set_addr(&ram_remapped_mapping, + start * 1024, size * 1024); + mem_mapping_set_exec(&ram_remapped_mapping, ram + (start * 1024)); + + flushmmucache(); + } +} + + +void +mem_remap_top_256k(void) +{ + mem_remap_top(256); +} + + +void +mem_remap_top_384k(void) +{ + mem_remap_top(384); +} + + +void +mem_reset_page_blocks(void) +{ + int c; + + if (pages == NULL) return; + + for (c = 0; c < ((mem_size * 1024) >> 12); c++) { + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + pages[c].block[0] = pages[c].block[1] = pages[c].block[2] = pages[c].block[3] = NULL; + pages[c].block_2[0] = pages[c].block_2[1] = pages[c].block_2[2] = pages[c].block_2[3] = NULL; + } +} + + +void +mem_a20_recalc(void) +{ + int state; + + if (! AT) { + rammask = 0xfffff; + flushmmucache(); + mem_a20_key = mem_a20_alt = mem_a20_state = 0; + + return; + } + + state = mem_a20_key | mem_a20_alt; + if (state && !mem_a20_state) { + rammask = (AT && cpu_16bitbus) ? 0xffffff : 0xffffffff; + flushmmucache(); + } else if (!state && mem_a20_state) { + rammask = (AT && cpu_16bitbus) ? 0xefffff : 0xffefffff; + flushmmucache(); + } + + mem_a20_state = state; +} + + +uint8_t +port_92_read(uint16_t port, void *priv) +{ + return port_92_reg; +} + + +void +port_92_write(uint16_t port, uint8_t val, void *priv) +{ + if ((mem_a20_alt ^ val) & 2) { + mem_a20_alt = (val & 2); + mem_a20_recalc(); + } + + if ((~port_92_reg & val) & 1) { + softresetx86(); + cpu_set_edx(); + } + + port_92_reg = val; +} + + +void +port_92_clear_reset(void) +{ + port_92_reg &= 2; +} + + +void +port_92_add(void) +{ + io_sethandler(0x0092, 1, + port_92_read,NULL,NULL, port_92_write, NULL,NULL,NULL); +} + + +void +port_92_remove(void) +{ + io_removehandler(0x0092, 1, + port_92_read,NULL,NULL, port_92_write,NULL,NULL, NULL); +} + + +void +port_92_reset(void) +{ + port_92_reg = 0; + mem_a20_alt = 0; + mem_a20_recalc(); + + flushmmucache(); +} diff --git a/src/mem.h b/src/mem.h index f7f488435..660bab616 100644 --- a/src/mem.h +++ b/src/mem.h @@ -1,26 +1,154 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the memory interface. + * + * Version: @(#)mem.h 1.0.4 2018/03/16 + * + * Authors: Fred N. van Kempen, + * Sarah Walker, + * + * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2008-2018 Sarah Walker. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ #ifndef EMU_MEM_H # define EMU_MEM_H -extern uint8_t *ram; -extern uint32_t rammask; +#define MEM_MAPPING_EXTERNAL 1 /* on external bus (ISA/PCI) */ +#define MEM_MAPPING_INTERNAL 2 /* on internal bus (RAM) */ +#define MEM_MAPPING_ROM 4 /* Executing from ROM may involve + * additional wait states. */ -extern int readlookup[256],readlookupp[256]; -extern uintptr_t *readlookup2; -extern int readlnext; -extern int writelookup[256],writelookupp[256]; -extern uintptr_t *writelookup2; -extern int writelnext; +#define MEM_MAP_TO_SHADOW_RAM_MASK 1 +#define MEM_MAP_TO_RAM_ADDR_MASK 2 + +#define MEM_READ_ANY 0x00 +#define MEM_READ_INTERNAL 0x10 +#define MEM_READ_EXTERNAL 0x20 +#define MEM_READ_MASK 0xf0 + +#define MEM_WRITE_ANY 0x00 +#define MEM_WRITE_INTERNAL 0x01 +#define MEM_WRITE_EXTERNAL 0x02 +#define MEM_WRITE_DISABLED 0x03 +#define MEM_WRITE_MASK 0x0f + + +typedef struct _mem_mapping_ { + struct _mem_mapping_ *prev, *next; + + int enable; + + uint32_t base; + uint32_t size; + + uint8_t (*read_b)(uint32_t addr, void *priv); + uint16_t (*read_w)(uint32_t addr, void *priv); + uint32_t (*read_l)(uint32_t addr, void *priv); + void (*write_b)(uint32_t addr, uint8_t val, void *priv); + void (*write_w)(uint32_t addr, uint16_t val, void *priv); + void (*write_l)(uint32_t addr, uint32_t val, void *priv); + + uint8_t *exec; + + uint32_t flags; + + void *p; +} mem_mapping_t; + +typedef struct _page_ { + void (*write_b)(uint32_t addr, uint8_t val, struct _page_ *p); + void (*write_w)(uint32_t addr, uint16_t val, struct _page_ *p); + void (*write_l)(uint32_t addr, uint32_t val, struct _page_ *p); + + uint8_t *mem; + + uint64_t code_present_mask[4], + dirty_mask[4]; + + struct codeblock_t *block[4], *block_2[4]; + + /*Head of codeblock tree associated with this page*/ + struct codeblock_t *head; +} page_t; + + +extern uint8_t *ram; +extern uint32_t rammask; + +extern uint8_t *rom; +extern uint8_t romext[32768]; +extern uint32_t biosmask; + +extern int readlookup[256], + readlookupp[256]; +extern uintptr_t * readlookup2; +extern int readlnext; +extern int writelookup[256], + writelookupp[256]; +extern uintptr_t *writelookup2; +extern int writelnext; +extern uint32_t ram_mapped_addr[64]; + +extern mem_mapping_t bios_mapping[8], + bios_high_mapping[8], + romext_mapping, + ram_low_mapping, + ram_mid_mapping, + ram_high_mapping; + +extern uint32_t mem_logical_addr; + +extern page_t *pages, + **page_lookup; + +extern uint32_t get_phys_virt,get_phys_phys; + +extern int shadowbios, + shadowbios_write; +extern int readlnum, + writelnum; + +extern int nopageerrors; +extern int memspeed[11]; +extern uint8_t isram[0x10000]; + +extern int mmu_perm; + +extern int mem_a20_state, + mem_a20_alt, + mem_a20_key; -extern int mmu_perm; #define readmemb(a) ((readlookup2[(a)>>12]==-1)?readmembl(a):*(uint8_t *)(readlookup2[(a) >> 12] + (a))) #define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl(s,a):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) #define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll(s,a):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) + extern uint8_t readmembl(uint32_t addr); extern void writemembl(uint32_t addr, uint8_t val); extern uint8_t readmemb386l(uint32_t seg, uint32_t addr); @@ -37,54 +165,7 @@ extern uint32_t mmutranslatereal(uint32_t addr, int rw); extern void addreadlookup(uint32_t virt, uint32_t phys); extern void addwritelookup(uint32_t virt, uint32_t phys); -extern int shadowbios,shadowbios_write; -extern int readlnum,writelnum; - - -typedef struct mem_mapping_t -{ - struct mem_mapping_t *prev, *next; - - int enable; - - uint32_t base; - uint32_t size; - - uint8_t (*read_b)(uint32_t addr, void *priv); - uint16_t (*read_w)(uint32_t addr, void *priv); - uint32_t (*read_l)(uint32_t addr, void *priv); - void (*write_b)(uint32_t addr, uint8_t val, void *priv); - void (*write_w)(uint32_t addr, uint16_t val, void *priv); - void (*write_l)(uint32_t addr, uint32_t val, void *priv); - - uint8_t *exec; - - uint32_t flags; - - void *p; -} mem_mapping_t; - -/*Only present on external bus (ISA/PCI)*/ -#define MEM_MAPPING_EXTERNAL 1 -/*Only present on internal bus (RAM)*/ -#define MEM_MAPPING_INTERNAL 2 -/*Executing from ROM may involve additional wait states*/ -#define MEM_MAPPING_ROM 4 - -extern uint8_t *ram,*rom; -extern uint8_t romext[32768]; -extern int readlnum,writelnum; -extern int memspeed[11]; -extern int nopageerrors; -extern uint32_t biosmask; -extern unsigned char isram[0x10000]; - -#define MEM_MAP_TO_SHADOW_RAM_MASK 1 -#define MEM_MAP_TO_RAM_ADDR_MASK 2 - -extern uint32_t ram_mapped_addr[64]; - -void mem_mapping_add(mem_mapping_t *mapping, +extern void mem_mapping_add(mem_mapping_t *mapping, uint32_t base, uint32_t size, uint8_t (*read_b)(uint32_t addr, void *p), @@ -96,149 +177,71 @@ void mem_mapping_add(mem_mapping_t *mapping, uint8_t *exec, uint32_t flags, void *p); -void mem_mapping_set_handler(mem_mapping_t *mapping, + +extern void mem_mapping_set_handler(mem_mapping_t *mapping, uint8_t (*read_b)(uint32_t addr, void *p), uint16_t (*read_w)(uint32_t addr, void *p), uint32_t (*read_l)(uint32_t addr, void *p), void (*write_b)(uint32_t addr, uint8_t val, void *p), void (*write_w)(uint32_t addr, uint16_t val, void *p), void (*write_l)(uint32_t addr, uint32_t val, void *p)); -void mem_mapping_set_p(mem_mapping_t *mapping, void *p); -void mem_mapping_set_addr(mem_mapping_t *mapping, uint32_t base, uint32_t size); -void mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec); -void mem_mapping_disable(mem_mapping_t *mapping); -void mem_mapping_enable(mem_mapping_t *mapping); -void mem_set_mem_state(uint32_t base, uint32_t size, int state); +extern void mem_mapping_set_p(mem_mapping_t *mapping, void *p); -#define MEM_READ_ANY 0x00 -#define MEM_READ_INTERNAL 0x10 -#define MEM_READ_EXTERNAL 0x20 -#define MEM_READ_MASK 0xf0 +extern void mem_mapping_set_addr(mem_mapping_t *mapping, + uint32_t base, uint32_t size); +extern void mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec); +extern void mem_mapping_disable(mem_mapping_t *mapping); +extern void mem_mapping_enable(mem_mapping_t *mapping); -#define MEM_WRITE_ANY 0x00 -#define MEM_WRITE_INTERNAL 0x01 -#define MEM_WRITE_EXTERNAL 0x02 -#define MEM_WRITE_DISABLED 0x03 -#define MEM_WRITE_MASK 0x0f +extern void mem_set_mem_state(uint32_t base, uint32_t size, int state); -extern int mem_a20_state; -extern int mem_a20_alt; -extern int mem_a20_key; -void mem_a20_recalc(); +extern uint8_t mem_readb_phys(uint32_t addr); +extern uint8_t mem_readb_phys_dma(uint32_t addr); +extern uint16_t mem_readw_phys(uint32_t addr); +extern void mem_writeb_phys(uint32_t addr, uint8_t val); +extern void mem_writeb_phys_dma(uint32_t addr, uint8_t val); +extern void mem_writew_phys(uint32_t addr, uint16_t val); -uint8_t mem_readb_phys(uint32_t addr); -uint8_t mem_readb_phys_dma(uint32_t addr); -uint16_t mem_readw_phys(uint32_t addr); -void mem_writeb_phys(uint32_t addr, uint8_t val); -void mem_writeb_phys_dma(uint32_t addr, uint8_t val); -void mem_writew_phys(uint32_t addr, uint16_t val); +extern uint8_t mem_read_ram(uint32_t addr, void *priv); +extern uint16_t mem_read_ramw(uint32_t addr, void *priv); +extern uint32_t mem_read_raml(uint32_t addr, void *priv); +extern void mem_write_ram(uint32_t addr, uint8_t val, void *priv); +extern void mem_write_ramw(uint32_t addr, uint16_t val, void *priv); +extern void mem_write_raml(uint32_t addr, uint32_t val, void *priv); -uint8_t mem_read_ram(uint32_t addr, void *priv); -uint16_t mem_read_ramw(uint32_t addr, void *priv); -uint32_t mem_read_raml(uint32_t addr, void *priv); +extern uint8_t mem_read_bios(uint32_t addr, void *priv); +extern uint16_t mem_read_biosw(uint32_t addr, void *priv); +extern uint32_t mem_read_biosl(uint32_t addr, void *priv); -void mem_write_ram(uint32_t addr, uint8_t val, void *priv); -void mem_write_ramw(uint32_t addr, uint16_t val, void *priv); -void mem_write_raml(uint32_t addr, uint32_t val, void *priv); +extern void mem_write_null(uint32_t addr, uint8_t val, void *p); +extern void mem_write_nullw(uint32_t addr, uint16_t val, void *p); +extern void mem_write_nulll(uint32_t addr, uint32_t val, void *p); -uint8_t mem_read_bios(uint32_t addr, void *priv); -uint16_t mem_read_biosw(uint32_t addr, void *priv); -uint32_t mem_read_biosl(uint32_t addr, void *priv); +extern uint32_t mmutranslate_noabrt(uint32_t addr, int rw); -void mem_write_null(uint32_t addr, uint8_t val, void *p); -void mem_write_nullw(uint32_t addr, uint16_t val, void *p); -void mem_write_nulll(uint32_t addr, uint32_t val, void *p); +extern void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr); -mem_mapping_t bios_mapping[8]; -mem_mapping_t bios_high_mapping[8]; -mem_mapping_t romext_mapping; - -extern mem_mapping_t ram_high_mapping; - - -typedef struct page_t -{ - void (*write_b)(uint32_t addr, uint8_t val, struct page_t *p); - void (*write_w)(uint32_t addr, uint16_t val, struct page_t *p); - void (*write_l)(uint32_t addr, uint32_t val, struct page_t *p); - - uint8_t *mem; - - struct codeblock_t *block[4], *block_2[4]; - - /*Head of codeblock tree associated with this page*/ - struct codeblock_t *head; - - uint64_t code_present_mask[4], dirty_mask[4]; -} page_t; - -extern page_t *pages; - -extern page_t **page_lookup; - -uint32_t mmutranslate_noabrt(uint32_t addr, int rw); - -extern uint32_t get_phys_virt,get_phys_phys; - -#ifdef EMU_CPU_H -static __inline uint32_t get_phys(uint32_t addr) -{ - if (!((addr ^ get_phys_virt) & ~0xfff)) - return get_phys_phys | (addr & 0xfff); - - get_phys_virt = addr; - - if (!(cr0 >> 31)) - { - get_phys_phys = (addr & rammask) & ~0xfff; - return addr & rammask; - } - - get_phys_phys = (mmutranslatereal(addr, 0) & rammask) & ~0xfff; - return get_phys_phys | (addr & 0xfff); - /* return mmutranslatereal(addr, 0) & rammask; */ -} - -static __inline uint32_t get_phys_noabrt(uint32_t addr) -{ - if (!(cr0 >> 31)) - return addr & rammask; - - return mmutranslate_noabrt(addr, 0) & rammask; -} -#endif - -void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr); - -extern uint32_t mem_logical_addr; - -void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p); -void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p); -void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p); -void mem_flush_write_page(uint32_t addr, uint32_t virt); +extern void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p); +extern void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p); +extern void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p); +extern void mem_flush_write_page(uint32_t addr, uint32_t virt); extern void mem_reset_page_blocks(void); -extern mem_mapping_t ram_low_mapping; -extern mem_mapping_t ram_mid_mapping; - -extern void mem_remap_top_256k(void); -extern void mem_remap_top_384k(void); - extern void flushmmucache(void); extern void flushmmucache_cr3(void); extern void flushmmucache_nopc(void); extern void mmu_invalidate(uint32_t addr); +extern void mem_a20_recalc(void); extern void mem_add_bios(void); extern void mem_init(void); -extern void mem_resize(void); - -extern void mem_destroy_pages(void); -extern void mem_resize_pages(void); +extern void mem_reset(void); +extern void mem_remap_top_256k(void); +extern void mem_remap_top_384k(void); extern uint8_t port_92_read(uint16_t port, void *priv); extern void port_92_write(uint16_t port, uint8_t val, void *priv); @@ -248,4 +251,38 @@ extern void port_92_remove(void); extern void port_92_reset(void); +#ifdef EMU_CPU_H +static __inline uint32_t get_phys(uint32_t addr) +{ + if (! ((addr ^ get_phys_virt) & ~0xfff)) + return get_phys_phys | (addr & 0xfff); + + get_phys_virt = addr; + + if (! (cr0 >> 31)) { + get_phys_phys = (addr & rammask) & ~0xfff; + + return addr & rammask; + } + + get_phys_phys = (mmutranslatereal(addr, 0) & rammask) & ~0xfff; + +#if 1 + return get_phys_phys | (addr & 0xfff); +#else + return mmutranslatereal(addr, 0) & rammask; +#endif +} + + +static __inline uint32_t get_phys_noabrt(uint32_t addr) +{ + if (! (cr0 >> 31)) + return addr & rammask; + + return mmutranslate_noabrt(addr, 0) & rammask; +} +#endif + + #endif /*EMU_MEM_H*/ diff --git a/src/mouse.c b/src/mouse.c index 62fd322f7..89fe585ea 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.24 2018/03/19 + * Version: @(#)mouse.c 1.0.25 2018/03/19 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -142,7 +142,7 @@ mouse_process(void) { static int poll_delay = 2; - if ((mouse_curr != NULL) || (mouse_type == MOUSE_TYPE_INTERNAL)) + if ((mouse_curr == NULL) || (mouse_type == MOUSE_TYPE_INTERNAL)) return; if (--poll_delay) return; diff --git a/src/pc.c b/src/pc.c index 38595a0da..172875c0a 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.66 2018/03/19 + * Version: @(#)pc.c 1.0.67 2018/03/19 * * Authors: Sarah Walker, * Miran Grca, @@ -558,8 +558,6 @@ pc_reload(wchar_t *fn) fdd_load(2, floppyfns[2]); fdd_load(3, floppyfns[3]); - mem_resize(); - rom_load_bios(romset); network_init(); pc_reset_hard_init(); @@ -947,8 +945,6 @@ pc_close(thread_t *ptr) sound_cd_thread_end(); - mem_destroy_pages(); - ide_destroy_buffers(); cdrom_destroy_drives(); diff --git a/src/sound/snd_lpt_dac.c b/src/sound/snd_lpt_dac.c index 5efd751d1..0e271ea2d 100644 --- a/src/sound/snd_lpt_dac.c +++ b/src/sound/snd_lpt_dac.c @@ -104,7 +104,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, @@ -113,7 +113,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 7db7a34dd..d9f505353 100644 --- a/src/sound/snd_lpt_dac.h +++ b/src/sound/snd_lpt_dac.h @@ -1,2 +1,2 @@ -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; diff --git a/src/sound/snd_lpt_dss.c b/src/sound/snd_lpt_dss.c index 2042a6494..bacd1e706 100644 --- a/src/sound/snd_lpt_dss.c +++ b/src/sound/snd_lpt_dss.c @@ -109,7 +109,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 b7d8fcbc1..07d37617a 100644 --- a/src/sound/snd_lpt_dss.h +++ b/src/sound/snd_lpt_dss.h @@ -1 +1 @@ -extern lpt_device_t dss_device; +extern const lpt_device_t dss_device; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 38337d5fe..365619145 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.24 2018/03/15 + * Version: @(#)vid_table.c 1.0.25 2018/03/19 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -74,105 +74,105 @@ enum { #define VIDEO_FLAG_TYPE_MASK 3 typedef struct { - const char *name; - const char *internal_name; + const char *name; + const char *internal_name; const device_t *device; - int legacy_id; - int flags; + int legacy_id; + int flags; video_timings_t timing; } VIDEO_CARD; static const VIDEO_CARD video_cards[] = { - { "None", "none", NULL, GFX_NONE }, - { "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, GFX_NONE }, + { "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}}, #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, GFX_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 CL-GD 5428", "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 CL-GD 5429", "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 CL-GD 5434", "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, 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 CL-GD 5428", "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 CL-GD 5429", "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 CL-GD 5434", "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}}, #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, GFX_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 CL-GD 5430", "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 CL-GD 5434", "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 CL-GD 5436", "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, 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 CL-GD 5430", "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 CL-GD 5434", "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 CL-GD 5436", "cl_gd5436_pci", &gd5436_pci_device, GFX_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, GFX_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] 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}}, #if defined(DEV_BRANCH) && defined(USE_RIVA) - {"[PCI] nVidia RIVA 128", "riva128", &riva128_device, GFX_RIVA128, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}}, - {"[PCI] nVidia RIVA TNT", "rivatnt", &rivatnt_device, GFX_RIVATNT, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}}, - {"[PCI] nVidia RIVA TNT2", "rivatnt2", &rivatnt2_device, GFX_RIVATNT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}}, + {"[PCI] nVidia RIVA 128", "riva128", &riva128_device, GFX_RIVA128, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}}, + {"[PCI] nVidia RIVA TNT", "rivatnt", &rivatnt_device, GFX_RIVATNT, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}}, + {"[PCI] nVidia RIVA TNT2", "rivatnt2", &rivatnt2_device, GFX_RIVATNT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 24, 24, 36}}, #endif - {"[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 CL-GD 5428", "cl_gd5428_vlb", &gd5428_vlb_device, GFX_CL_GD5428_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"[VLB] Cirrus Logic CL-GD 5429", "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 CL-GD 5434", "cl_gd5434_vlb", &gd5434_vlb_device, GFX_CL_GD5434_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"[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 CL-GD 5428", "cl_gd5428_vlb", &gd5428_vlb_device, GFX_CL_GD5428_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"[VLB] Cirrus Logic CL-GD 5429", "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 CL-GD 5434", "cl_gd5434_vlb", &gd5434_vlb_device, GFX_CL_GD5434_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, GFX_ET4000W32_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, #endif - {"[VLB] Diamond SpeedStar PRO (CL-GD5426)", "cl_gd5426_vlb", &gd5426_vlb_device, GFX_CL_GD5426_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}}, - {"[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}}, - {"", "", NULL, -1 } + {"[VLB] Diamond SpeedStar PRO (CL-GD5426)", "cl_gd5426_vlb", &gd5426_vlb_device, GFX_CL_GD5426_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}}, + {"[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}}, + {"", "", NULL, -1 } }; From 7237cc723749fe432df14b75bf771ca6373e926e Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Mar 2018 09:48:44 +0100 Subject: [PATCH 16/39] Some tweaks to hard disk image creation. --- src/86box.h | 3 ++- src/disk/hdd_image.c | 30 +++++++++++++++--------------- src/pc.c | 19 ++++++++++++++++--- src/win/win_settings.c | 22 +++++++++------------- 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/86box.h b/src/86box.h index 7998741cf..28a46cc0b 100644 --- a/src/86box.h +++ b/src/86box.h @@ -8,7 +8,7 @@ * * Main include file for the application. * - * Version: @(#)86box.h 1.0.20 2018/03/18 + * Version: @(#)86box.h 1.0.21 2018/03/19 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -134,6 +134,7 @@ extern int config_changed; /* config has changed */ #ifdef HAVE_STDARG_H extern void pclog_ex(const char *fmt, va_list); #endif +extern void pclog_toggle_suppr(void); extern void pclog(const char *fmt, ...); extern void fatal(const char *fmt, ...); extern void set_screen_size(int x, int y); diff --git a/src/disk/hdd_image.c b/src/disk/hdd_image.c index 4e41057fd..272138b38 100644 --- a/src/disk/hdd_image.c +++ b/src/disk/hdd_image.c @@ -8,7 +8,7 @@ * * Handling of hard disk image files. * - * Version: @(#)hdd_image.c 1.0.12 2018/02/08 + * Version: @(#)hdd_image.c 1.0.13 2018/03/19 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -288,29 +288,29 @@ int hdd_image_load(int id) if (ftello64(hdd_images[id].file) < (full_size + hdd_images[id].base)) { s = (full_size + hdd_images[id].base) - ftello64(hdd_images[id].file); prepare_new_hard_disk: - s >>= 9; - t = (s >> 11) << 11; - s -= t; - t >>= 11; + t = s >> 20; /* Amount of 1 MB blocks. */ + s &= 0xfffff; /* 1 MB mask. */ empty_sector_1mb = (char *) malloc(1048576); memset(empty_sector_1mb, 0, 1048576); + /* Temporarily switch off suppression of seen messages so that the + progress gets displayed. */ + pclog_toggle_suppr(); pclog("Writing image sectors: ["); - if (s > 0) { - for (i = 0; i < s; i++) { + + /* First, write all the 1 MB blocks. */ + if (t > 0) { + for (i = 0; i < t; i++) { + fwrite(empty_sector_1mb, 1, 1045876, hdd_images[id].file); pclog("#"); - fwrite(empty_sector, 1, 512, hdd_images[id].file); } } - if (t > 0) { - for (i = 0; i < t; i++) { - pclog("#"); - fwrite(empty_sector_1mb, 1, 1045876, hdd_images[id].file); - } - } - pclog("]\n"); + /* Then, write the remainder. */ + fwrite(empty_sector_1mb, 1, s, hdd_images[id].file); + pclog("#]\n"); + pclog_toggle_suppr(); free(empty_sector_1mb); } diff --git a/src/pc.c b/src/pc.c index 172875c0a..09268e0c5 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.67 2018/03/19 + * Version: @(#)pc.c 1.0.68 2018/03/19 * * Authors: Sarah Walker, * Miran Grca, @@ -170,9 +170,13 @@ int unscaled_size_x = SCREEN_RES_X, /* current unscaled size X */ efscrnsz_y = SCREEN_RES_Y; +#ifndef RELEASE_BUILD static char buff[1024]; static int seen = 0; +static int suppr_seen = 1; +#endif + /* * Log something to the logfile or stdout. * @@ -197,10 +201,10 @@ pclog_ex(const char *fmt, va_list ap) } vsprintf(temp, fmt, ap); - if (! strcmp(buff, temp)) { + if (suppr_seen && ! strcmp(buff, temp)) { seen++; } else { - if (seen) { + if (suppr_seen && seen) { fprintf(stdlog, "*** %d repeats ***\n", seen); } seen = 0; @@ -213,6 +217,15 @@ pclog_ex(const char *fmt, va_list ap) } +void +pclog_toggle_suppr(void) +{ +#ifndef RELEASE_BUILD + suppr_seen ^= 1; +#endif +} + + /* Log something. We only do this in non-release builds. */ void pclog(const char *fmt, ...) diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 6f380a4b9..6544035b6 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.45 2018/03/19 + * Version: @(#)win_settings.c 1.0.46 2018/03/19 * * Author: Miran Grca, * @@ -2986,10 +2986,9 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM } memset(buf, 0, 512); - size >>= 9; - r = (size >> 11) << 11; - size -= r; - r >>= 11; + + r = size >> 20; + size &= 0xfffff; if (size || r) { h = GetDlgItem(hdlg, IDT_1731); @@ -3005,10 +3004,10 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM ShowWindow(h, SW_HIDE); h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); - SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) (size + r - 1)); - SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0); EnableWindow(h, TRUE); ShowWindow(h, SW_SHOW); + SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) r); + SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0); h = GetDlgItem(hdlg, IDT_1752); EnableWindow(h, TRUE); @@ -3017,11 +3016,8 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM if (size) { - for (i = 0; i < size; i++) - { - fwrite(buf, 1, 512, f); - SendMessage(h, PBM_SETPOS, (WPARAM) i, (LPARAM) 0); - } + fwrite(buf, 1, size, f); + SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); } if (r) @@ -3031,7 +3027,7 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM for (i = 0; i < r; i++) { fwrite(big_buf, 1, 1048576, f); - SendMessage(h, PBM_SETPOS, (WPARAM) (size + i), (LPARAM) 0); + SendMessage(h, PBM_SETPOS, (WPARAM) (size + 1), (LPARAM) 0); } free(big_buf); } From 9faea517a4ddc827fb925579ef98a6196ab99172 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Mar 2018 09:56:39 +0100 Subject: [PATCH 17/39] Removed some leftovers of a scrapped attempt at something from cdrom_image.cc. --- src/cdrom/cdrom_image.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cdrom/cdrom_image.cc b/src/cdrom/cdrom_image.cc index 50cee9e20..1df0c3a2d 100644 --- a/src/cdrom/cdrom_image.cc +++ b/src/cdrom/cdrom_image.cc @@ -837,7 +837,7 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, uint32_t temp; int first_track; - int last_track, last_track_pos; + int last_track; int number; unsigned char attr; TMSF tmsf; @@ -870,7 +870,6 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, break; cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - last_track_pos = 0; b[len++] = 0; /* reserved */ b[len++] = attr; b[len++] = number; /* track number */ From 433055ea09157da08a4d860ac6a3672f2349eef3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Mar 2018 13:52:06 +0100 Subject: [PATCH 18/39] A minor fix to the ATI Korean VGA by greatpsycho; Added the Cirrus Logic CL-GD 5446 (two variants) and CL-GD 5480. --- src/video/vid_ati28800.c | 24 +++++----- src/video/vid_cl54xx.c | 95 ++++++++++++++++++++++++++++++++++++---- src/video/vid_cl54xx.h | 5 ++- src/video/vid_table.c | 9 ++-- src/video/video.h | 11 +++-- 5 files changed, 115 insertions(+), 29 deletions(-) diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 17c6f7b71..a85acab9f 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.14 2018/03/19 + * Version: @(#)vid_ati28800.c 1.0.15 2018/03/20 * * Authors: Sarah Walker, * Miran Grca, @@ -553,17 +553,6 @@ ati28800_force_redraw(void *priv) ati->svga.fullchange = changeframecount; } -void ati28800k_add_status_info(char *s, int max_len, void *p) -{ - ati28800_t *ati28800 = (ati28800_t *)p; - char temps[128]; - - svga_add_status_info(s, max_len, &ati28800->svga); - - sprintf(temps, "Korean SVGA mode enabled : %s\n\n", ati28800->ksc5601_mode_enabled ? "Yes" : "No"); - strncat(s, temps, max_len); -} - static void ati28800_add_status_info(char *s, int max_len, void *priv) { ati28800_t *ati = (ati28800_t *)priv; @@ -571,6 +560,17 @@ static void ati28800_add_status_info(char *s, int max_len, void *priv) svga_add_status_info(s, max_len, &ati->svga); } +void ati28800k_add_status_info(char *s, int max_len, void *p) +{ + ati28800_t *ati28800 = (ati28800_t *)p; + char temps[128]; + + ati28800_add_status_info(s, max_len, p); + + sprintf(temps, "Korean SVGA mode enabled : %s\n\n", ati28800->ksc5601_mode_enabled ? "Yes" : "No"); + strncat(s, temps, max_len); +} + static const device_config_t ati28800_config[] = { diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index de04c6fb2..168f1586b 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, CL-GD 5430, CL-GD 5434 and CL-GD 5436 are supported). * - * Version: @(#)vid_cl_54xx.c 1.0.10 2018/03/18 + * Version: @(#)vid_cl_54xx.c 1.0.11 2018/03/20 * * Authors: Sarah Walker, * Barry Rodewald, @@ -39,7 +39,6 @@ #include "vid_svga_render.h" #include "vid_cl54xx.h" -#define BIOS_GD5424_PATH L"roms/video/cirruslogic/cl5424.bin" #define BIOS_GD5426_PATH L"roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin" #define BIOS_GD5428_PATH L"roms/video/cirruslogic/vlbusjapan.BIN" #define BIOS_GD5429_PATH L"roms/video/cirruslogic/5429.vbi" @@ -47,14 +46,18 @@ #define BIOS_GD5430_PCI_PATH L"roms/video/cirruslogic/pci.bin" #define BIOS_GD5434_PATH L"roms/video/cirruslogic/gd5434.bin" #define BIOS_GD5436_PATH L"roms/video/cirruslogic/5436.vbi" +#define BIOS_GD5446_PATH L"roms/video/cirruslogic/5446BV.VBI" +#define BIOS_GD5446_STB_PATH L"roms/video/cirruslogic/stb nitro64v.BIN" +#define BIOS_GD5480_PATH L"roms/video/cirruslogic/clgd5480.rom" -#define CIRRUS_ID_CLGD5424 0x94 #define CIRRUS_ID_CLGD5426 0x90 #define CIRRUS_ID_CLGD5428 0x98 #define CIRRUS_ID_CLGD5429 0x9c #define CIRRUS_ID_CLGD5430 0xa0 #define CIRRUS_ID_CLGD5434 0xa8 #define CIRRUS_ID_CLGD5436 0xac +#define CIRRUS_ID_CLGD5446 0xb8 +#define CIRRUS_ID_CLGD5480 0xbc /* sequencer 0x07 */ #define CIRRUS_SR7_BPP_VGA 0x00 @@ -588,13 +591,13 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) } } else if (gd54xx->pci) { base = gd54xx->lfb_base; - if (svga->crtc[0x27] == CIRRUS_ID_CLGD5436) + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) size = 16 * 1024 * 1024; else size = 4 * 1024 * 1024; } else { /*VLB*/ base = 128*1024*1024; - if (svga->crtc[0x27] == CIRRUS_ID_CLGD5436) + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) size = 16 * 1024 * 1024; else size = 4 * 1024 * 1024; @@ -1690,7 +1693,7 @@ gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) else gd54xx->blt.dst_addr &= 0x1fffff; - if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5436) && (gd54xx->blt.status & CIRRUS_BLT_AUTOSTART)) { + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) && (gd54xx->blt.status & CIRRUS_BLT_AUTOSTART)) { if (gd54xx->blt.mode == CIRRUS_BLTMODE_MEMSYSSRC) { gd54xx->blt.sys_tx = 1; gd54xx->blt.sys_cnt = 0; @@ -1729,7 +1732,7 @@ gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) break; case 0x1b: - if (svga->crtc[0x27] == CIRRUS_ID_CLGD5436) + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) gd54xx->blt.modeext = val; break; @@ -2294,7 +2297,7 @@ static void { gd54xx_t *gd54xx = malloc(sizeof(gd54xx_t)); svga_t *svga = &gd54xx->svga; - int id = info->local; + int id = info->local & 0xff; wchar_t *romfn = NULL; memset(gd54xx, 0, sizeof(gd54xx_t)); @@ -2328,7 +2331,18 @@ static void case CIRRUS_ID_CLGD5436: romfn = BIOS_GD5436_PATH; break; - } + + case CIRRUS_ID_CLGD5446: + if (info->local & 0x100) + romfn = BIOS_GD5446_STB_PATH; + else + romfn = BIOS_GD5446_PATH; + break; + + case CIRRUS_ID_CLGD5480: + romfn = BIOS_GD5480_PATH; + break; + } gd54xx->vram_size = device_get_config_int("memory"); gd54xx->vram_mask = (gd54xx->vram_size << 20) - 1; @@ -2413,6 +2427,24 @@ gd5436_available(void) return rom_present(BIOS_GD5436_PATH); } +static int +gd5446_available(void) +{ + return rom_present(BIOS_GD5446_PATH); +} + +static int +gd5446_stb_available(void) +{ + return rom_present(BIOS_GD5446_STB_PATH); +} + +static int +gd5480_available(void) +{ + return rom_present(BIOS_GD5480_PATH); +} + void gd54xx_close(void *p) { @@ -2669,3 +2701,48 @@ const device_t gd5436_pci_device = gd54xx_add_status_info, gd5434_config }; + +const device_t gd5446_pci_device = +{ + "Cirrus Logic CL-GD 5446 (PCI)", + DEVICE_PCI, + CIRRUS_ID_CLGD5446, + gd54xx_init, + gd54xx_close, + NULL, + gd5446_available, + gd54xx_speed_changed, + gd54xx_force_redraw, + gd54xx_add_status_info, + gd5434_config +}; + +const device_t gd5446_stb_pci_device = +{ + "STB Nitro 64V (PCI)", + DEVICE_PCI, + CIRRUS_ID_CLGD5446, + gd54xx_init, + gd54xx_close, + NULL, + gd5446_stb_available, + gd54xx_speed_changed, + gd54xx_force_redraw, + gd54xx_add_status_info, + gd5434_config +}; + +const device_t gd5480_pci_device = +{ + "Cirrus Logic CL-GD 5480 (PCI)", + DEVICE_PCI, + CIRRUS_ID_CLGD5480, + gd54xx_init, + gd54xx_close, + NULL, + gd5480_available, + gd54xx_speed_changed, + gd54xx_force_redraw, + gd54xx_add_status_info, + gd5434_config +}; diff --git a/src/video/vid_cl54xx.h b/src/video/vid_cl54xx.h index af7707f0a..91bfa44aa 100644 --- a/src/video/vid_cl54xx.h +++ b/src/video/vid_cl54xx.h @@ -11,4 +11,7 @@ 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; \ No newline at end of file +extern const device_t gd5436_pci_device; +extern const device_t gd5446_pci_device; +extern const device_t gd5446_stb_pci_device; +extern const device_t gd5480_pci_device; \ No newline at end of file diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 365619145..fcb8ff503 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.25 2018/03/19 + * Version: @(#)vid_table.c 1.0.26 2018/03/20 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -131,6 +131,8 @@ video_cards[] = { {"[PCI] Cirrus Logic CL-GD 5430", "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 CL-GD 5434", "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 CL-GD 5436", "cl_gd5436_pci", &gd5436_pci_device, GFX_CL_GD5436_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"[PCI] Cirrus Logic CL-GD 5446", "cl_gd5446_pci", &gd5446_pci_device, GFX_CL_GD5446_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"[PCI] Cirrus Logic CL-GD 5480", "cl_gd5480_pci", &gd5480_pci_device, GFX_CL_GD5480_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}}, #endif @@ -149,6 +151,7 @@ video_cards[] = { {"[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] STB Nitro 64V (CL-GD 5446)", "cl_gd5446_stb_pci", &gd5446_stb_pci_device, GFX_CL_GD5446_STB_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"[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}}, @@ -158,8 +161,8 @@ video_cards[] = { #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}}, #endif - {"[VLB] Diamond SpeedStar PRO (CL-GD5426)", "cl_gd5426_vlb", &gd5426_vlb_device, GFX_CL_GD5426_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}}, + {"[VLB] Diamond SpeedStar PRO (CL-GD 5426)", "cl_gd5426_vlb", &gd5426_vlb_device, GFX_CL_GD5426_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"[VLB] Diamond SpeedStar PRO SE (CL-GD 5430)", "cl_gd5430_vlb", &gd5430_vlb_device, GFX_CL_GD5430_VLB, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"[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}}, diff --git a/src/video/video.h b/src/video/video.h index 4bb7e8dc4..99b54a66f 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.24 2018/03/19 + * Version: @(#)video.h 1.0.25 2018/03/20 * * Authors: Sarah Walker, * Miran Grca, @@ -84,9 +84,12 @@ enum { GFX_CL_GD5430_VLB, /* Diamond SpeedStar PRO SE (Cirrus Logic CL-GD 5430) VLB */ GFX_CL_GD5430_PCI, /* Cirrus Logic CL-GD 5430 PCI */ GFX_CL_GD5434_ISA, /* Cirrus Logic CL-GD 5434 ISA */ - GFX_CL_GD5434_VLB, /* Cirrus Logic CL-GD 5434 VLB */ - GFX_CL_GD5434_PCI, /* Cirrus Logic CL-GD 5434 PCI */ - GFX_CL_GD5436_PCI, /* Cirrus Logic CL-GD 5436 PCI */ + GFX_CL_GD5434_VLB, /* Cirrus Logic CL-GD 5434 VLB */ + GFX_CL_GD5434_PCI, /* Cirrus Logic CL-GD 5434 PCI */ + GFX_CL_GD5436_PCI, /* Cirrus Logic CL-GD 5436 PCI */ + GFX_CL_GD5446_PCI, /* Cirrus Logic CL-GD 5446 PCI */ + GFX_CL_GD5446_STB_PCI, /* STB Nitro 64V (Cirrus Logic CL-GD 5446) PCI */ + GFX_CL_GD5480_PCI, /* Cirrus Logic CL-GD 5480 PCI */ #if defined(DEV_BRANCH) && defined(USE_RIVA) GFX_RIVATNT, /* nVidia Riva TNT */ GFX_RIVATNT2, /* nVidia Riva TNT2 */ From be7fdaf374792e6fd4021367b10fcdaccc524ef2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Mar 2018 14:08:53 +0100 Subject: [PATCH 19/39] The IDE buffer is now once again memset'd to 0x00's at the beginning of ide_atapi_zip_identify(), fixes ATAPI Iomega ZIP drive identification. --- src/disk/hdc_ide.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 889058198..2b2ca6852 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.40 2018/03/18 + * Version: @(#)hdc_ide.c 1.0.41 2018/03/20 * * Authors: Sarah Walker, * Miran Grca, @@ -503,6 +503,7 @@ static void ide_atapi_zip_identify(IDE *ide) uint8_t zip_id; int32_t d; + memset(ide->buffer, 0, 512); zip_id = atapi_zip_drives[ide->channel]; /* Using (2<<5) below makes the ASUS P/I-P54TP4XE misdentify the ZIP drive From f87500ddbf2d5961df0ab9d7a4e488fc874fdfa5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Mar 2018 16:04:09 +0100 Subject: [PATCH 20/39] IDE reset via PCI turbo reset control's hard reset function now only sets the signature for all IDE devices and clears the buffers; The buffers are now memset'd to 0x00's on allocation; The Iomega ZIP drive now issues an IRQ on receipt of the PACKET COMMAND command, fixes it on Windows 98 SE. --- src/disk/hdc_ide.c | 38 ++++++++++++++++++++++++++++++++------ src/disk/hdc_ide.h | 4 +++- src/disk/zip.c | 2 +- src/pci.c | 3 ++- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 2b2ca6852..58fbef1f7 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.41 2018/03/20 + * Version: @(#)hdc_ide.c 1.0.42 2018/03/20 * * Authors: Sarah Walker, * Miran Grca, @@ -508,7 +508,7 @@ static void ide_atapi_zip_identify(IDE *ide) /* Using (2<<5) below makes the ASUS P/I-P54TP4XE misdentify the ZIP drive as a LS-120. */ - ide->buffer[0] = 0x8000 | (0<<8) | 0x80 | (1<<5); /* ATAPI device, direct-access device, removable media, accelerated DRQ */ + ide->buffer[0] = 0x8000 | (0<<8) | 0x80 | (1<<5); /* ATAPI device, direct-access device, removable media, interrupt DRQ */ ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ if (zip_drives[zip_id].is_250) { ide_padstr((char *) (ide->buffer + 23), "42.S", 8); /* Firmware */ @@ -517,6 +517,8 @@ static void ide_atapi_zip_identify(IDE *ide) ide_padstr((char *) (ide->buffer + 23), "E.08", 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), "IOMEGA ZIP 100 ATAPI", 40); /* Model */ } + + ide->buffer[48] = 1; /*Dword transfers supported*/ ide->buffer[49] = 0x200; /* LBA supported */ /* Note by Kotori: Look at this if this is supported by ZIP at all. */ @@ -544,6 +546,7 @@ static void ide_atapi_zip_identify(IDE *ide) ide->buffer[52] = 120; ide->buffer[53] = 2; /*Words 64-70 are valid*/ ide->buffer[63] = 0x0003; /*Multi-word DMA 0 & 1*/ + ide->buffer[88] = 7; ide->buffer[64] = 0x0001; /*PIO Mode 3*/ ide->buffer[65] = 120; ide->buffer[66] = 120; @@ -556,11 +559,12 @@ static void ide_atapi_zip_identify(IDE *ide) d <<= 8; if ((ide->mdma_mode & 0x300) == 0x200) ide->buffer[88] |= d; + else if ((ide->mdma_mode & 0x300) == 0x100) + ide->buffer[63] |= d; else if ((ide->mdma_mode & 0x300) == 0x400) { if ((ide->mdma_mode & 0xff) >= 3) ide->buffer[64] |= d; - } else - ide->buffer[63] |= d; + } ide_log("PIDENTIFY DMA Mode: %04X, %04X\n", ide->buffer[62], ide->buffer[63]); } } @@ -686,7 +690,7 @@ static int ide_set_features(IDE *ide) if (!PCI || !dma || (ide->board >= 2)) max_pio = 0; else - max_pio = 2; + max_pio = 4; } ide_log("Features code %02X\n", features); @@ -863,6 +867,7 @@ 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); + memset(ide_drives[hdd[d].ide_channel].sector_buffer, 0, 256*512); if (++c >= (IDE_NUM+XTIDE_NUM)) break; } if ((hdd[d].bus==HDD_BUS_XTIDE) && (hdd[d].xtide_channel < XTIDE_NUM)) @@ -870,6 +875,7 @@ void ide_reset(void) 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); + memset(ide_drives[hdd[d].ide_channel].sector_buffer, 0, 256*512); if (++c >= (IDE_NUM+XTIDE_NUM)) break; } } @@ -882,8 +888,10 @@ void ide_reset(void) 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) + if (ide_drives[d].type != IDE_NONE) { ide_drives[d].buffer = (uint16_t *) malloc(65536 * sizeof(uint16_t)); + memset(ide_drives[d].buffer, 0, 65536 * sizeof(uint16_t)); + } ide_set_signature(&ide_drives[d]); @@ -909,6 +917,23 @@ void ide_reset(void) } +void ide_set_all_signatures(void) +{ + int d; + + for (d = 0; d < IDE_NUM; d++) + { + ide_set_signature(&ide_drives[d]); + + if (ide_drives[d].sector_buffer) + memset(ide_drives[d].sector_buffer, 0, 256*512); + + if (ide_drives[d].buffer) + memset(ide_drives[d].buffer, 0, 65536 * sizeof(uint16_t)); + } +} + + void ide_reset_hard(void) { int d; @@ -1517,6 +1542,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) zip[atapi_zip_drives[ide->channel]].pos=0; zip[atapi_zip_drives[ide->channel]].phase = 1; zip[atapi_zip_drives[ide->channel]].status = READY_STAT | DRQ_STAT | (zip[atapi_zip_drives[ide->channel]].status & ERR_STAT); + ide_irq_raise(ide); /* Interrupt IRQ, requires IRQ on any DRQ. */ } else if (ide_drive_is_cdrom(ide)) { diff --git a/src/disk/hdc_ide.h b/src/disk/hdc_ide.h index 74e938b2e..5258d389e 100644 --- a/src/disk/hdc_ide.h +++ b/src/disk/hdc_ide.h @@ -9,7 +9,7 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)hdd_ide.h 1.0.7 2018/03/15 + * Version: @(#)hdd_ide.h 1.0.8 2018/03/20 * * Authors: Sarah Walker, * Miran Grca, @@ -86,6 +86,8 @@ extern void ide_init_first(void); extern void ide_reset(void); extern void ide_reset_hard(void); +extern void ide_set_all_signatures(void); + extern void ide_xtide_init(void); extern void ide_pri_enable(void); diff --git a/src/disk/zip.c b/src/disk/zip.c index a02f64204..2e241bee1 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -9,7 +9,7 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.c 1.0.13 2018/03/18 + * Version: @(#)zip.c 1.0.14 2018/03/20 * * Author: Miran Grca, * diff --git a/src/pci.c b/src/pci.c index 8ebc3fd6a..32ca3499d 100644 --- a/src/pci.c +++ b/src/pci.c @@ -654,7 +654,8 @@ static void trc_reset(uint8_t val) pci_reset_handler.super_io_reset(); } - ide_reset(); + /* ide_reset(); */ + ide_set_all_signatures(); for (i = 0; i < CDROM_NUM; i++) { if (!cdrom_drives[i].bus_type) From df746297c2c7f46b7ffb54221d6c66870fb0801c Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Mar 2018 18:32:18 +0100 Subject: [PATCH 21/39] Several CD-ROM fixes. --- src/cdrom/cdrom.c | 42 +++++++++++++++++++++++---------------- src/cdrom/cdrom.h | 4 +--- src/disk/zip.c | 3 +-- src/disk/zip.h | 4 +--- src/pci.c | 10 +++++++++- src/win/win_cdrom_ioctl.c | 11 ++++++++-- 6 files changed, 46 insertions(+), 28 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 6fa7b7e50..45086635a 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.42 2018/03/19 + * Version: @(#)cdrom.c 1.0.43 2018/03/20 * * Author: Miran Grca, * @@ -128,7 +128,7 @@ const uint8_t cdrom_command_flags[0x100] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED | CHECK_READY, - IMPLEMENTED | CHECK_READY | ALLOW_UA, /* Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS + IMPLEMENTED | CHECK_READY, /* Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS NOTE: The ATAPI reference says otherwise, but I think this is a question of interpreting things right - the UNIT ATTENTION condition we have here is a tradition from not ready to ready, by definition the drive @@ -449,10 +449,19 @@ void cdrom_init(int id, int cdb_len_setting) { cdrom_t *dev; + uint8_t *trcbuf; + uint32_t tcap; + if (id >= CDROM_NUM) return; dev = cdrom[id]; + tcap = dev->cdrom_capacity; + trcbuf = (uint8_t *) malloc(16); + memcpy(trcbuf, dev->rcbuf, 16); memset(dev, 0, sizeof(cdrom_t)); + memcpy(dev->rcbuf, trcbuf, 16); + free(trcbuf); + dev->cdrom_capacity = tcap; dev->requested_blocks = 1; if (cdb_len_setting <= 1) dev->cdb_len_setting = cdb_len_setting; @@ -468,7 +477,6 @@ void cdrom_init(int id, int cdb_len_setting) cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n", id, cdrom_drives[id].bus_type, cdrom_drives[id].bus_mode); if (cdrom_drives[id].bus_type < CDROM_BUS_SCSI) cdrom_set_signature(id); - cdrom_drives[id].max_blocks_at_once = 85; dev->status = READY_STAT | DSC_STAT; dev->pos = 0; dev->packet_status = 0xff; @@ -1236,29 +1244,29 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, uint32_t *len) int last_valid_data_pos = 0; - if (cdrom_drives[id].handler->pass_through) { - cdsize = cdrom_drives[id].handler->size(id); + cdsize = cdrom_drives[id].handler->size(id); + if (dev->sector_pos >= cdsize) { + cdrom_log("CD-ROM %i: Trying to read from beyond the end of disc (%i >= %i)\n", id, dev->sector_pos, cdsize); + cdrom_lba_out_of_range(id); + return 0; + } + + if ((dev->sector_pos + dev->sector_len - 1) >= cdsize) { + cdrom_log("CD-ROM %i: Trying to read to beyond the end of disc (%i >= %i)\n", id, (dev->sector_pos + dev->sector_len - 1), cdsize); + cdrom_lba_out_of_range(id); + return 0; + } + + if (cdrom_drives[id].handler->pass_through) { ret = cdrom_pass_through(id, len, dev->current_cdb, cdbufferb + dev->data_pos); dev->data_pos += *len; if (!ret) return 0; - if (dev->sector_pos > (cdsize - 1)) { - /* cdrom_log("CD-ROM %i: Trying to read beyond the end of disc\n", id); */ - cdrom_lba_out_of_range(id); - return 0; - } - dev->old_len = *len; } else { - if (dev->sector_pos > (cdrom_drives[id].handler->size(id) - 1)) { - /* cdrom_log("CD-ROM %i: Trying to read beyond the end of disc\n", id); */ - cdrom_lba_out_of_range(id); - return 0; - } - dev->old_len = 0; *len = 0; diff --git a/src/cdrom/cdrom.h b/src/cdrom/cdrom.h index 9b2e97e59..1a2607507 100644 --- a/src/cdrom/cdrom.h +++ b/src/cdrom/cdrom.h @@ -9,7 +9,7 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)cdrom.h 1.0.9 2018/03/18 + * Version: @(#)cdrom.h 1.0.10 2018/03/20 * * Author: Miran Grca, * @@ -170,8 +170,6 @@ typedef struct { } cdrom_t; typedef struct { - int max_blocks_at_once; - CDROM *handler; int host_drive; diff --git a/src/disk/zip.c b/src/disk/zip.c index 2e241bee1..09fb5cd2d 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -9,7 +9,7 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.c 1.0.14 2018/03/20 + * Version: @(#)zip.c 1.0.15 2018/03/20 * * Author: Miran Grca, * @@ -654,7 +654,6 @@ void zip_init(int id, int cdb_len_setting) zip_log("ZIP %i: Bus type %i, bus mode %i\n", id, zip_drives[id].bus_type, zip_drives[id].bus_mode); if (zip_drives[id].bus_type < ZIP_BUS_SCSI) zip_set_signature(id); - zip_drives[id].max_blocks_at_once = 85; zip[id].status = READY_STAT | DSC_STAT; zip[id].pos = 0; zip[id].packet_status = 0xff; diff --git a/src/disk/zip.h b/src/disk/zip.h index 1968b79ff..63b96f9b6 100644 --- a/src/disk/zip.h +++ b/src/disk/zip.h @@ -9,7 +9,7 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.h 1.0.3 2018/03/17 + * Version: @(#)zip.h 1.0.4 2018/03/20 * * Author: Miran Grca, * @@ -122,8 +122,6 @@ typedef struct { } zip_t; typedef struct { - int max_blocks_at_once; - int host_drive; int prev_host_drive; diff --git a/src/pci.c b/src/pci.c index 32ca3499d..3ec8e186b 100644 --- a/src/pci.c +++ b/src/pci.c @@ -16,6 +16,7 @@ #include "cdrom/cdrom.h" #include "disk/hdc.h" #include "disk/hdc_ide.h" +#include "disk/zip.h" static uint64_t pci_irq_hold[16]; @@ -658,11 +659,18 @@ static void trc_reset(uint8_t val) ide_set_all_signatures(); for (i = 0; i < CDROM_NUM; i++) { - if (!cdrom_drives[i].bus_type) + if ((cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) || (cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA)) { cdrom_reset(i); } } + for (i = 0; i < ZIP_NUM; i++) + { + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI_PIO_ONLY) || (zip_drives[i].bus_type == ZIP_BUS_ATAPI_PIO_AND_DMA)) + { + zip_reset(i); + } + } port_92_reset(); keyboard_at_reset(); diff --git a/src/win/win_cdrom_ioctl.c b/src/win/win_cdrom_ioctl.c index 580788025..a54231037 100644 --- a/src/win/win_cdrom_ioctl.c +++ b/src/win/win_cdrom_ioctl.c @@ -9,7 +9,7 @@ * Implementation of the CD-ROM host drive IOCTL interface for * Windows using SCSI Passthrough Direct. * - * Version: @(#)cdrom_ioctl.c 1.0.14 2018/03/17 + * Version: @(#)cdrom_ioctl.c 1.0.15 2018/03/20 * * Authors: Sarah Walker, * Miran Grca, @@ -1202,6 +1202,7 @@ static uint32_t ioctl_size(uint8_t id) { uint8_t capacity_buffer[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; uint32_t capacity = 0; + ioctl_read_capacity(id, capacity_buffer); capacity = ((uint32_t) capacity_buffer[0]) << 24; capacity |= ((uint32_t) capacity_buffer[1]) << 16; @@ -1260,16 +1261,22 @@ int ioctl_hopen(uint8_t id) return 0; } +#define rcs "Read capacity: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n" +#define drb dev->rcbuf + int ioctl_open(uint8_t id, char d) { cdrom_t *dev = cdrom[id]; sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d); + pclog("IOCTL path: %s\n", cdrom_ioctl[id].ioctl_path); dev->disc_changed = 1; cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); cdrom_drives[id].handler = &ioctl_cdrom; dev->handler_inited=1; - cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ + cdrom_ioctl[id].capacity_read=0; /* With these two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ ioctl_read_capacity(id, NULL); + pclog(rcs, drb[0], drb[1], drb[2], drb[3], drb[4], drb[5], drb[6], drb[7], + drb[8], drb[9], drb[10], drb[11], drb[12], drb[13], drb[14], drb[15]); CloseHandle(cdrom_ioctl_windows[id].hIOCTL); cdrom_ioctl_windows[id].hIOCTL = NULL; return 0; From ab3cce21ee5756b267298db9d2df10f4fb5e6cf4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Mar 2018 19:45:45 +0100 Subject: [PATCH 22/39] The Iomega ZIP sector access commands no longer read/write the data sector by sector (there was absolutely no need for that since that was done before ever asserting DRQ and was a left-over from the CD-ROM where it does that to make IOCTL happy); The CD-ROM and Iomega ZIP drives now clear the error bit when the PACKET COMMAND command is issued, fixes the Iomega GUEST.EXE for DOS hang when run while the Iomega ZIP drive is empty. --- src/disk/hdc_ide.c | 6 +++--- src/disk/zip.c | 50 +++++++++++++++++----------------------------- 2 files changed, 21 insertions(+), 35 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 58fbef1f7..d5a5f36d5 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.42 2018/03/20 + * Version: @(#)hdc_ide.c 1.0.43 2018/03/20 * * Authors: Sarah Walker, * Miran Grca, @@ -1541,7 +1541,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) zip[atapi_zip_drives[ide->channel]].packet_status = ZIP_PHASE_IDLE; zip[atapi_zip_drives[ide->channel]].pos=0; zip[atapi_zip_drives[ide->channel]].phase = 1; - zip[atapi_zip_drives[ide->channel]].status = READY_STAT | DRQ_STAT | (zip[atapi_zip_drives[ide->channel]].status & ERR_STAT); + zip[atapi_zip_drives[ide->channel]].status = READY_STAT | DRQ_STAT; ide_irq_raise(ide); /* Interrupt IRQ, requires IRQ on any DRQ. */ } else if (ide_drive_is_cdrom(ide)) @@ -1549,7 +1549,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) cdrom[atapi_cdrom_drives[ide->channel]]->packet_status = CDROM_PHASE_IDLE; cdrom[atapi_cdrom_drives[ide->channel]]->pos=0; cdrom[atapi_cdrom_drives[ide->channel]]->phase = 1; - cdrom[atapi_cdrom_drives[ide->channel]]->status = READY_STAT | DRQ_STAT | (cdrom[atapi_cdrom_drives[ide->channel]]->status & ERR_STAT); + cdrom[atapi_cdrom_drives[ide->channel]]->status = READY_STAT | DRQ_STAT; } else { diff --git a/src/disk/zip.c b/src/disk/zip.c index 09fb5cd2d..6ba2d9896 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -9,7 +9,7 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.c 1.0.15 2018/03/20 + * Version: @(#)zip.c 1.0.16 2018/03/20 * * Author: Miran Grca, * @@ -455,6 +455,7 @@ static const mode_sense_pages_t zip_250_mode_sense_pages_changeable = static mode_sense_pages_t zip_mode_sense_pages_saved[ZIP_NUM]; +#define ENABLE_ZIP_LOG 1 #ifdef ENABLE_ZIP_LOG int zip_do_log = ENABLE_ZIP_LOG; #endif @@ -1151,37 +1152,12 @@ static void zip_data_phase_error(uint8_t id) #define zipbufferb zip[id].buffer -int zip_data(uint8_t id, uint32_t *len, int out) -{ - int i = 0; - - if (zip[id].sector_pos >= zip_drives[id].medium_size) { - zip_log("ZIP %i: Trying to %s beyond the end of disk\n", id, out ? "write" : "read"); - zip_lba_out_of_range(id); - return 0; - } - - *len = 0; - - for (i = 0; i < zip[id].requested_blocks; i++) { - fseek(zip_drives[id].f, zip_drives[id].base + (zip[id].sector_pos << 9) + *len, SEEK_SET); - if (out) - fwrite(zipbufferb + *len, 1, 512, zip_drives[id].f); - else - fread(zipbufferb + *len, 1, 512, zip_drives[id].f); - - *len += 512; - } - - return 1; -} - int zip_blocks(uint8_t id, uint32_t *len, int first_batch, int out) { - int ret = 0; - zip[id].data_pos = 0; + *len = 0; + if (!zip[id].sector_len) { zip_command_complete(id); return -1; @@ -1189,13 +1165,22 @@ int zip_blocks(uint8_t id, uint32_t *len, int first_batch, int out) zip_log("%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", zip[id].requested_blocks, zip[id].sector_pos); - ret = zip_data(id, len, out); + if (zip[id].sector_pos >= zip_drives[id].medium_size) { + zip_log("ZIP %i: Trying to %s beyond the end of disk\n", id, out ? "write" : "read"); + zip_lba_out_of_range(id); + return 0; + } + + *len = zip[id].requested_blocks << 9; + + fseek(zip_drives[id].f, zip_drives[id].base + (zip[id].sector_pos << 9), SEEK_SET); + if (out) + fwrite(zipbufferb, 1, *len, zip_drives[id].f); + else + fread(zipbufferb, 1, *len, zip_drives[id].f); zip_log("%s %i bytes of blocks...\n", out ? "Written" : "Read", *len); - if (!ret) - return 0; - zip[id].sector_pos += zip[id].requested_blocks; zip[id].sector_len -= zip[id].requested_blocks; @@ -2387,6 +2372,7 @@ void zip_phase_callback(uint8_t id) zip_log("ZIP %i: ZIP_PHASE_ERROR\n", id); zip[id].status = READY_STAT | ERR_STAT; zip[id].phase = 3; + zip[id].packet_status = 0xFF; zip_irq_raise(id); ui_sb_update_icon(SB_ZIP | id, 0); return; From 77817f9437037d9074f8f2c947e5d3b3ec9e11cf Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Mar 2018 19:46:47 +0100 Subject: [PATCH 23/39] Disabled the Iomega ZIP logging. --- src/disk/zip.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/disk/zip.c b/src/disk/zip.c index 6ba2d9896..eea0eedbf 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -9,7 +9,7 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.c 1.0.16 2018/03/20 + * Version: @(#)zip.c 1.0.17 2018/03/20 * * Author: Miran Grca, * @@ -455,7 +455,6 @@ static const mode_sense_pages_t zip_250_mode_sense_pages_changeable = static mode_sense_pages_t zip_mode_sense_pages_saved[ZIP_NUM]; -#define ENABLE_ZIP_LOG 1 #ifdef ENABLE_ZIP_LOG int zip_do_log = ENABLE_ZIP_LOG; #endif From 76f0cb2790b52b46a37c262290797835df80cbc2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Mar 2018 19:54:06 +0100 Subject: [PATCH 24/39] Updated the ROM set link in README.md. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b0c10351c..b554b0ac6 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ guide: 7. In order to test your fresh build, replace the `86Box.exe` in your current 86Box enviroment with your freshly built one. If you do not have a pre-existing 86Box environment, download the latest successful build from - http://ci.86box.net, and the ROM set from http://tinyurl.com/rs20180312. + http://ci.86box.net, and the ROM set from http://tinyurl.com/rs20180320. 8. Enjoy using and testing the emulator! :) If you encounter issues at any step or have additional questions, please join From 3a18912d5af3ade2430553befa955be9fdd662dd Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Mar 2018 20:02:22 +0100 Subject: [PATCH 25/39] The KMS-C-02 now correctly initializes with the AMI AT keyboard controller, should hopefully fix the last keyboard problems on this machine. --- src/machine/m_at_scat.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/machine/m_at_scat.c b/src/machine/m_at_scat.c index 39ee46ea3..fdb56fe72 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.11 2018/03/18 + * Version: @(#)m_at_scat.c 1.0.12 2018/03/20 * * Authors: Original by GreatPsycho for PCem. * Fred N. van Kempen, @@ -27,6 +27,7 @@ #include "../cpu/x86.h" #include "../floppy/fdd.h" #include "../floppy/fdc.h" +#include "../keyboard.h" #include "../io.h" #include "../mem.h" #include "../nmi.h" @@ -724,7 +725,9 @@ machine_at_scat_init(const machine_t *model) void machine_at_scatsx_init(const machine_t *model) { - machine_at_init(model); + machine_at_common_init(model); + + device_add(&keyboard_at_ami_device); device_add(&fdc_at_device); scatsx_init(); From e42c24868c2d33924a46e7bd31be383092e05650 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Mar 2018 20:32:14 +0100 Subject: [PATCH 26/39] Fixed one instance of the SPINNER configuration type handler to handle it correctly by using wide strings and then converting to narrow strings, fixes #270. --- src/win/win_devconf.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/win/win_devconf.c b/src/win/win_devconf.c index d738ab39e..5b1e80535 100644 --- a/src/win/win_devconf.c +++ b/src/win/win_devconf.c @@ -8,7 +8,7 @@ * * Windows device configuration dialog implementation. * - * Version: @(#)win_devconf.c 1.0.16 2018/03/18 + * Version: @(#)win_devconf.c 1.0.17 2018/03/20 * * Authors: Sarah Walker, * Miran Grca, @@ -241,7 +241,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) val_int = config->spinner.min; SendMessage(h, WM_GETTEXT, 79, (LPARAM)ws); - wcstombs(s, ws, 79); + wcstombs(s, ws, 512); sscanf(s, "%i", &c); if (val_int != c) @@ -330,7 +330,8 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) break; case CONFIG_SPINNER: - SendMessage(h, WM_GETTEXT, 79, (LPARAM)s); + SendMessage(h, WM_GETTEXT, 79, (LPARAM)ws); + wcstombs(s, ws, 512); sscanf(s, "%i", &c); if (c > config->spinner.max) c = config->spinner.max; From 32fa58a568ec2d5ce67d9953e1eb1d12a9e621b1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Mar 2018 22:00:58 +0100 Subject: [PATCH 27/39] Fixed NVRAM loading and saving for the two PS/2 Model 70 types. --- src/nvr_ps2.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/nvr_ps2.c b/src/nvr_ps2.c index ff887ca2c..3c7d68d7d 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.5 2018/03/18 + * Version: @(#)nvr_ps2.c 1.0.6 2018/03/20 * * Authors: Fred N. van Kempen, * Sarah Walker, @@ -115,6 +115,12 @@ ps2_nvr_init(const device_t *info) ps2_nvr_read,NULL,NULL, ps2_nvr_write,NULL,NULL, nvr); switch (romset) { + case ROM_IBMPS2_M70_TYPE3: + f = nvr_fopen(L"ibmps2_m70_type3_sec.nvr", L"rb"); + break; + case ROM_IBMPS2_M70_TYPE4: + f = nvr_fopen(L"ibmps2_m70_type4_sec.nvr", L"rb"); + break; case ROM_IBMPS2_M80: f = nvr_fopen(L"ibmps2_m80_sec.nvr", L"rb"); break; @@ -138,10 +144,10 @@ ps2_nvr_close(void *priv) switch (romset) { case ROM_IBMPS2_M70_TYPE3: - f = nvr_fopen(L"ibmps2_m70_type3_sec.nvr", L"rb"); + f = nvr_fopen(L"ibmps2_m70_type3_sec.nvr", L"wb"); break; case ROM_IBMPS2_M70_TYPE4: - f = nvr_fopen(L"ibmps2_m70_type4_sec.nvr", L"rb"); + f = nvr_fopen(L"ibmps2_m70_type4_sec.nvr", L"wb"); break; case ROM_IBMPS2_M80: f = nvr_fopen(L"ibmps2_m80_sec.nvr", L"wb"); From 0ed4750eac61667f0b19b5483b23ebd0e694388e Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Mar 2018 22:06:15 +0100 Subject: [PATCH 28/39] Added the split mapping for the two PS/2 Model 70 types. --- src/machine/m_ps2_mca.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index 5033945c2..a51fe1143 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -956,11 +956,11 @@ static void mem_encoding_write_cached(uint16_t addr, uint8_t val, void *p) switch (addr) { - case 0xe0: - ps2.mem_regs[0] = val; - break; - case 0xe1: - ps2.mem_regs[1] = val; + case 0xe0: + ps2.mem_regs[0] = val; + break; + case 0xe1: + ps2.mem_regs[1] = val; break; case 0xe2: old = ps2.mem_regs[2]; @@ -1042,13 +1042,27 @@ static void ps2_mca_board_model_70_type34_init(int is_type4) if (is_type4) ps2.option[2] |= 0x04; /*486 CPU*/ + 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); + mem_mapping_add(&ps2.cache_mapping, 0, is_type4 ? (8 * 1024) : (64 * 1024), ps2_read_cache_ram, ps2_read_cache_ramw, ps2_read_cache_raml, - ps2_write_cache_ram, + ps2_write_cache_ram, NULL, NULL, ps2_cache, @@ -1095,8 +1109,8 @@ static void ps2_mca_board_model_70_type34_init(int is_type4) NULL); mem_mapping_disable(&ps2.expansion_mapping); } - - device_add(&ps1vga_device); + + device_add(&ps1vga_device); } static void ps2_mca_board_model_80_type2_init(int is486) From 8e22d282d16783d45c655bbc291352f93a7ba8c0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 21 Mar 2018 14:46:54 +0100 Subject: [PATCH 29/39] More CD-ROM fixes, Little Big Adventure now looks again; Made SCAT logging optional and disabled by default. --- src/Makefile.local | 5 +- src/cdrom/cdrom.c | 130 ++++++++++++++++++++++++++----------- src/cdrom/cdrom_dosbox.cpp | 5 +- src/cdrom/cdrom_image.cc | 15 +++-- src/machine/m_at_scat.c | 47 ++++++++++---- src/win/win_cdrom_ioctl.c | 66 +++++++++++-------- 6 files changed, 181 insertions(+), 87 deletions(-) diff --git a/src/Makefile.local b/src/Makefile.local index c02156f0f..9b9b7f2a7 100644 --- a/src/Makefile.local +++ b/src/Makefile.local @@ -10,7 +10,7 @@ # settings, so we can avoid changing the main one for all of # our local setups. # -# Version: @(#)Makefile.local 1.0.9 2017/12/28 +# Version: @(#)Makefile.local 1.0.10 2018/03/20 # # Author: Fred N. van Kempen, # @@ -39,11 +39,14 @@ STUFF := # -DENABLE_KEYBOARD_LOG=N sets logging level at N. # -DENABLE_PCI_LOG=N sets logging level at N. # -DENABLE_CDROM_LOG=N sets logging level at N. +# -DENABLE_CDROM_IMAGE_LOG=N sets logging level at N. +# -DENABLE_CDROM_IOCTL_LOG=N sets logging level at N. # -DENABLE_HDD_LOG=N sets logging level at N. # -DENABLE_IDE_LOG=N sets logging level at N. # -DENABLE_FDC_LOG=N sets logging level at N. # -DENABLE_D86F_LOG=N sets logging level at N. # -DENABLE_NIC_LOG=N sets logging level at N. +# -DENABLE_SCAT_LOG=N sets logging level at N. # -DENABLE_SCSI_BUS_LOG=N sets logging level at N. # -DENABLE_SCSI_DISK_LOG=N sets logging level at N. # -DENABLE_X54X_LOG=N sets logging level at N. diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 45086635a..485db1dcc 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -9,12 +9,13 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)cdrom.c 1.0.43 2018/03/20 + * Version: @(#)cdrom.c 1.0.44 2018/03/21 * * Author: Miran Grca, * * Copyright 2016-2018 Miran Grca. */ +#include #include #include #include @@ -732,6 +733,8 @@ void cdrom_update_request_length(uint8_t id, int len, int block_len) cdrom_t *dev = cdrom[id]; uint32_t bt; + uint32_t min_len = 0; + dev->max_transfer_len = dev->request_length; /* For media access commands, make sure the requested DRQ length matches the block length. */ @@ -741,11 +744,23 @@ void cdrom_update_request_length(uint8_t id, int len, int block_len) case 0xa8: case 0xb9: case 0xbe: - if (dev->max_transfer_len < block_len) - dev->max_transfer_len = block_len; + /* Make sure total length is not bigger than sum of the lengths of + all the requested blocks. */ bt = (dev->requested_blocks * block_len); if (len > bt) len = bt; + + min_len = block_len; + + if (len <= block_len) { + /* Total length is less or equal to block length. */ + if (dev->max_transfer_len < block_len) { + /* Transfer a minimum of (block size) bytes. */ + dev->max_transfer_len = block_len; + dev->packet_len = block_len; + break; + } + } default: dev->packet_len = len; break; @@ -756,14 +771,18 @@ void cdrom_update_request_length(uint8_t id, int len, int block_len) /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ if (!dev->max_transfer_len) dev->max_transfer_len = 65534; - if (len <= dev->max_transfer_len) - dev->max_transfer_len = len; + + if ((len <= dev->max_transfer_len) && (len >= min_len)) { + dev->request_length = dev->max_transfer_len = len; + } return; } static double cdrom_get_short_seek(uint8_t id) { - switch(cdrom_drives[id].speed) { + cdrom_t *dev = cdrom[id]; + + switch(dev->cur_speed) { case 0: fatal("CD-ROM %i: 0x speed\n", id); return 0.0; @@ -793,7 +812,9 @@ static double cdrom_get_short_seek(uint8_t id) static double cdrom_get_long_seek(uint8_t id) { - switch(cdrom_drives[id].speed) { + cdrom_t *dev = cdrom[id]; + + switch(dev->cur_speed) { case 0: fatal("CD-ROM %i: 0x speed\n", id); return 0.0; @@ -857,6 +878,17 @@ static double cdrom_bus_speed(uint8_t id) return 3333333.333333333333333; /* 3.3 MB/s PIO-0 speed */ } +static void cdrom_command_bus(uint8_t id) +{ + cdrom_t *dev = cdrom[id]; + + dev->status = BUSY_STAT; + dev->phase = 1; + dev->pos = 0; + dev->callback = 1LL * CDROM_TIME; + cdrom_set_callback(id); +} + static void cdrom_command_common(uint8_t id) { cdrom_t *dev = cdrom[id]; @@ -868,6 +900,9 @@ static void cdrom_command_common(uint8_t id) dev->phase = 1; dev->pos = 0; dev->callback = 0LL; + + cdrom_log("CD-ROM %i: Current speed: %ix\n", id, dev->cur_speed); + if (dev->packet_status == CDROM_PHASE_COMPLETE) { cdrom_phase_callback(id); dev->callback = 0LL; @@ -880,6 +915,7 @@ static void cdrom_command_common(uint8_t id) period = cdrom_seek_time(id) * ((double) TIMER_USEC); dev->callback += ((int64_t) period); cdrom_set_callback(id); + cdrom_log("CD-ROM %i: Seek period: %" PRIu64 " us\n", id, (int64_t) cdrom_seek_time(id)); return; case 0x08: case 0x28: @@ -887,6 +923,7 @@ static void cdrom_command_common(uint8_t id) /* Seek time is in us. */ period = cdrom_seek_time(id) * ((double) TIMER_USEC); dev->callback += ((int64_t) period); + cdrom_log("CD-ROM %i: Seek period: %" PRIu64 " us\n", id, (int64_t) cdrom_seek_time(id)); case 0x25: case 0x42: case 0x43: @@ -898,7 +935,8 @@ static void cdrom_command_common(uint8_t id) case 0xb9: case 0xbe: /* bytes_per_second = 150.0 * 1024.0; */ - bytes_per_second = (1000000.0 / 12000.0) * 2048.0; /* Account for seek time. */ + /* bytes_per_second = (1000000.0 / 12000.0) * 2048.0; */ /* Account for seek time. */ + bytes_per_second = 176.0 * 1024.0; bytes_per_second *= (double) dev->cur_speed; break; default: @@ -911,8 +949,10 @@ static void cdrom_command_common(uint8_t id) } period = 1000000.0 / bytes_per_second; - dusec = (double) TIMER_USEC; - dusec = dusec * period * (double) (dev->packet_len); + cdrom_log("CD-ROM %i: Byte transfer period: %" PRIu64 " us\n", id, (int64_t) period); + period = period * (double) (dev->packet_len); + cdrom_log("CD-ROM %i: Sector transfer period: %" PRIu64 " us\n", id, (int64_t) period); + dusec = period * ((double) TIMER_USEC); dev->callback += ((int64_t) dusec); } cdrom_set_callback(id); @@ -2443,7 +2483,7 @@ cdrom_readtoc_fallback: max_len |= cdb[8]; msf = (cdb[1] >> 1) & 1; - cdrom_buf_alloc(id, 65536); + cdrom_buf_alloc(id, 32); cdrom_log("CD-ROM %i: Getting page %i (%s)\n", id, cdb[3], msf ? "MSF" : "LBA"); if ((cdrom_drives[id].handler->pass_through) && (cdb[3] != 1)) { @@ -2533,6 +2573,13 @@ cdrom_readtoc_fallback: len = MIN(len, max_len); cdrom_set_buf_len(id, BufLen, &len); + cdrom_log("CD-ROM %i: Read subchannel:", id); + for (i = 0; i < 32; i += 8) { + pclog("[%02X] %02X %02X %02X %02X %02X %02X %02X %02X\n", i, + cdbufferb[i], cdbufferb[i + 1], cdbufferb[i + 2], cdbufferb[i + 3], + cdbufferb[i + 4], cdbufferb[i + 5], cdbufferb[i + 6], cdbufferb[i + 7]); + } + cdrom_data_command_finish(id, len, len, len, 0); break; @@ -2983,7 +3030,6 @@ int cdrom_read_from_dma(uint8_t id) cdrom_t *dev = cdrom[id]; int32_t *BufLen = &SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].BufferLength; - int ret = 0; if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) @@ -3001,18 +3047,9 @@ int cdrom_read_from_dma(uint8_t id) ret = cdrom_phase_data_out(id); - if (ret || (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)) { - cdrom_buf_free(id); - dev->packet_status = CDROM_PHASE_COMPLETE; - dev->status = READY_STAT; - dev->phase = 3; - ui_sb_update_icon(SB_CDROM | id, 0); - cdrom_irq_raise(id); - if (ret) - return 1; - else - return 0; - } else + if (ret) + return 1; + else return 0; } @@ -3059,6 +3096,7 @@ int cdrom_write_to_dma(uint8_t id) { cdrom_t *dev = cdrom[id]; + int32_t *BufLen = &SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].BufferLength; int ret = 0; if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { @@ -3067,18 +3105,14 @@ int cdrom_write_to_dma(uint8_t id) } else ret = cdrom_write_to_ide_dma(cdrom_drives[id].ide_channel); - if (ret || (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)) { - cdrom_buf_free(id); - dev->packet_status = CDROM_PHASE_COMPLETE; - dev->status = READY_STAT; - dev->phase = 3; - ui_sb_update_icon(SB_CDROM | id, 0); - cdrom_irq_raise(id); - if (ret) - return 1; - else - return 0; - } else + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) + cdrom_log("CD-ROM %i: SCSI Output data length: %i\n", id, *BufLen); + else + cdrom_log("CD-ROM %i: ATAPI Output data length: %i\n", id, dev->packet_len); + + if (ret) + return 1; + else return 0; } @@ -3086,6 +3120,7 @@ int cdrom_write_to_dma(uint8_t id) void cdrom_phase_callback(uint8_t id) { cdrom_t *dev = cdrom[id]; + int ret; switch(dev->packet_status) { case CDROM_PHASE_IDLE: @@ -3116,7 +3151,17 @@ void cdrom_phase_callback(uint8_t id) return; case CDROM_PHASE_DATA_OUT_DMA: cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT_DMA\n", id); - cdrom_read_from_dma(id); + ret = cdrom_read_from_dma(id); + cdrom_command_complete(id); + + if (ret || (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)) { + cdrom_log("CD-ROM %i: DMA data out phase done\n"); + cdrom_buf_free(id); + cdrom_command_complete(id); + } else { + cdrom_log("CD-ROM %i: DMA data out phase failure\n"); + cdrom_command_bus(id); + } return; case CDROM_PHASE_DATA_IN: cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN\n", id); @@ -3126,7 +3171,16 @@ void cdrom_phase_callback(uint8_t id) return; case CDROM_PHASE_DATA_IN_DMA: cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN_DMA\n", id); - cdrom_write_to_dma(id); + ret = cdrom_write_to_dma(id); + + if (ret || (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)) { + cdrom_log("CD-ROM %i: DMA data in phase done\n"); + cdrom_buf_free(id); + cdrom_command_complete(id); + } else { + cdrom_log("CD-ROM %i: DMA data in phase failure\n"); + cdrom_command_bus(id); + } return; case CDROM_PHASE_ERROR: cdrom_log("CD-ROM %i: CDROM_PHASE_ERROR\n", id); diff --git a/src/cdrom/cdrom_dosbox.cpp b/src/cdrom/cdrom_dosbox.cpp index a7347abf7..7fffa01b9 100644 --- a/src/cdrom/cdrom_dosbox.cpp +++ b/src/cdrom/cdrom_dosbox.cpp @@ -412,6 +412,7 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) track.attr = DATA_TRACK; track.mode2 = true; } else if (type == "MODE2/2352") { + track.form = 1; /* Assume this is XA Mode 2 Form 1. */ track.sectorSize = RAW_SECTOR_SIZE; track.attr = DATA_TRACK; track.mode2 = true; @@ -481,8 +482,8 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) track.number++; track.track_number = 0xAA; // track.attr = 0;//sync with load iso - // track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ - track.attr = last_attr | 0x02; + track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ + // track.attr = last_attr | 0x02; track.start = 0; track.length = 0; track.file = NULL; diff --git a/src/cdrom/cdrom_image.cc b/src/cdrom/cdrom_image.cc index 1df0c3a2d..6a7c74e8c 100644 --- a/src/cdrom/cdrom_image.cc +++ b/src/cdrom/cdrom_image.cc @@ -57,8 +57,8 @@ void cdrom_image_log(const char *format, ...) va_end(ap); fflush(stdout); } -#else - (void)format; +/* #else + (void)format; */ #endif } @@ -68,7 +68,6 @@ void image_audio_callback(uint8_t id, int16_t *output, int len) { cdrom_t *dev = cdrom[id]; - return; if (!cdrom_drives[id].sound_on || (dev->cd_state != CD_PLAYING) || cdrom_image[id].image_is_iso) { cdrom_image_log("image_audio_callback(i): Not playing\n", id); @@ -767,10 +766,14 @@ read_mode2_xa_form2: return 0; } - if (mode2) - goto read_mode2_non_xa; - else + if (mode2 && (form == 1)) + goto read_mode2_xa_form1; + else if (!mode2) goto read_mode1; + else { + cdrom_image_log("CD-ROM %i: [Any Data] Attempting to read a data sector whose cooked size is not 2048 bytes\n", id); + return 0; + } } else { if (mode2) if (form == 1) diff --git a/src/machine/m_at_scat.c b/src/machine/m_at_scat.c index fdb56fe72..420c474a0 100644 --- a/src/machine/m_at_scat.c +++ b/src/machine/m_at_scat.c @@ -10,13 +10,14 @@ * * Re-worked version based on the 82C235 datasheet and errata. * - * Version: @(#)m_at_scat.c 1.0.12 2018/03/20 + * Version: @(#)m_at_scat.c 1.0.13 2018/03/20 * * Authors: Original by GreatPsycho for PCem. * Fred N. van Kempen, * * Copyright 2017,2018 Fred N. van Kempen. */ +#include #include #include #include @@ -84,6 +85,24 @@ static int scatsx_mem_conf_val[33] = { 0x00, 0x01, 0x03, 0x04, 0x05, 0x08, 0x06, uint8_t scat_read(uint16_t port, void *priv); void scat_write(uint16_t port, uint8_t val, void *priv); + +#ifdef ENABLE_SCAT_LOG +int scat_do_log = ENABLE_SCAT_LOG; +#endif + +static void +scat_log(const char *format, ...) +{ +#ifdef ENABLE_SCAT_LOG + if (scat_do_log) { + va_start(ap, format); + pclog_ex(format, ap); + va_end(ap); + } +#endif +} + + void scat_shadow_state_update() { int i, val; @@ -186,7 +205,7 @@ void scat_set_xms_bound(uint8_t val) mem_mapping_disable(&scat_shadowram_mapping[i]); if(mem_size > 1024) mem_mapping_enable(&ram_high_mapping); } - pclog("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, (0x160000 - scat_xms_bound) >> 10); + scat_log("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, (0x160000 - scat_xms_bound) >> 10); if (scat_xms_bound > 0x100000) mem_set_mem_state(0x100000, scat_xms_bound - 0x100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); if (scat_xms_bound < 0x160000) @@ -200,7 +219,7 @@ void scat_set_xms_bound(uint8_t val) if (scat_xms_bound > max_xms_size) scat_xms_bound = max_xms_size; - pclog("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, ((mem_size << 10) - scat_xms_bound) >> 10); + scat_log("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, ((mem_size << 10) - scat_xms_bound) >> 10); if (scat_xms_bound > 0x100000) mem_set_mem_state(0x100000, scat_xms_bound - 0x100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); if (scat_xms_bound < (mem_size << 10)) @@ -399,12 +418,12 @@ void scat_write(uint16_t port, uint8_t val, void *priv) } if (scat_reg_valid) scat_regs[scat_index] = val; - else pclog("Attemped to write unimplemented SCAT register %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); + else scat_log("Attemped to write unimplemented SCAT register %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); if (scat_shadow_update) scat_shadow_state_update(); if (scat_map_update) scat_memmap_state_update(); -// pclog("Write SCAT Register %02X to %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); +// scat_log("Write SCAT Register %02X to %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); break; case 0x92: @@ -425,7 +444,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv) case 0x218: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { -// pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); +// scat_log("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); if((scat_regs[SCAT_VERSION] & 0xF0) == 0) index = scat_ems_reg_2xA & 0x1F; else index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; scat_stat[index].regs_2x8 = val; @@ -446,7 +465,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv) case 0x219: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { -// pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); +// scat_log("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); if((scat_regs[SCAT_VERSION] & 0xF0) == 0) index = scat_ems_reg_2xA & 0x1F; else index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; scat_stat[index].regs_2x9 = val; @@ -463,14 +482,14 @@ void scat_write(uint16_t port, uint8_t val, void *priv) if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); else mem_mapping_set_exec(&scat_mapping[index], NULL); mem_mapping_enable(&scat_mapping[index]); -// pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); +// scat_log("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); } else { mem_mapping_set_exec(&scat_mapping[index], ram + base_addr); mem_mapping_disable(&scat_mapping[index]); if(index < 24) mem_mapping_enable(&scat_4000_9FFF_mapping[index]); -// pclog("Unmap page %d(address %06X)\n", scat_ems_reg_2xA & 0x1f, base_addr); +// scat_log("Unmap page %d(address %06X)\n", scat_ems_reg_2xA & 0x1f, base_addr); } flushmmucache(); } @@ -485,7 +504,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv) case 0x21A: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { -// pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); +// scat_log("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); scat_ems_reg_2xA = ((scat_regs[SCAT_VERSION] & 0xF0) == 0) ? val : val & 0xc3; } break; @@ -512,7 +531,7 @@ uint8_t scat_read(uint16_t port, void *priv) val = scat_regs[scat_index]; break; } -// pclog("Read SCAT Register %02X at %04X:%04X\n", scat_index, CS, cpu_state.pc); +// scat_log("Read SCAT Register %02X at %04X:%04X\n", scat_index, CS, cpu_state.pc); break; case 0x92: @@ -523,7 +542,7 @@ uint8_t scat_read(uint16_t port, void *priv) case 0x218: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { -// pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); +// scat_log("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); if((scat_regs[SCAT_VERSION] & 0xF0) == 0) index = scat_ems_reg_2xA & 0x1F; else index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; val = scat_stat[index].regs_2x8; @@ -533,7 +552,7 @@ uint8_t scat_read(uint16_t port, void *priv) case 0x219: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { -// pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); +// scat_log("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); if((scat_regs[SCAT_VERSION] & 0xF0) == 0) index = scat_ems_reg_2xA & 0x1F; else index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; val = scat_stat[index].regs_2x9; @@ -543,7 +562,7 @@ uint8_t scat_read(uint16_t port, void *priv) case 0x21A: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { -// pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); +// scat_log("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); val = scat_ems_reg_2xA; } break; diff --git a/src/win/win_cdrom_ioctl.c b/src/win/win_cdrom_ioctl.c index a54231037..3261fc441 100644 --- a/src/win/win_cdrom_ioctl.c +++ b/src/win/win_cdrom_ioctl.c @@ -22,10 +22,12 @@ #include #include #include +#include #include #include #include #include +#define HAVE_STDARG_H #include "../86box.h" #include "../device.h" #include "../scsi/scsi.h" @@ -52,8 +54,8 @@ typedef struct { cdrom_ioctl_windows_t cdrom_ioctl_windows[CDROM_NUM]; -#ifdef ENABLE_CDROM_LOG -int cdrom_ioctl_do_log = ENABLE_CDROM_LOG; +#ifdef ENABLE_CDROM_IOCTL_LOG +int cdrom_ioctl_do_log = ENABLE_CDROM_IOCTL_LOG; #endif @@ -63,13 +65,13 @@ static CDROM ioctl_cdrom; static void cdrom_ioctl_log(const char *format, ...) { -#ifdef ENABLE_CDROM_LOG +#ifdef ENABLE_CDROM_IOCTL_LOG + va_list ap; + if (cdrom_ioctl_do_log) { - va_list ap; va_start(ap, format); - vfprintf(stdlog, format, ap); + pclog_ex(format, ap); va_end(ap); - fflush(stdlog); } #endif } @@ -88,15 +90,19 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len) if (dev->cd_state == CD_PLAYING) { dev->seek_pos += (len >> 11); - } + cdrom_ioctl_log("ioctl_audio_callback(): playing but mute\n"); + } else + cdrom_ioctl_log("ioctl_audio_callback(): not playing\n"); + cdrom_ioctl_windows[id].is_playing = 0; memset(output, 0, len * 2); return; } + cdrom_ioctl_log("ioctl_audio_callback(): dev->cd_buflen = %i, len = %i\n", dev->cd_buflen, len); while (dev->cd_buflen < len) { if (dev->seek_pos < dev->cd_end) { - in.DiskOffset.LowPart = (dev->seek_pos - 150) * 2048; + in.DiskOffset.LowPart = dev->seek_pos * 2048; in.DiskOffset.HighPart = 0; in.SectorCount = 1; in.TrackMode = CDDA; @@ -107,11 +113,13 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len) ioctl_close(id); dev->cd_state = CD_STOPPED; dev->cd_buflen = len; + cdrom_ioctl_log("ioctl_audio_callback(): read sector error, stopped\n"); } else { dev->seek_pos++; dev->cd_buflen += (2352 / 2); + cdrom_ioctl_log("ioctl_audio_callback(): dev->seek_pos = %i\n", dev->seek_pos); } } else @@ -121,6 +129,7 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len) ioctl_close(id); dev->cd_state = CD_STOPPED; dev->cd_buflen = len; + cdrom_ioctl_log("ioctl_audio_callback(): reached the end\n"); } } memcpy(output, dev->cd_buffer, len * 2); @@ -146,27 +155,32 @@ static int get_track_nr(uint8_t id, uint32_t pos) if (dev->disc_changed) { return 0; + cdrom_ioctl_log("get_track_nr(): disc changed\n"); } if (cdrom_ioctl[id].last_track_pos == pos) { + cdrom_ioctl_log("get_track_nr(): cdrom_ioctl[id].last_track_pos == pos\n"); return cdrom_ioctl[id].last_track_nr; } - for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) + /* for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) */ + for (c = 0; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) { - uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + - (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] * 75) + - (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] * 75 * 60); + uint32_t track_address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1], + cdrom_ioctl_windows[id].toc.TrackData[c].Address[2], + cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]) - 150; if (track_address <= pos) { + cdrom_ioctl_log("get_track_nr(): track = %i\n", c); track = c; } } cdrom_ioctl[id].last_track_pos = pos; cdrom_ioctl[id].last_track_nr = track; + cdrom_ioctl_log("get_track_nr(): return %i\n", track); return track; } @@ -199,6 +213,7 @@ static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) { return; } + cdrom_ioctl_log("Play audio - %08X %08X %i\n", pos, len, ismsf); if (ismsf == 2) { start_msf = get_track_msf(id, pos); @@ -214,11 +229,11 @@ static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) m = (start_msf >> 16) & 0xff; s = (start_msf >> 8) & 0xff; f = start_msf & 0xff; - pos = MSFtoLBA(m, s, f); + pos = MSFtoLBA(m, s, f) - 150; m = (end_msf >> 16) & 0xff; s = (end_msf >> 8) & 0xff; f = end_msf & 0xff; - len = MSFtoLBA(m, s, f); + len = MSFtoLBA(m, s, f) - 150; } else if (ismsf == 1) { @@ -233,13 +248,13 @@ static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) } else { - pos = MSFtoLBA(m, s, f); + pos = MSFtoLBA(m, s, f) - 150; } m = (len >> 16) & 0xff; s = (len >> 8) & 0xff; f = len & 0xff; - len = MSFtoLBA(m, s, f); + len = MSFtoLBA(m, s, f) - 150; } else if (ismsf == 0) { @@ -252,11 +267,7 @@ static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) } dev->seek_pos = pos; dev->cd_end = len; - if (dev->seek_pos < 150) - { - /* Adjust because the host expects a minimum adjusted LBA of 0 which is equivalent to an absolute LBA of 150. */ - dev->seek_pos = 150; - } + if (!cdrom_ioctl_windows[id].is_playing) { ioctl_hopen(id); @@ -462,9 +473,11 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) if (dev->cd_state == CD_PLAYING || dev->cd_state == CD_PAUSED) { track = get_track_nr(id, cdpos); - track_address = cdrom_ioctl_windows[id].toc.TrackData[track].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[2] * 75) + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[1] * 75 * 60); + track_address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[track].Address[1], + cdrom_ioctl_windows[id].toc.TrackData[track].Address[2], + cdrom_ioctl_windows[id].toc.TrackData[track].Address[3]) - 150; - cdrom_ioctl_log("cdpos = %i, track = %i, track_address = %i\n", cdpos, track, track_address); + cdrom_ioctl_log("ioctl_getcurrentsubchannel(): cdpos = %i, track = %i, track_address = %i\n", cdpos, track, track_address); b[pos++] = sub.CurrentPosition.Control; b[pos++] = track + 1; @@ -478,7 +491,7 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) b[pos + 1] = (uint8_t)dat; b[pos] = 0; pos += 4; - dat = cdpos - track_address - 150; + dat = cdpos - track_address; b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; b[pos + 1] = (uint8_t)dat; @@ -522,12 +535,12 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) } else { - uint32_t temp = MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]); + uint32_t temp = MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]) - 150; b[pos++] = temp >> 24; b[pos++] = temp >> 16; b[pos++] = temp >> 8; b[pos++] = temp; - temp = MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3]); + temp = MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3]) - 150; b[pos++] = temp >> 24; b[pos++] = temp >> 16; b[pos++] = temp >> 8; @@ -1273,6 +1286,7 @@ int ioctl_open(uint8_t id, char d) cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); cdrom_drives[id].handler = &ioctl_cdrom; dev->handler_inited=1; + cdrom_ioctl_windows[id].is_playing = 0; cdrom_ioctl[id].capacity_read=0; /* With these two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ ioctl_read_capacity(id, NULL); pclog(rcs, drb[0], drb[1], drb[2], drb[3], drb[4], drb[5], drb[6], drb[7], From 0f06407825daa98c065f635856f09fea0e0b794d Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 21 Mar 2018 15:16:25 +0100 Subject: [PATCH 30/39] Applied the latest PCem commits. --- src/disk/zip.c | 72 ++++++++++++++- src/scsi/scsi.h | 3 +- src/video/vid_s3.c | 106 +++++++++++++++++---- src/video/vid_sdac_ramdac.c | 178 ++++++++++++++++++++---------------- src/video/vid_sdac_ramdac.h | 2 + 5 files changed, 261 insertions(+), 100 deletions(-) diff --git a/src/disk/zip.c b/src/disk/zip.c index eea0eedbf..1a7289503 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -9,7 +9,7 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.c 1.0.17 2018/03/20 + * Version: @(#)zip.c 1.0.19 2018/03/21 * * Author: Miran Grca, * @@ -99,7 +99,9 @@ const uint8_t zip_command_flags[0x100] = 0, IMPLEMENTED, /* 0x1D */ IMPLEMENTED | CHECK_READY, /* 0x1E */ - 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + IMPLEMENTED | ATAPI_ONLY, /* 0x23 */ + 0, IMPLEMENTED | CHECK_READY, /* 0x25 */ 0, 0, IMPLEMENTED | CHECK_READY, /* 0x28 */ @@ -1988,7 +1990,7 @@ atapi_out: zip_buf_free(id); return; } - + zip_set_buf_len(id, BufLen, &len); zip_data_command_finish(id, len, len, len, 0); @@ -2000,6 +2002,70 @@ atapi_out: zip_command_complete(id); break; + case GPCMD_READ_FORMAT_CAPACITIES: + len = (cdb[7] << 8) | cdb[8]; + + zip_buf_alloc(id, len); + memset(zipbufferb, 0, len); + + pos = 0; + + /* List header */ + zipbufferb[pos++] = 0; + zipbufferb[pos++] = 0; + zipbufferb[pos++] = 0; + if (zip_drives[id].f != NULL) + zipbufferb[pos++] = 16; + else + zipbufferb[pos++] = 8; + + /* Current/Maximum capacity header */ + if (zip_drives[id].is_250) { + if (zip_drives[id].f != NULL) { + zipbufferb[pos++] = (zip_drives[id].medium_size >> 24) & 0xff; + zipbufferb[pos++] = (zip_drives[id].medium_size >> 16) & 0xff; + zipbufferb[pos++] = (zip_drives[id].medium_size >> 8) & 0xff; + zipbufferb[pos++] = zip_drives[id].medium_size & 0xff; + zipbufferb[pos++] = 2; /* Current medium capacity */ + } else { + zipbufferb[pos++] = (ZIP_250_SECTORS >> 24) & 0xff; + zipbufferb[pos++] = (ZIP_250_SECTORS >> 16) & 0xff; + zipbufferb[pos++] = (ZIP_250_SECTORS >> 8) & 0xff; + zipbufferb[pos++] = ZIP_250_SECTORS & 0xff; + zipbufferb[pos++] = 3; /* Maximum medium capacity */ + } + } else { + zipbufferb[pos++] = (ZIP_SECTORS >> 24) & 0xff; + zipbufferb[pos++] = (ZIP_SECTORS >> 16) & 0xff; + zipbufferb[pos++] = (ZIP_SECTORS >> 8) & 0xff; + zipbufferb[pos++] = ZIP_SECTORS & 0xff; + if (zip_drives[id].f != NULL) + zipbufferb[pos++] = 2; + else + zipbufferb[pos++] = 3; + } + + zipbufferb[pos++] = 512 >> 16; + zipbufferb[pos++] = 512 >> 8; + zipbufferb[pos++] = 512 & 0xff; + + if (zip_drives[id].f != NULL) { + /* Formattable capacity descriptor */ + zipbufferb[pos++] = (zip_drives[id].medium_size >> 24) & 0xff; + zipbufferb[pos++] = (zip_drives[id].medium_size >> 16) & 0xff; + zipbufferb[pos++] = (zip_drives[id].medium_size >> 8) & 0xff; + zipbufferb[pos++] = zip_drives[id].medium_size & 0xff; + zipbufferb[pos++] = 0; + zipbufferb[pos++] = 512 >> 16; + zipbufferb[pos++] = 512 >> 8; + zipbufferb[pos++] = 512 & 0xff; + } + + zip_set_buf_len(id, BufLen, &len); + + zip_data_command_finish(id, len, len, len, 0); + break; + default: zip_illegal_opcode(id); break; diff --git a/src/scsi/scsi.h b/src/scsi/scsi.h index 0a8239cc6..c33c5e611 100644 --- a/src/scsi/scsi.h +++ b/src/scsi/scsi.h @@ -8,7 +8,7 @@ * * SCSI controller handler header. * - * Version: @(#)scsi_h 1.0.14 2018/03/18 + * Version: @(#)scsi_h 1.0.15 2018/03/21 * * Authors: TheCollector1995, * Miran Grca, @@ -54,6 +54,7 @@ #define GPCMD_START_STOP_UNIT 0x1b #define GPCMD_SEND_DIAGNOSTIC 0x1d #define GPCMD_PREVENT_REMOVAL 0x1e +#define GPCMD_READ_FORMAT_CAPACITIES 0x23 #define GPCMD_READ_CDROM_CAPACITY 0x25 #define GPCMD_READ_10 0x28 #define GPCMD_WRITE_10 0x2a diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 22777421c..1df6e8eb3 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -8,7 +8,7 @@ * * S3 emulation. * - * Version: @(#)vid_s3.c 1.0.7 2018/03/18 + * Version: @(#)vid_s3.c 1.0.8 2018/03/21 * * Authors: Sarah Walker, * Miran Grca, @@ -159,6 +159,9 @@ typedef struct s3_t uint64_t status_time; uint8_t subsys_cntl, subsys_stat; + + uint32_t hwc_fg_col, hwc_bg_col; + int hwc_col_stack_pos; } s3_t; #define INT_VSY (1 << 0) @@ -815,15 +818,16 @@ void s3_out(uint16_t addr, uint8_t val, void *p) break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - if (s3->chip == S3_VISION864) - { - sdac_ramdac_out(addr, val, &s3->ramdac, svga); - return; - } - else - { - break; - } + if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) + svga_out(addr, val, svga); + else + { + if ((svga->crtc[0x55] & 1) || (svga->crtc[0x43] & 2)) + sdac_ramdac_out((addr & 3) | 4, val, &s3->ramdac, svga); + else + sdac_ramdac_out(addr & 3, val, &s3->ramdac, svga); + } + return; case 0x3D4: svga->crtcreg = val & 0x7f; @@ -903,6 +907,37 @@ void s3_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.x <<= 1; break; + case 0x4a: + switch (s3->hwc_col_stack_pos) + { + case 0: + s3->hwc_fg_col = (s3->hwc_fg_col & 0xffff00) | val; + break; + case 1: + s3->hwc_fg_col = (s3->hwc_fg_col & 0xff00ff) | (val << 8); + break; + case 2: + s3->hwc_fg_col = (s3->hwc_fg_col & 0x00ffff) | (val << 16); + break; + } + s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) % 3; + break; + case 0x4b: + switch (s3->hwc_col_stack_pos) + { + case 0: + s3->hwc_bg_col = (s3->hwc_bg_col & 0xffff00) | val; + break; + case 1: + s3->hwc_bg_col = (s3->hwc_bg_col & 0xff00ff) | (val << 8); + break; + case 2: + s3->hwc_bg_col = (s3->hwc_bg_col & 0x00ffff) | (val << 16); + break; + } + s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) % 3; + break; + case 0x53: case 0x58: case 0x59: case 0x5a: s3_updatemapping(s3); @@ -956,14 +991,11 @@ uint8_t s3_in(uint16_t addr, void *p) break; case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - if (s3->chip == S3_VISION864) - { - return sdac_ramdac_in(addr, &s3->ramdac, svga); - } - else - { - break; - } + if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) + return svga_in(addr, svga); + if ((svga->crtc[0x55] & 1) || (svga->crtc[0x43] & 2)) + return sdac_ramdac_in((addr & 3) | 4, &s3->ramdac, svga); + return sdac_ramdac_in(addr & 3, &s3->ramdac, svga); case 0x3d4: return svga->crtcreg; @@ -976,6 +1008,7 @@ uint8_t s3_in(uint16_t addr, void *p) case 0x30: return s3->id; /*Chip ID*/ case 0x31: return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); case 0x35: return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); + case 0x45: s3->hwc_col_stack_pos = 0; break; case 0x51: return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); case 0x69: return s3->ma_ext; case 0x6a: return s3->bank; @@ -1977,6 +2010,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat void s3_hwcursor_draw(svga_t *svga, int displine) { + s3_t *s3 = (s3_t *)svga->p; int x; uint16_t dat[2]; int xx; @@ -1984,6 +2018,39 @@ void s3_hwcursor_draw(svga_t *svga, int displine) int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; + uint32_t fg = 0, bg = 0; + + switch (svga->bpp) + { + case 15: + fg = video_15to32[s3->hwc_fg_col & 0xffff]; + bg = video_15to32[s3->hwc_bg_col & 0xffff]; + break; + + case 16: + fg = video_16to32[s3->hwc_fg_col & 0xffff]; + bg = video_16to32[s3->hwc_bg_col & 0xffff]; + break; + + case 24: case 32: + fg = s3->hwc_fg_col; + bg = s3->hwc_bg_col; + break; + + default: + if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) + { + fg = svga->pallook[s3->hwc_fg_col & 0xff]; + bg = svga->pallook[s3->hwc_bg_col & 0xff]; + } + else + { + fg = svga->pallook[svga->crtc[0xe]]; + bg = svga->pallook[svga->crtc[0xf]]; + } + break; + } + if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; @@ -1996,7 +2063,7 @@ void s3_hwcursor_draw(svga_t *svga, int displine) if (offset >= svga->hwcursor_latch.x) { if (!(dat[0] & 0x8000)) - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = (dat[1] & 0x8000) ? 0xffffff : 0; + ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = (dat[1] & 0x8000) ? fg : bg; else if (dat[1] & 0x8000) ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; } @@ -2268,6 +2335,7 @@ void *s3_vision864_init(const device_t *info, wchar_t *bios_fn) s3->getclock = sdac_getclock; s3->getclock_p = &s3->ramdac; + sdac_init(&s3->ramdac); return s3; } diff --git a/src/video/vid_sdac_ramdac.c b/src/video/vid_sdac_ramdac.c index 37448128b..95742e26a 100644 --- a/src/video/vid_sdac_ramdac.c +++ b/src/video/vid_sdac_ramdac.c @@ -8,15 +8,13 @@ * * 87C716 'SDAC' true colour RAMDAC emulation. * - * Misidentifies as AT&T 21C504. - * - * Version: @(#)vid_sdac_ramdac.c 1.0.2 2017/11/04 + * Version: @(#)vid_sdac_ramdac.c 1.0.3 2018/03/21 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include @@ -28,72 +26,91 @@ #include "vid_svga.h" #include "vid_sdac_ramdac.h" - -/* Returning divider * 2 */ -int sdac_get_clock_divider(sdac_ramdac_t *ramdac) +static void sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) { - switch (ramdac->command >> 4) + ramdac->command = val; + switch (val >> 4) { - case 0x1: return 1; - case 0x0: case 0x3: case 0x5: return 2; - case 0x9: return 3; - case 0x2: case 0x6: case 0x7: case 0x8: case 0xa: case 0xc: return 4; - case 0x4: case 0xe: return 6; - default: return 2; + case 0x2: case 0x3: case 0xa: svga->bpp = 15; break; + case 0x4: case 0xe: svga->bpp = 24; break; + case 0x5: case 0x6: case 0xc: svga->bpp = 16; break; + case 0x7: svga->bpp = 32; break; + + case 0: case 1: default: svga->bpp = 8; break; } } +static void sdac_reg_write(sdac_ramdac_t *ramdac, int reg, uint8_t val) +{ + if ((reg >= 2 && reg <= 7) || (reg == 0xa) || (reg == 0xe)) + { + if (!ramdac->reg_ff) + ramdac->regs[reg] = (ramdac->regs[reg] & 0xff00) | val; + else + ramdac->regs[reg] = (ramdac->regs[reg] & 0x00ff) | (val << 8); + } + ramdac->reg_ff = !ramdac->reg_ff; + if (!ramdac->reg_ff) + ramdac->windex++; +} + +static uint8_t sdac_reg_read(sdac_ramdac_t *ramdac, int reg) +{ + uint8_t temp; + + if (!ramdac->reg_ff) + temp = ramdac->regs[reg] & 0xff; + else + temp = ramdac->regs[reg] >> 8; + ramdac->reg_ff = !ramdac->reg_ff; + if (!ramdac->reg_ff) + ramdac->rindex++; + + return temp; +} + void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga) { switch (addr) - { - case 0x3C6: - if (val == 0xff) - { - ramdac->rs2 = 0; - ramdac->magic_count = 0; - break; - } - if (ramdac->magic_count < 4) break; + { + case 2: if (ramdac->magic_count == 4) - { - ramdac->command = val; - switch (val >> 4) - { - case 0x2: case 0x3: case 0x8: case 0xa: svga->bpp = 15; break; - case 0x4: case 0x9: case 0xe: svga->bpp = 24; break; - case 0x5: case 0x6: case 0xc: svga->bpp = 16; break; - case 0x7: case 0xd: svga->bpp = 32; break; - - case 0: case 1: default: svga->bpp = 8; break; - } - svga_recalctimings(svga); - pclog("RAMDAC: Mode: %i, BPP: %i\n", val >> 4, svga->bpp); - } + sdac_control_write(ramdac, svga, val); + ramdac->magic_count = 0; break; - case 0x3C7: + case 3: ramdac->magic_count = 0; - if (ramdac->rs2) - ramdac->rindex = val; break; - case 0x3C8: + case 0: ramdac->magic_count = 0; - if (ramdac->rs2) - ramdac->windex = val; break; - case 0x3C9: + case 1: ramdac->magic_count = 0; - if (ramdac->rs2) - { - if (!ramdac->reg_ff) ramdac->regs[ramdac->windex & 0xff] = (ramdac->regs[ramdac->windex & 0xff] & 0xff00) | val; - else ramdac->regs[ramdac->windex & 0xff] = (ramdac->regs[ramdac->windex & 0xff] & 0x00ff) | (val << 8); - ramdac->reg_ff = !ramdac->reg_ff; - if (!ramdac->reg_ff) ramdac->windex++; - } + break; + + case 4: + ramdac->windex = val; + ramdac->reg_ff = 0; + break; + case 5: + sdac_reg_write(ramdac, ramdac->windex & 0xff, val); + break; + case 6: + sdac_control_write(ramdac, svga, val); + break; + case 7: + ramdac->rindex = val; + ramdac->reg_ff = 0; break; } - svga_out(addr, val, svga); + if (!(addr & 4)) + { + if (addr < 2) + svga_out(addr + 0x3c8, val, svga); + else + svga_out(addr + 0x3c4, val, svga); + } } uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga) @@ -101,10 +118,9 @@ uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga) uint8_t temp; switch (addr) { - case 0x3C6: - ramdac->reg_ff = 0; + case 2: if (ramdac->magic_count < 5) - ramdac->magic_count++; + ramdac->magic_count++; if (ramdac->magic_count == 4) { temp = 0x70; /*SDAC ID*/ @@ -116,31 +132,33 @@ uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga) ramdac->magic_count = 0; } return temp; - case 0x3C7: - ramdac->magic_count=0; - if (ramdac->rs2) return ramdac->rindex; + case 3: + ramdac->magic_count=0; break; - case 0x3C8: - ramdac->magic_count=0; - if (ramdac->rs2) return ramdac->windex; + case 0: + ramdac->magic_count=0; break; - case 0x3C9: - ramdac->magic_count=0; - if (ramdac->rs2) - { - if (!ramdac->reg_ff) temp = ramdac->regs[ramdac->rindex & 0xff] & 0xff; - else temp = ramdac->regs[ramdac->rindex & 0xff] >> 8; - ramdac->reg_ff = !ramdac->reg_ff; - if (!ramdac->reg_ff) - { - ramdac->rindex++; - ramdac->magic_count = 0; - } - return temp; - } + case 1: + ramdac->magic_count=0; break; + + case 4: + return ramdac->windex; + case 5: + return sdac_reg_read(ramdac, ramdac->rindex & 0xff); + case 6: + return ramdac->command; + case 7: + return ramdac->rindex; } - return svga_in(addr, svga); + if (!(addr & 4)) + { + if (addr < 2) + return svga_in(addr + 0x3c8, svga); + else + return svga_in(addr + 0x3c4, svga); + } + return 0xff; } float sdac_getclock(int clock, void *p) @@ -157,3 +175,9 @@ float sdac_getclock(int clock, void *p) t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); return t; } + +void sdac_init(sdac_ramdac_t *ramdac) +{ + ramdac->regs[0] = 0x6128; + ramdac->regs[1] = 0x623d; +} diff --git a/src/video/vid_sdac_ramdac.h b/src/video/vid_sdac_ramdac.h index e2a8557bb..52d908599 100644 --- a/src/video/vid_sdac_ramdac.h +++ b/src/video/vid_sdac_ramdac.h @@ -11,6 +11,8 @@ typedef struct sdac_ramdac_t int rs2; } sdac_ramdac_t; +void sdac_init(sdac_ramdac_t *ramdac); + void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga); uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga); From a136b327928cb14eaf0fc763caa17bfa79792fc4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 21 Mar 2018 17:45:23 +0100 Subject: [PATCH 31/39] Fixed an excess logging line in cdrom.c. --- src/cdrom/cdrom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 485db1dcc..e88a9606e 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.44 2018/03/21 + * Version: @(#)cdrom.c 1.0.45 2018/03/21 * * Author: Miran Grca, * @@ -2575,7 +2575,7 @@ cdrom_readtoc_fallback: cdrom_log("CD-ROM %i: Read subchannel:", id); for (i = 0; i < 32; i += 8) { - pclog("[%02X] %02X %02X %02X %02X %02X %02X %02X %02X\n", i, + cdrom_log("[%02X] %02X %02X %02X %02X %02X %02X %02X %02X\n", i, cdbufferb[i], cdbufferb[i + 1], cdbufferb[i + 2], cdbufferb[i + 3], cdbufferb[i + 4], cdbufferb[i + 5], cdbufferb[i + 6], cdbufferb[i + 7]); } From 19d87069e651b9a31d886f9423ff147a8704ab0c Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Mar 2018 02:40:33 +0100 Subject: [PATCH 32/39] Some Cirrus Logic CL-GD 54x6 fixes - fixes rendering of CMD.EXE's scroll bars on Windows 2000 and Neptune. --- src/video/vid_cl54xx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 168f1586b..f1270a1c1 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, CL-GD 5430, CL-GD 5434 and CL-GD 5436 are supported). * - * Version: @(#)vid_cl_54xx.c 1.0.11 2018/03/20 + * Version: @(#)vid_cl_54xx.c 1.0.12 2018/03/22 * * Authors: Sarah Walker, * Barry Rodewald, @@ -1996,13 +1996,13 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~7)) + (gd54xx->blt.y_count << 3) + (gd54xx->blt.x_count & 7)]; break; case CIRRUS_BLTMODE_PIXELWIDTH16: - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~3)) + (gd54xx->blt.y_count << 4) + (gd54xx->blt.x_count & 15)]; + src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~15)) + (gd54xx->blt.y_count << 4) + (gd54xx->blt.x_count & 15)]; break; case CIRRUS_BLTMODE_PIXELWIDTH24: - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~3)) + (gd54xx->blt.y_count << 5) + (gd54xx->blt.x_count % 24)]; + src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~31)) + (gd54xx->blt.y_count << 5) + (gd54xx->blt.x_count % 31)]; break; case CIRRUS_BLTMODE_PIXELWIDTH32: - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~3)) + (gd54xx->blt.y_count << 5) + (gd54xx->blt.x_count & 31)]; + src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~31)) + (gd54xx->blt.y_count << 5) + (gd54xx->blt.x_count & 31)]; break; } mask = 1; From 6ebdd0e461e0dda8bd452c8e5abdda58e5161519 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Mar 2018 05:39:05 +0100 Subject: [PATCH 33/39] Slightly reworked part of the Cirrus Logic emulation code to be smaller and more efficient. --- src/video/vid_cl54xx.c | 194 ++++++++++++----------------------------- 1 file changed, 54 insertions(+), 140 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index f1270a1c1..5c2cdeadb 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, CL-GD 5430, CL-GD 5434 and CL-GD 5436 are supported). * - * Version: @(#)vid_cl_54xx.c 1.0.12 2018/03/22 + * Version: @(#)vid_cl_54xx.c 1.0.13 2018/03/22 * * Authors: Sarah Walker, * Barry Rodewald, @@ -1860,6 +1860,8 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) { int blt_mask = 0; int x_max = 0; + + int shift = 0, last_x = 0; switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { case CIRRUS_BLTMODE_PIXELWIDTH8: @@ -1880,7 +1882,9 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) x_max = 32; blt_mask *= 4; break; - } + } + + last_x = (x_max >> 3) - 1; if (count == -1) { gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; @@ -1894,26 +1898,20 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) gd54xx->blt.y_count = 0; if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_COLOREXPAND)) == (CIRRUS_BLTMODE_MEMSYSSRC|CIRRUS_BLTMODE_COLOREXPAND)) { - if (!(svga->seqregs[7] & 0xf0)) - { + if (!(svga->seqregs[7] & 0xf0)) { mem_mapping_set_handler(&svga->mapping, NULL, NULL, NULL, NULL, gd54xx_blt_write_w, gd54xx_blt_write_l); mem_mapping_set_p(&svga->mapping, gd54xx); - } - else - { + } else { mem_mapping_set_handler(&gd54xx->linear_mapping, NULL, NULL, NULL, NULL, gd54xx_blt_write_w, gd54xx_blt_write_l); mem_mapping_set_p(&gd54xx->linear_mapping, gd54xx); } gd543x_recalc_mapping(gd54xx); return; } else if (gd54xx->blt.mode != CIRRUS_BLTMODE_MEMSYSSRC) { - if (!(svga->seqregs[7] & 0xf0)) - { + if (!(svga->seqregs[7] & 0xf0)) { mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); mem_mapping_set_p(&gd54xx->svga.mapping, gd54xx); - } - else - { + } else { mem_mapping_set_handler(&gd54xx->linear_mapping, svga_readb_linear, svga_readw_linear, svga_readl_linear, gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear); mem_mapping_set_p(&gd54xx->linear_mapping, svga); } @@ -1927,60 +1925,34 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) int mask = 0; if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) { - if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { - + if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY) mask = (cpu_dat >> 31); else mask = cpu_dat & 0x80; - - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) - { + + switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { case CIRRUS_BLTMODE_PIXELWIDTH8: src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; - cpu_dat <<= 1; - count--; + shift = 0; break; case CIRRUS_BLTMODE_PIXELWIDTH16: - if (gd54xx->blt.x_count & 1) - src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); - else - src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; - if (gd54xx->blt.x_count & 1) - { - cpu_dat <<= 1; - count--; - } + shift = (gd54xx->blt.x_count & 1); break; case CIRRUS_BLTMODE_PIXELWIDTH24: - if ((gd54xx->blt.x_count % 3) == 2) - src = mask ? (gd54xx->blt.fg_col >> 16) : (gd54xx->blt.bg_col >> 16); - else if ((gd54xx->blt.x_count % 3) == 1) - src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); - else - src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; - if ((gd54xx->blt.x_count % 3) == 2) - { - cpu_dat <<= 1; - count--; - } + shift = (gd54xx->blt.x_count % 3); break; case CIRRUS_BLTMODE_PIXELWIDTH32: - if ((gd54xx->blt.x_count & 3) == 3) - src = mask ? (gd54xx->blt.fg_col >> 24) : (gd54xx->blt.bg_col >> 24); - else if ((gd54xx->blt.x_count & 3) == 2) - src = mask ? (gd54xx->blt.fg_col >> 16) : (gd54xx->blt.bg_col >> 16); - else if ((gd54xx->blt.x_count & 3) == 1) - src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); - else - src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; - if ((gd54xx->blt.x_count & 3) == 3) - { - cpu_dat <<= 1; - count--; - } + shift = (gd54xx->blt.x_count & 3); break; } + + src = mask ? (gd54xx->blt.fg_col >> (shift << 3)) : (gd54xx->blt.bg_col >> (shift << 3)); + + if (shift == last_x) { + cpu_dat <<= 1; + count--; + } } } else { switch (gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) { @@ -1990,8 +1962,7 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) mask = 1; break; case CIRRUS_BLTMODE_PATTERNCOPY: - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) - { + switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { case CIRRUS_BLTMODE_PIXELWIDTH8: src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~7)) + (gd54xx->blt.y_count << 3) + (gd54xx->blt.x_count & 7)]; break; @@ -1999,7 +1970,7 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~15)) + (gd54xx->blt.y_count << 4) + (gd54xx->blt.x_count & 15)]; break; case CIRRUS_BLTMODE_PIXELWIDTH24: - src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~31)) + (gd54xx->blt.y_count << 5) + (gd54xx->blt.x_count % 31)]; + src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~31)) + (gd54xx->blt.y_count << 5) + (gd54xx->blt.x_count % 24)]; break; case CIRRUS_BLTMODE_PIXELWIDTH32: src = svga->vram[(gd54xx->blt.src_addr & (svga->vram_mask & ~31)) + (gd54xx->blt.y_count << 5) + (gd54xx->blt.x_count & 31)]; @@ -2008,113 +1979,64 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) mask = 1; break; case CIRRUS_BLTMODE_COLOREXPAND: - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) - { + switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { case CIRRUS_BLTMODE_PIXELWIDTH8: mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> gd54xx->blt.x_count); - src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + shift = 0; break; case CIRRUS_BLTMODE_PIXELWIDTH16: mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count >> 1)); - if (gd54xx->blt.dst_addr & 1) - src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); - else - src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + shift = (gd54xx->blt.dst_addr & 1); break; case CIRRUS_BLTMODE_PIXELWIDTH24: mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count / 3)); - if ((gd54xx->blt.dst_addr % 3) == 2) - src = mask ? (gd54xx->blt.fg_col >> 16) : (gd54xx->blt.bg_col >> 16); - else if ((gd54xx->blt.dst_addr % 3) == 1) - src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); - else - src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + shift = (gd54xx->blt.dst_addr % 3); break; case CIRRUS_BLTMODE_PIXELWIDTH32: mask = svga->vram[gd54xx->blt.src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count >> 2)); - if ((gd54xx->blt.dst_addr & 3) == 3) - src = mask ? (gd54xx->blt.fg_col >> 24) : (gd54xx->blt.bg_col >> 24); - else if ((gd54xx->blt.dst_addr & 3) == 2) - src = mask ? (gd54xx->blt.fg_col >> 16) : (gd54xx->blt.bg_col >> 16); - else if ((gd54xx->blt.dst_addr & 3) == 1) - src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); - else - src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + shift = (gd54xx->blt.dst_addr & 3); break; } + src = mask ? (gd54xx->blt.fg_col >> (shift << 3)) : (gd54xx->blt.bg_col >> (shift << 3)); break; case CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND: - if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) - { - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) - { + if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) { + switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { case CIRRUS_BLTMODE_PIXELWIDTH8: - src = gd54xx->blt.fg_col; + shift = 0; break; case CIRRUS_BLTMODE_PIXELWIDTH16: - if (gd54xx->blt.dst_addr & 1) - src = (gd54xx->blt.fg_col >> 8); - else - src = gd54xx->blt.fg_col; + shift = (gd54xx->blt.dst_addr & 1); break; case CIRRUS_BLTMODE_PIXELWIDTH24: - if ((gd54xx->blt.dst_addr % 3) == 2) - src = (gd54xx->blt.fg_col >> 16); - else if ((gd54xx->blt.dst_addr % 3) == 1) - src = (gd54xx->blt.fg_col >> 8); - else - src = gd54xx->blt.fg_col; + shift = (gd54xx->blt.dst_addr % 3); break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - if ((gd54xx->blt.dst_addr & 3) == 3) - src = (gd54xx->blt.fg_col >> 24); - else if ((gd54xx->blt.dst_addr & 3) == 2) - src = (gd54xx->blt.fg_col >> 16); - else if ((gd54xx->blt.dst_addr & 3) == 1) - src = (gd54xx->blt.fg_col >> 8); - else - src = gd54xx->blt.fg_col; + shift = (gd54xx->blt.dst_addr & 3); break; } - } - else - { - switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) - { + src = (gd54xx->blt.fg_col >> (shift << 3)); + } else { + switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { case CIRRUS_BLTMODE_PIXELWIDTH8: mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> gd54xx->blt.x_count); - src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + shift = 0; break; case CIRRUS_BLTMODE_PIXELWIDTH16: mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count >> 1)); - if (gd54xx->blt.dst_addr & 1) - src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); - else - src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + shift = (gd54xx->blt.dst_addr & 1); break; case CIRRUS_BLTMODE_PIXELWIDTH24: mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count / 3)); - if ((gd54xx->blt.dst_addr % 3) == 2) - src = mask ? (gd54xx->blt.fg_col >> 16) : (gd54xx->blt.bg_col >> 16); - else if ((gd54xx->blt.dst_addr % 3) == 1) - src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); - else - src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; - break; - + shift = (gd54xx->blt.dst_addr % 3); + break; case CIRRUS_BLTMODE_PIXELWIDTH32: mask = svga->vram[(gd54xx->blt.src_addr & svga->vram_mask & ~7) | gd54xx->blt.y_count] & (0x80 >> (gd54xx->blt.x_count >> 2)); - if ((gd54xx->blt.dst_addr & 3) == 3) - src = mask ? (gd54xx->blt.fg_col >> 24) : (gd54xx->blt.bg_col >> 24); - else if ((gd54xx->blt.dst_addr & 3) == 2) - src = mask ? (gd54xx->blt.fg_col >> 16) : (gd54xx->blt.bg_col >> 16); - else if ((gd54xx->blt.dst_addr & 3) == 1) - src = mask ? (gd54xx->blt.fg_col >> 8) : (gd54xx->blt.bg_col >> 8); - else - src = mask ? gd54xx->blt.fg_col : gd54xx->blt.bg_col; + shift = (gd54xx->blt.dst_addr & 3); break; } + + src = mask ? (gd54xx->blt.fg_col >> (shift << 3)) : (gd54xx->blt.bg_col >> (shift << 3)); } break; } @@ -2142,14 +2064,11 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) case 0xda: dst = ~(src & dst); break; } - if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) - { + if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { if ((gd54xx->blt.width_backup - gd54xx->blt.width) >= blt_mask && !((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && mask)) svga->vram[gd54xx->blt.dst_addr & svga->vram_mask] = dst; - } - else - { + } else { if ((gd54xx->blt.width_backup - gd54xx->blt.width) >= blt_mask && !((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && !mask)) svga->vram[gd54xx->blt.dst_addr & svga->vram_mask] = dst; @@ -2159,8 +2078,7 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) gd54xx->blt.x_count++; - if (gd54xx->blt.x_count == x_max) - { + if (gd54xx->blt.x_count == x_max) { gd54xx->blt.x_count = 0; if ((gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) == CIRRUS_BLTMODE_COLOREXPAND) gd54xx->blt.src_addr++; @@ -2191,15 +2109,11 @@ gd54xx_start_blit(uint32_t cpu_dat, int count, gd54xx_t *gd54xx, svga_t *svga) gd54xx->blt.height_internal--; if (gd54xx->blt.height_internal == 0xffff) { - if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) - { - if (!(svga->seqregs[7] & 0xf0)) - { + if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) { + if (!(svga->seqregs[7] & 0xf0)) { mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); mem_mapping_set_p(&svga->mapping, gd54xx); - } - else - { + } else { mem_mapping_set_handler(&gd54xx->linear_mapping, svga_readb_linear, svga_readw_linear, svga_readl_linear, gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear); mem_mapping_set_p(&gd54xx->linear_mapping, svga); } From c162a4cb1ef07ac79f0025172436f44863115f8a Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Mar 2018 19:05:51 +0100 Subject: [PATCH 34/39] Fixed some things regarding the PS/2 Model 70 Type 3 and 4 (but the 12903 error remains, and is also present on PCem, so waiting for an upstream fix), and slightly debloated the PS/2 MCA code. --- src/keyboard.h | 3 +- src/keyboard_at.c | 16 ++- src/machine/m_ps2_mca.c | 198 ++++++++++++------------------------ src/machine/machine_table.c | 6 +- 4 files changed, 85 insertions(+), 138 deletions(-) diff --git a/src/keyboard.h b/src/keyboard.h index 388f29d10..289b1a40c 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -8,7 +8,7 @@ * * Definitions for the keyboard interface. * - * Version: @(#)keyboard.h 1.0.13 2018/03/19 + * Version: @(#)keyboard.h 1.0.14 2018/03/22 * * Authors: Sarah Walker, * Miran Grca, @@ -68,6 +68,7 @@ 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_mca_2_device; extern const device_t keyboard_ps2_quadtel_device; #endif diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 87e7af857..2a78ef62c 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.32 2018/03/19 + * Version: @(#)keyboard_at.c 1.0.33 2018/03/22 * * Authors: Sarah Walker, * Miran Grca, @@ -1900,6 +1900,10 @@ kbd_init(const device_t *info) timer_add(kbd_poll, &keyboard_delay, TIMER_ALWAYS_ENABLED, kbd); if ((kbd->flags & KBC_TYPE_MASK) != KBC_TYPE_ISA) { + if ((kbd->flags & KBC_TYPE_MASK) == KBC_TYPE_PS2_2) + keyboard_mode &= ~0x03; /* These machines force translation off, so the keyboard + must start in scan code set 0. */ + timer_add(kbd_refresh, &kbd->refresh_time, TIMER_ALWAYS_ENABLED, kbd); } @@ -2020,6 +2024,16 @@ const device_t keyboard_ps2_mca_device = { NULL, NULL, NULL, NULL }; +const device_t keyboard_ps2_mca_2_device = { + "PS/2 Keyboard", + 0, + KBC_TYPE_PS2_2 | KBC_VEN_IBM_MCA, + kbd_init, + kbd_close, + kbd_reset, + NULL, NULL, NULL, NULL +}; + const device_t keyboard_ps2_quadtel_device = { "PS/2 Keyboard (Quadtel/MegaPC)", 0, diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index a51fe1143..0aeed187a 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -741,6 +741,67 @@ static void ps2_mem_expansion_write(int port, uint8_t val, void *p) mem_mapping_disable(&ps2.expansion_mapping); } +static void ps2_mca_mem_fffc_init(int start_mb) +{ + uint32_t planar_size, expansion_start; + + if (start_mb == 2) { + planar_size = 0x160000; + expansion_start = 0x260000; + } else { + planar_size = (start_mb - 1) << 20; + expansion_start = start_mb << 20; + } + + mem_mapping_set_addr(&ram_high_mapping, 0x100000, planar_size); + + ps2.mem_pos_regs[0] = 0xff; + ps2.mem_pos_regs[1] = 0xfc; + + switch ((mem_size / 1024) - start_mb) + { + case 1: + ps2.mem_pos_regs[4] = 0xfc; /* 11 11 11 00 = 0 0 0 1 */ + break; + case 2: + ps2.mem_pos_regs[4] = 0xfe; /* 11 11 11 10 = 0 0 0 2 */ + break; + case 3: + ps2.mem_pos_regs[4] = 0xf2; /* 11 11 00 10 = 0 0 1 2 */ + break; + case 4: + ps2.mem_pos_regs[4] = 0xfa; /* 11 11 10 10 = 0 0 2 2 */ + break; + case 5: + ps2.mem_pos_regs[4] = 0xca; /* 11 00 10 10 = 0 1 2 2 */ + break; + case 6: + ps2.mem_pos_regs[4] = 0xea; /* 11 10 10 10 = 0 2 2 2 */ + break; + case 7: + ps2.mem_pos_regs[4] = 0x2a; /* 00 10 10 10 = 1 2 2 2 */ + break; + case 8: + ps2.mem_pos_regs[4] = 0xaa; /* 10 10 10 10 = 2 2 2 2 */ + break; + } + + mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL); + mem_mapping_add(&ps2.expansion_mapping, + expansion_start, + (mem_size - (start_mb << 10)) << 10, + mem_read_ram, + mem_read_ramw, + mem_read_raml, + mem_write_ram, + mem_write_ramw, + mem_write_raml, + &ram[expansion_start], + MEM_MAPPING_INTERNAL, + NULL); + mem_mapping_disable(&ps2.expansion_mapping); +} + static void ps2_mca_board_model_50_init() { ps2_mca_board_common_init(); @@ -754,53 +815,7 @@ static void ps2_mca_board_model_50_init() if (mem_size > 2048) { /* Only 2 MB supported on planar, create a memory expansion card for the rest */ - mem_mapping_set_addr(&ram_high_mapping, 0x100000, 0x160000); - - ps2.mem_pos_regs[0] = 0xff; - ps2.mem_pos_regs[1] = 0xfc; - - switch (mem_size/1024) - { - case 3: - ps2.mem_pos_regs[4] = 0xfc; /* 11 11 11 00 = 0 0 0 1 */ - break; - case 4: - ps2.mem_pos_regs[4] = 0xfe; /* 11 11 11 10 = 0 0 0 2 */ - break; - case 5: - ps2.mem_pos_regs[4] = 0xf2; /* 11 11 00 10 = 0 0 1 2 */ - break; - case 6: - ps2.mem_pos_regs[4] = 0xfa; /* 11 11 10 10 = 0 0 2 2 */ - break; - case 7: - ps2.mem_pos_regs[4] = 0xca; /* 11 00 10 10 = 0 1 2 2 */ - break; - case 8: - ps2.mem_pos_regs[4] = 0xea; /* 11 10 10 10 = 0 2 2 2 */ - break; - case 9: - ps2.mem_pos_regs[4] = 0x2a; /* 00 10 10 10 = 1 2 2 2 */ - break; - case 10: - ps2.mem_pos_regs[4] = 0xaa; /* 10 10 10 10 = 2 2 2 2 */ - break; - } - - mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL); - mem_mapping_add(&ps2.expansion_mapping, - 0x260000, - (mem_size - 2048)*1024, - mem_read_ram, - mem_read_ramw, - mem_read_raml, - mem_write_ram, - mem_write_ramw, - mem_write_raml, - &ram[0x260000], - MEM_MAPPING_INTERNAL, - NULL); - mem_mapping_disable(&ps2.expansion_mapping); + ps2_mca_mem_fffc_init(2); } device_add(&ps1vga_device); @@ -1005,7 +1020,6 @@ static void ps2_mca_board_model_70_type34_init(int is_type4) { ps2_mca_board_common_init(); - mem_remap_top_256k(); ps2.split_addr = mem_size * 1024; mca_init(4); @@ -1015,7 +1029,7 @@ static void ps2_mca_board_model_70_type34_init(int is_type4) device_add(&ps2_nvr_device); io_sethandler(0x00e0, 0x0003, mem_encoding_read_cached, NULL, NULL, mem_encoding_write_cached, NULL, NULL, NULL); - + ps2.mem_regs[1] = 2; switch (mem_size/1024) @@ -1073,41 +1087,7 @@ static void ps2_mca_board_model_70_type34_init(int is_type4) if (mem_size > 8192) { /* Only 8 MB supported on planar, create a memory expansion card for the rest */ - mem_mapping_set_addr(&ram_high_mapping, 0x100000, 0x700000); - - ps2.mem_pos_regs[0] = 0xff; - ps2.mem_pos_regs[1] = 0xfc; - - switch (mem_size/1024) - { - case 10: - ps2.mem_pos_regs[4] = 0xfe; - break; - case 12: - ps2.mem_pos_regs[4] = 0xfa; - break; - case 14: - ps2.mem_pos_regs[4] = 0xea; - break; - case 16: - ps2.mem_pos_regs[4] = 0xaa; - break; - } - - mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL); - mem_mapping_add(&ps2.expansion_mapping, - 0x800000, - (mem_size - 8192)*1024, - mem_read_ram, - mem_read_ramw, - mem_read_raml, - mem_write_ram, - mem_write_ramw, - mem_write_raml, - &ram[0x800000], - MEM_MAPPING_INTERNAL, - NULL); - mem_mapping_disable(&ps2.expansion_mapping); + ps2_mca_mem_fffc_init(8); } device_add(&ps1vga_device); @@ -1176,55 +1156,7 @@ static void ps2_mca_board_model_80_type2_init(int is486) if ((mem_size > 4096) && !is486) { /* Only 4 MB supported on planar, create a memory expansion card for the rest */ - mem_mapping_set_addr(&ram_high_mapping, 0x100000, 0x300000); - - ps2.mem_pos_regs[0] = 0xff; - ps2.mem_pos_regs[1] = 0xfc; - - switch (mem_size/1024) - { - case 5: - ps2.mem_pos_regs[4] = 0xfc; /* 11 11 11 00 = 0 0 0 1 */ - break; - case 6: - ps2.mem_pos_regs[4] = 0xfe; /* 11 11 11 10 = 0 0 0 2 */ - break; - case 7: - ps2.mem_pos_regs[4] = 0xf2; /* 11 11 00 10 = 0 0 1 2 */ - break; - case 8: - ps2.mem_pos_regs[4] = 0xfa; /* 11 11 10 10 = 0 0 2 2 */ - break; - case 9: - ps2.mem_pos_regs[4] = 0xca; /* 11 00 10 10 = 0 1 2 2 */ - break; - case 10: - ps2.mem_pos_regs[4] = 0xea; /* 11 10 10 10 = 0 2 2 2 */ - break; - case 11: - ps2.mem_pos_regs[4] = 0x2a; /* 00 10 10 10 = 1 2 2 2 */ - break; - case 12: - ps2.mem_pos_regs[4] = 0xaa; /* 10 10 10 10 = 2 2 2 2 */ - break; - } - - /* pclog("ps2.mem_pos_regs[4] = %08X\n", ps2.mem_pos_regs[4]); */ - - mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL); - mem_mapping_add(&ps2.expansion_mapping, - 0x400000, - (mem_size - 4096)*1024, - mem_read_ram, - mem_read_ramw, - mem_read_raml, - mem_write_ram, - mem_write_ramw, - mem_write_raml, - &ram[0x400000], - MEM_MAPPING_INTERNAL, - NULL); - mem_mapping_disable(&ps2.expansion_mapping); + ps2_mca_mem_fffc_init(4); } device_add(&ps1vga_device); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 8f02f57c8..eaee5820a 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.26 2018/03/18 + * Version: @(#)machine_table.c 1.0.27 2018/03/22 * * Authors: Sarah Walker, * Miran Grca, @@ -104,7 +104,7 @@ const machine_t machines[] = { #if defined(DEV_BRANCH) && defined(USE_PORTABLE3) { "[386DX ISA] Compaq Portable III (386)", ROM_PORTABLEIII386, "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 1, 14, 1, 127, machine_at_compaq_init, NULL, nvr_at_close }, #endif - { "[386DX MCA] IBM PS/2 model 70 (type 3)", ROM_IBMPS2_M70_TYPE3, "ibmps2_m70_type3", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 2, 16, 2, 63, machine_ps2_model_70_type3_init, NULL, nvr_at_close }, + { "[386DX MCA] IBM PS/2 model 70 (type 3)", ROM_IBMPS2_M70_TYPE3, "ibmps2_m70_type3", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 2, 16, 2, 63, machine_ps2_model_70_type3_init, NULL, nvr_at_close }, { "[386DX MCA] IBM PS/2 model 80", ROM_IBMPS2_M80, "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 12, 1, 63, machine_ps2_model_80_init, NULL, nvr_at_close }, @@ -114,7 +114,7 @@ const machine_t machines[] = { { "[486 ISA] DTK PKM-0038S E-2", ROM_DTK486, "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_dtk486_init, NULL, nvr_at_close }, { "[486 ISA] IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 1, 64, 1, 127, machine_ps1_m2133_init, NULL, nvr_at_close }, - { "[486 MCA] IBM PS/2 model 70 (type 4)", ROM_IBMPS2_M70_TYPE4, "ibmps2_m70_type4", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 2, 64, 2, 63, machine_ps2_model_70_type4_init, NULL, nvr_at_close }, + { "[486 MCA] IBM PS/2 model 70 (type 4)", ROM_IBMPS2_M70_TYPE4, "ibmps2_m70_type4", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 2, 16, 2, 63, machine_ps2_model_70_type4_init, NULL, nvr_at_close }, #ifdef WALTJE { "[486 MCA] IBM PS/2 model 80-486", ROM_IBMPS2_M80_486, "ibmps2_m80-486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 1, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2, 1, 32, 1, 63, machine_ps2_model_80_486_init, NULL, nvr_at_close }, From e269619ef32b3703e6e30a8a10f47f7657280459 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Mar 2018 19:42:59 +0100 Subject: [PATCH 35/39] Ported the S3 ViRGE fixes from PCem. --- src/video/vid_s3_virge.c | 118 ++++++++++++++++++++++++--------------- 1 file changed, 73 insertions(+), 45 deletions(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 5747d1119..462fa5146 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.6 2018/03/18 + * Version: @(#)vid_s3_virge.c 1.0.7 2018/03/22 * * Authors: Sarah Walker, * Miran Grca, @@ -131,8 +131,6 @@ typedef struct virge_t uint8_t bank; uint8_t ma_ext; - int width; - int bpp; uint8_t virge_id, virge_id_high, virge_id_low, virge_rev; @@ -155,8 +153,8 @@ typedef struct virge_t event_t *wake_main_thread; event_t *not_full_event; - uint32_t hwcursor_col[2]; - int hwcursor_col_pos; + uint32_t hwc_fg_col, hwc_bg_col; + int hwc_col_stack_pos; struct { @@ -379,23 +377,9 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) virge->ma_ext = (virge->ma_ext & 0x1c) | ((val & 0x30) >> 4); break; case 0x32: - if ((svga->crtc[0x67] & 0xc) != 0xc) - svga->vram_display_mask = (val & 0x40) ? 0x3ffff : ((virge->memory_size << 20) - 1); s3_virge_update_irqs(virge); break; - case 0x50: - switch (svga->crtc[0x50] & 0xc1) - { - case 0x00: virge->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; break; - case 0x01: virge->width = 1152; break; - case 0x40: virge->width = 640; break; - case 0x80: virge->width = 800; break; - case 0x81: virge->width = 1600; break; - case 0xc0: virge->width = 1280; break; - } - virge->bpp = (svga->crtc[0x50] >> 4) & 3; - break; case 0x69: virge->ma_ext = val & 0x1f; break; @@ -434,16 +418,34 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) break; case 0x4a: - virge->hwcursor_col[1] = (virge->hwcursor_col[1] & ~(0xff << (virge->hwcursor_col_pos * 8))) | - (val << (virge->hwcursor_col_pos * 8)); - virge->hwcursor_col_pos++; - virge->hwcursor_col_pos &= 3; + switch (virge->hwc_col_stack_pos) + { + case 0: + virge->hwc_fg_col = (virge->hwc_fg_col & 0xffff00) | val; + break; + case 1: + virge->hwc_fg_col = (virge->hwc_fg_col & 0xff00ff) | (val << 8); + break; + case 2: + virge->hwc_fg_col = (virge->hwc_fg_col & 0x00ffff) | (val << 16); + break; + } + virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3; break; case 0x4b: - virge->hwcursor_col[0] = (virge->hwcursor_col[0] & ~(0xff << (virge->hwcursor_col_pos * 8))) | - (val << (virge->hwcursor_col_pos * 8)); - virge->hwcursor_col_pos++; - virge->hwcursor_col_pos &= 3; + switch (virge->hwc_col_stack_pos) + { + case 0: + virge->hwc_bg_col = (virge->hwc_bg_col & 0xffff00) | val; + break; + case 1: + virge->hwc_bg_col = (virge->hwc_bg_col & 0xff00ff) | (val << 8); + break; + case 2: + virge->hwc_bg_col = (virge->hwc_bg_col & 0x00ffff) | (val << 16); + break; + } + virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3; break; case 0x53: @@ -515,7 +517,7 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) case 0x31: ret = (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4); break; case 0x35: ret = (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf); break; case 0x36: ret = (svga->crtc[0x36] & 0xfc) | 2; break; /*PCI bus*/ - case 0x45: virge->hwcursor_col_pos = 0; ret = svga->crtc[0x45]; break; + case 0x45: virge->hwc_col_stack_pos = 0; ret = svga->crtc[0x45]; break; case 0x51: ret = (svga->crtc[0x51] & 0xf0) | ((virge->bank >> 2) & 0xc) | ((virge->ma_ext >> 2) & 3); break; case 0x69: ret = virge->ma_ext; break; case 0x6a: ret = virge->bank; break; @@ -584,7 +586,7 @@ static void s3_virge_recalctimings(svga_t *svga) svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/ } } - svga->vram_display_mask = (svga->crtc[0x32] & 0x40) ? 0x3ffff : ((virge->memory_size << 20) - 1); + svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : ((virge->memory_size << 20) - 1); } else /*Streams mode*/ { @@ -1810,20 +1812,20 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) switch (bpp) \ { \ case 0: /*8 bpp*/ \ - val = vram[addr & 0x3fffff]; \ + val = vram[addr & svga->vram_mask]; \ break; \ case 1: /*16 bpp*/ \ - val = *(uint16_t *)&vram[addr & 0x3fffff]; \ + val = *(uint16_t *)&vram[addr & svga->vram_mask]; \ break; \ case 2: /*24 bpp*/ \ - val = (*(uint32_t *)&vram[addr & 0x3fffff]) & 0xffffff; \ + val = (*(uint32_t *)&vram[addr & svga->vram_mask]) & 0xffffff; \ break; \ } \ } while (0) -#define Z_READ(addr) *(uint16_t *)&vram[addr & 0x3fffff] +#define Z_READ(addr) *(uint16_t *)&vram[addr & svga->vram_mask] -#define Z_WRITE(addr, val) if (!(s3d_tri->cmd_set & CMD_SET_ZB_MODE)) *(uint16_t *)&vram[addr & 0x3fffff] = val +#define Z_WRITE(addr, val) if (!(s3d_tri->cmd_set & CMD_SET_ZB_MODE)) *(uint16_t *)&vram[addr & svga->vram_mask] = val #define CLIP(x, y) \ do \ @@ -1883,23 +1885,24 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) switch (bpp) \ { \ case 0: /*8 bpp*/ \ - vram[addr & 0x3fffff] = val; \ - virge->svga.changedvram[(addr & 0x3fffff) >> 12] = changeframecount; \ + vram[addr & svga->vram_mask] = val; \ + virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = changeframecount; \ break; \ case 1: /*16 bpp*/ \ - *(uint16_t *)&vram[addr & 0x3fffff] = val; \ - virge->svga.changedvram[(addr & 0x3fffff) >> 12] = changeframecount; \ + *(uint16_t *)&vram[addr & svga->vram_mask] = val; \ + virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = changeframecount; \ break; \ case 2: /*24 bpp*/ \ - *(uint32_t *)&vram[addr & 0x3fffff] = (val & 0xffffff) | \ - (vram[(addr + 3) & 0x3fffff] << 24); \ - virge->svga.changedvram[(addr & 0x3fffff) >> 12] = changeframecount; \ + *(uint32_t *)&vram[addr & svga->vram_mask] = (val & 0xffffff) | \ + (vram[(addr + 3) & svga->vram_mask] << 24); \ + virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = changeframecount; \ break; \ } \ } while (0) static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) { + svga_t *svga = &virge->svga; uint8_t *vram = virge->svga.vram; uint32_t mono_pattern[64]; int count_mask; @@ -2916,6 +2919,7 @@ static void dest_pixel_lit_texture_modulate(s3d_state_t *state) static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int32_t dx2) { + svga_t *svga = &virge->svga; uint8_t *vram = virge->svga.vram; int x_dir = s3d_tri->tlr ? 1 : -1; @@ -3059,7 +3063,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 } } - virge->svga.changedvram[(dest_offset & 0x3fffff) >> 12] = changeframecount; + virge->svga.changedvram[(dest_offset & svga->vram_mask) >> 12] = changeframecount; dest_addr = dest_offset + (x * (bpp + 1)); z_addr = z_offset + (x << 1); @@ -3089,7 +3093,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 /*Not implemented yet*/ break; case 1: /*16 bpp*/ - src_col = *(uint16_t *)&vram[dest_addr & 0x3fffff]; + src_col = *(uint16_t *)&vram[dest_addr & svga->vram_mask]; RGB15_TO_24(src_col, src_r, src_g, src_b); break; case 2: /*24 bpp*/ @@ -3352,12 +3356,36 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) uint16_t dat[2]; int xx; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + uint32_t fg, bg; int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; + switch (svga->bpp) + { + case 15: + fg = video_15to32[virge->hwc_fg_col & 0xffff]; + bg = video_15to32[virge->hwc_bg_col & 0xffff]; + break; + + case 16: + fg = video_16to32[virge->hwc_fg_col & 0xffff]; + bg = video_16to32[virge->hwc_bg_col & 0xffff]; + break; + + case 24: case 32: + fg = virge->hwc_fg_col; + bg = virge->hwc_bg_col; + break; + + default: + fg = svga->pallook[virge->hwc_fg_col & 0xff]; + bg = svga->pallook[virge->hwc_bg_col & 0xff]; + break; + } + for (x = 0; x < 64; x += 16) { dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1]; @@ -3370,7 +3398,7 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) if (offset >= svga->hwcursor_latch.x) { if (dat[0] & 0x8000) - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = virge->hwcursor_col[dat[1] >> 15]; + ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = (dat[1] & 0x8000) ? fg : bg; } offset++; @@ -3386,7 +3414,7 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) if (offset >= svga->hwcursor_latch.x) { if (!(dat[0] & 0x8000)) - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = virge->hwcursor_col[dat[1] >> 15]; + ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = (dat[1] & 0x8000) ? fg : bg; else if (dat[1] & 0x8000) ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; } From a5aae09eb7cbb3b2d24b9bc02cf2ca39f3ebd676 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Mar 2018 23:37:36 +0100 Subject: [PATCH 36/39] Fixed a minor issue in the S3 ViRGE emulation caused by me when porting the latest PCem commits. --- src/video/vid_s3_virge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 462fa5146..bb104c921 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.7 2018/03/22 + * Version: @(#)vid_s3_virge.c 1.0.8 2018/03/22 * * Authors: Sarah Walker, * Miran Grca, @@ -3097,7 +3097,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 RGB15_TO_24(src_col, src_r, src_g, src_b); break; case 2: /*24 bpp*/ - src_col = (*(uint32_t *)&vram[dest_addr & 0x3fffff]) & 0xffffff; + src_col = (*(uint32_t *)&vram[dest_addr & svga->vram_mask]) & 0xffffff; RGB24_TO_24(src_col, src_r, src_g, src_b); break; } From 46b0b17454a7d37b331eca19a3cdce19d71bd72a Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Mar 2018 03:19:27 +0100 Subject: [PATCH 37/39] The CL-GD 5428 ISA now uses the correct BIOS again. --- src/video/vid_cl54xx.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 5c2cdeadb..d590d291c 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, CL-GD 5430, CL-GD 5434 and CL-GD 5436 are supported). * - * Version: @(#)vid_cl_54xx.c 1.0.13 2018/03/22 + * Version: @(#)vid_cl_54xx.c 1.0.14 2018/03/23 * * Authors: Sarah Walker, * Barry Rodewald, @@ -40,6 +40,7 @@ #include "vid_cl54xx.h" #define BIOS_GD5426_PATH L"roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin" +#define BIOS_GD5428_ISA_PATH L"roms/video/cirruslogic/5428.bin" #define BIOS_GD5428_PATH L"roms/video/cirruslogic/vlbusjapan.BIN" #define BIOS_GD5429_PATH L"roms/video/cirruslogic/5429.vbi" #define BIOS_GD5430_VLB_PATH L"roms/video/cirruslogic/diamondvlbus.bin" @@ -2224,7 +2225,10 @@ static void break; case CIRRUS_ID_CLGD5428: - romfn = BIOS_GD5428_PATH; + if (gd54xx->vlb) + romfn = BIOS_GD5428_PATH; + else + romfn = BIOS_GD5428_ISA_PATH; break; case CIRRUS_ID_CLGD5429: @@ -2261,7 +2265,7 @@ static void gd54xx->vram_size = device_get_config_int("memory"); gd54xx->vram_mask = (gd54xx->vram_size << 20) - 1; - rom_init(&gd54xx->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&gd54xx->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&gd54xx->svga, gd54xx, gd54xx->vram_size << 20, gd54xx_recalctimings, gd54xx_in, gd54xx_out, @@ -2311,6 +2315,12 @@ gd5428_available(void) return rom_present(BIOS_GD5428_PATH); } +static int +gd5428_isa_available(void) +{ + return rom_present(BIOS_GD5428_ISA_PATH); +} + static int gd5429_available(void) { @@ -2474,7 +2484,7 @@ const device_t gd5428_isa_device = gd54xx_init, gd54xx_close, NULL, - gd5428_available, + gd5428_isa_available, gd54xx_speed_changed, gd54xx_force_redraw, gd54xx_add_status_info, From 48c44b53832ee474fbfec770bc0ccff3266233c8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Mar 2018 04:40:49 +0100 Subject: [PATCH 38/39] Implemented support for the special Cirrus Logic extended DAC color palette; Slightly reworked the Cirrus Logic hardware cursor handler, it now loads the foreground and background colors from the special color palette; Implemented Cirrus Logic SR 0x12 bit 7 that if set, makes the card use special color palette entry 2 for the overscan border color instead of attribute register 0x11. --- src/video/vid_cl54xx.c | 220 +++++++++++++++++++++++++++++++++-------- src/video/vid_svga.c | 24 +++-- src/video/vid_svga.h | 3 +- 3 files changed, 196 insertions(+), 51 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index d590d291c..576d4eeea 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, CL-GD 5430, CL-GD 5434 and CL-GD 5436 are supported). * - * Version: @(#)vid_cl_54xx.c 1.0.14 2018/03/23 + * Version: @(#)vid_cl_54xx.c 1.0.15 2018/03/23 * * Authors: Sarah Walker, * Barry Rodewald, @@ -163,16 +163,20 @@ typedef struct gd54xx_t uint16_t pixel_cnt; uint16_t scan_cnt; } blt; - - int pci, vlb; - - uint8_t pci_regs[256]; - uint8_t int_line; - int card; - - uint32_t lfb_base; - - int mmio_vram_overlap; + + int pci, vlb; + + uint8_t pci_regs[256]; + uint8_t int_line; + + int card; + + uint32_t lfb_base; + + int mmio_vram_overlap; + + uint32_t extpallook[256]; + PALETTE extpal; } gd54xx_t; static void @@ -203,16 +207,57 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) gd54xx_t *gd54xx = (gd54xx_t *)p; svga_t *svga = &gd54xx->svga; uint8_t old; + int c; + uint8_t o; + uint32_t o32; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) { + case 0x3c0: + case 0x3c1: + if (!svga->attrff) { + svga->attraddr = val & 31; + if ((val & 0x20) != svga->attr_palette_enable) { + svga->fullchange = 3; + svga->attr_palette_enable = val & 0x20; + svga_recalctimings(svga); + } + } else { + o = svga->attrregs[svga->attraddr & 31]; + svga->attrregs[svga->attraddr & 31] = val; + if (svga->attraddr < 16) + svga->fullchange = changeframecount; + if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { + for (c = 0; c < 16; c++) { + if (svga->attrregs[0x10] & 0x80) svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); + else svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4); + } + } + /* Recalculate timings on change of attribute register 0x11 (overscan border color) too. */ + if (svga->attraddr == 0x10) { + if (o != val) + svga_recalctimings(svga); + } else if (svga->attraddr == 0x11) { + if (!(svga->seqregs[0x12] & 0x80)) { + svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; + if (o != val) svga_recalctimings(svga); + } + } else if (svga->attraddr == 0x12) { + if ((val & 0xf) != svga->plane_mask) + svga->fullchange = changeframecount; + svga->plane_mask = val & 0xf; + } + } + svga->attrff ^= 1; + return; case 0x3c4: svga->seqaddr = val; break; case 0x3c5: if (svga->seqaddr > 5) { + o = svga->seqregs[svga->seqaddr & 0x1f]; svga->seqregs[svga->seqaddr & 0x1f] = val; switch (svga->seqaddr & 0x1f) { case 6: @@ -237,18 +282,30 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.y = (val << 3) | (svga->seqaddr >> 5); break; case 0x12: - svga->hwcursor.ena = val & CIRRUS_CURSOR_SHOW; - svga->hwcursor.xsize = svga->hwcursor.ysize = (val & CIRRUS_CURSOR_LARGE) ? 64 : 32; - if (val & CIRRUS_CURSOR_LARGE) - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((svga->seqregs[0x13] & 0x3c) * 256)); - else - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((svga->seqregs[0x13] & 0x3f) * 256)); + if ((o ^ val) & 0x80) { + if (val & 0x80) + svga->overscan_color = gd54xx->extpallook[2]; + else + svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; + svga_recalctimings(svga); + } + if ((o ^ val) & CIRRUS_CURSOR_SHOW) + svga->hwcursor.ena = val & CIRRUS_CURSOR_SHOW; + if ((o ^ val) & CIRRUS_CURSOR_LARGE) { + svga->hwcursor.xsize = svga->hwcursor.ysize = (val & CIRRUS_CURSOR_LARGE) ? 64 : 32; + if (val & CIRRUS_CURSOR_LARGE) + svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((svga->seqregs[0x13] & 0x3c) * 256)); + else + svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((svga->seqregs[0x13] & 0x3f) * 256)); + } break; case 0x13: - if (svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3c) * 256)); - else - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3f) * 256)); + if (o != val) { + if (svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) + svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3c) * 256)); + else + svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3f) * 256)); + } break; case 0x07: svga->set_reset_disabled = svga->seqregs[7] & 1; @@ -268,6 +325,42 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) } gd54xx->ramdac.state = 0; break; + case 0x3C9: + svga->dac_status = 0; + svga->fullchange = changeframecount; + switch (svga->dac_pos) { + case 0: + svga->dac_r = val; + svga->dac_pos++; + break; + case 1: + svga->dac_g = val; + svga->dac_pos++; + break; + case 2: + if (svga->seqregs[0x12] & 2) { + gd54xx->extpal[svga->dac_write].r = svga->dac_r; + gd54xx->extpal[svga->dac_write].g = svga->dac_g; + gd54xx->extpal[svga->dac_write].b = val; + gd54xx->extpallook[svga->dac_write & 15] = makecol32(video_6to8[gd54xx->extpal[svga->dac_write].r & 0x3f], video_6to8[gd54xx->extpal[svga->dac_write].g & 0x3f], video_6to8[gd54xx->extpal[svga->dac_write].b & 0x3f]); + if ((svga->seqregs[0x12] & 0x80) && ((svga->dac_write & 15) == 2)) { + o32 = svga->overscan_color; + svga->overscan_color = gd54xx->extpallook[2]; + if (o32 != svga->overscan_color) + svga_recalctimings(svga); + } + svga->dac_write = (svga->dac_write + 1) & 15; + } else { + svga->vgapal[svga->dac_write].r = svga->dac_r; + svga->vgapal[svga->dac_write].g = svga->dac_g; + svga->vgapal[svga->dac_write].b = val; + svga->pallook[svga->dac_write] = makecol32(video_6to8[svga->vgapal[svga->dac_write].r & 0x3f], video_6to8[svga->vgapal[svga->dac_write].g & 0x3f], video_6to8[svga->vgapal[svga->dac_write].b & 0x3f]); + svga->dac_write = (svga->dac_write + 1) & 255; + } + svga->dac_pos = 0; + break; + } + return; case 0x3cf: if (svga->gdcaddr == 0) gd543x_mmio_write(0xb8000, val, gd54xx); @@ -487,6 +580,32 @@ gd54xx_in(uint16_t addr, void *p) return svga->seqregs[svga->seqaddr & 0x3f]; } break; + case 0x3c9: + svga->dac_status = 3; + switch (svga->dac_pos) { + case 0: + svga->dac_pos++; + if (svga->seqregs[0x12] & 2) + return gd54xx->extpal[svga->dac_read].r & 0x3f; + else + return svga->vgapal[svga->dac_read].r & 0x3f; + case 1: + svga->dac_pos++; + if (svga->seqregs[0x12] & 2) + return gd54xx->extpal[svga->dac_read].g & 0x3f; + else + return svga->vgapal[svga->dac_read].g & 0x3f; + case 2: + svga->dac_pos=0; + if (svga->seqregs[0x12] & 2) { + svga->dac_read = (svga->dac_read + 1) & 15; + return gd54xx->extpal[(svga->dac_read - 1) & 15].b & 0x3f; + } else { + svga->dac_read = (svga->dac_read + 1) & 255; + return svga->vgapal[(svga->dac_read - 1) & 255].b & 0x3f; + } + } + return 0xFF; case 0x3C6: if (gd54xx->ramdac.state == 4) { gd54xx->ramdac.state = 0; @@ -740,18 +859,20 @@ gd54xx_recalctimings(svga_t *svga) static void gd54xx_hwcursor_draw(svga_t *svga, int displine) { - int x; - uint8_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; - int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; - int pitch = (svga->hwcursor.xsize == 64) ? 16 : 4; - - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += pitch; - - for (x = 0; x < svga->hwcursor.xsize; x += 8) { + gd54xx_t *gd54xx = (gd54xx_t *)svga->p; + int x, xx, comb; + uint8_t dat[2]; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; + int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; + int pitch = (svga->hwcursor.xsize == 64) ? 16 : 4; + uint32_t bgcol = gd54xx->extpallook[0x00]; + uint32_t fgcol = gd54xx->extpallook[0x0f]; + + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += pitch; + + for (x = 0; x < svga->hwcursor.xsize; x += 8) { dat[0] = svga->vram[svga->hwcursor_latch.addr]; if (svga->hwcursor.xsize == 64) dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x08]; @@ -759,10 +880,25 @@ void gd54xx_hwcursor_draw(svga_t *svga, int displine) dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; for (xx = 0; xx < 8; xx++) { if (offset >= svga->hwcursor_latch.x) { - if (dat[1] & 0x80) - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = 0; - if (dat[0] & 0x80) - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; + comb = ((dat[0] & 0x80) >> 6) | ((dat[1] & 0x80) >> 7); + switch(comb) { + case 0: + /* The original screen pixel is shown (invisible cursor) */ + break; + case 1: + /* The pixel is shown in the cursor background color */ + ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = bgcol; + break; + case 2: + /* The pixel is shown as the inverse of the original screen pixel + (XOR cursor) */ + ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; + break; + case 3: + /* The pixel is shown in the cursor foreground color */ + ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = fgcol; + break; + } } offset++; @@ -770,12 +906,12 @@ void gd54xx_hwcursor_draw(svga_t *svga, int displine) dat[1] <<= 1; } svga->hwcursor_latch.addr++; - } - - if (svga->hwcursor.xsize == 64) + } + + if (svga->hwcursor.xsize == 64) svga->hwcursor_latch.addr += 8; - - if (svga->interlace && !svga->hwcursor_oddeven) + + if (svga->interlace && !svga->hwcursor_oddeven) svga->hwcursor_latch.addr += pitch; } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index f09b99f6d..cb03307a2 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -11,7 +11,7 @@ * This is intended to be used by another SVGA driver, * and not as a card in it's own right. * - * Version: @(#)vid_svga.c 1.0.26 2018/03/16 + * Version: @(#)vid_svga.c 1.0.27 2018/03/23 * * Authors: Sarah Walker, * Miran Grca, @@ -69,7 +69,7 @@ void svga_out(uint16_t addr, uint8_t val, void *p) switch (addr) { case 0x3C0: - case 0x3C1: + case 0x3C1: if (!svga->attrff) { svga->attraddr = val & 31; @@ -95,9 +95,16 @@ void svga_out(uint16_t addr, uint8_t val, void *p) } } /* Recalculate timings on change of attribute register 0x11 (overscan border color) too. */ - if ((svga->attraddr == 0x10) || (svga->attraddr == 0x11)) + if (svga->attraddr == 0x10) + { if (o != val) svga_recalctimings(svga); - if (svga->attraddr == 0x12) + } + else if (svga->attraddr == 0x11) + { + svga->overscan_color = svga->pallook[svga->overscan_color]; + if (o != val) svga_recalctimings(svga); + } + else if (svga->attraddr == 0x12) { if ((val & 0xf) != svga->plane_mask) svga->fullchange = changeframecount; @@ -687,6 +694,7 @@ int svga_init(svga_t *svga, void *p, int memsize, svga->readmode = 0; svga->attrregs[0x11] = 0; + svga->overscan_color = 0x000000; overscan_x = 16; overscan_y = 32; @@ -1270,7 +1278,7 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) p = &((uint32_t *)buffer32->line[i & 0x7ff])[32]; for (j = 0; j < (xsize + x_add); j++) - p[j] = svga_color_transform(svga->pallook[svga->attrregs[0x11]]); + p[j] = svga_color_transform(svga->overscan_color); } /* Draw (overscan_size + scroll size) lines of overscan on the bottom. */ @@ -1278,15 +1286,15 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) p = &((uint32_t *)buffer32->line[(ysize + (y_add >> 1) + i) & 0x7ff])[32]; for (j = 0; j < (xsize + x_add); j++) - p[j] = svga_color_transform(svga->pallook[svga->attrregs[0x11]]); + p[j] = svga_color_transform(svga->overscan_color); } for (i = (y_add >> 1); i < (ysize + (y_add >> 1)); i ++) { p = &((uint32_t *)buffer32->line[i & 0x7ff])[32]; for (j = 0; j < 8; j++) { - p[j] = svga_color_transform(svga->pallook[svga->attrregs[0x11]]); - p[xsize + (x_add >> 1) + j] = svga_color_transform(svga->pallook[svga->attrregs[0x11]]); + p[j] = svga->pallook[svga->overscan_color]; + p[xsize + (x_add >> 1) + j] = svga_color_transform(svga->overscan_color); } } } diff --git a/src/video/vid_svga.h b/src/video/vid_svga.h index bf1189ed4..b2811995b 100644 --- a/src/video/vid_svga.h +++ b/src/video/vid_svga.h @@ -8,7 +8,7 @@ * * Generic SVGA handling. * - * Version: @(#)vid_svga.h 1.0.9 2018/03/01 + * Version: @(#)vid_svga.h 1.0.10 2018/03/23 * * Authors: Sarah Walker, * Miran Grca, @@ -153,6 +153,7 @@ typedef struct svga_t void *p; uint32_t linear_base; + uint32_t overscan_color; } svga_t; extern int svga_init(svga_t *svga, void *p, int memsize, From a26d47720884a2c05463a467222d3ec4d398a8f1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Mar 2018 05:26:28 +0100 Subject: [PATCH 39/39] More Cirrus Logic cursor-related fixes, fixes the hardware cursor on Windows NT 5.x. --- src/video/vid_cl54xx.c | 49 ++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 576d4eeea..81960c350 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, CL-GD 5430, CL-GD 5434 and CL-GD 5436 are supported). * - * Version: @(#)vid_cl_54xx.c 1.0.15 2018/03/23 + * Version: @(#)vid_cl_54xx.c 1.0.16 2018/03/23 * * Authors: Sarah Walker, * Barry Rodewald, @@ -282,30 +282,23 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.y = (val << 3) | (svga->seqaddr >> 5); break; case 0x12: - if ((o ^ val) & 0x80) { - if (val & 0x80) - svga->overscan_color = gd54xx->extpallook[2]; - else - svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; - svga_recalctimings(svga); - } - if ((o ^ val) & CIRRUS_CURSOR_SHOW) - svga->hwcursor.ena = val & CIRRUS_CURSOR_SHOW; - if ((o ^ val) & CIRRUS_CURSOR_LARGE) { - svga->hwcursor.xsize = svga->hwcursor.ysize = (val & CIRRUS_CURSOR_LARGE) ? 64 : 32; - if (val & CIRRUS_CURSOR_LARGE) - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((svga->seqregs[0x13] & 0x3c) * 256)); - else - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((svga->seqregs[0x13] & 0x3f) * 256)); - } + if (val & 0x80) + svga->overscan_color = gd54xx->extpallook[2]; + else + svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; + svga_recalctimings(svga); + svga->hwcursor.ena = val & CIRRUS_CURSOR_SHOW; + svga->hwcursor.xsize = svga->hwcursor.ysize = (val & CIRRUS_CURSOR_LARGE) ? 64 : 32; + if (val & CIRRUS_CURSOR_LARGE) + svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((svga->seqregs[0x13] & 0x3c) * 256)); + else + svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((svga->seqregs[0x13] & 0x3f) * 256)); break; case 0x13: - if (o != val) { - if (svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3c) * 256)); - else - svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3f) * 256)); - } + if (svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) + svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3c) * 256)); + else + svga->hwcursor.addr = (((gd54xx->vram_size<<20)-0x4000) + ((val & 0x3f) * 256)); break; case 0x07: svga->set_reset_disabled = svga->seqregs[7] & 1; @@ -860,7 +853,7 @@ static void gd54xx_hwcursor_draw(svga_t *svga, int displine) { gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - int x, xx, comb; + int x, xx, comb, b0, b1; uint8_t dat[2]; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; @@ -870,7 +863,7 @@ void gd54xx_hwcursor_draw(svga_t *svga, int displine) uint32_t fgcol = gd54xx->extpallook[0x0f]; if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += pitch; + svga->hwcursor_latch.addr += pitch; for (x = 0; x < svga->hwcursor.xsize; x += 8) { dat[0] = svga->vram[svga->hwcursor_latch.addr]; @@ -879,8 +872,10 @@ void gd54xx_hwcursor_draw(svga_t *svga, int displine) else dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; for (xx = 0; xx < 8; xx++) { + b0 = (dat[0] >> (7 - xx)) & 1; + b1 = (dat[1] >> (7 - xx)) & 1; + comb = (b1 | (b0 << 1)); if (offset >= svga->hwcursor_latch.x) { - comb = ((dat[0] & 0x80) >> 6) | ((dat[1] & 0x80) >> 7); switch(comb) { case 0: /* The original screen pixel is shown (invisible cursor) */ @@ -902,8 +897,6 @@ void gd54xx_hwcursor_draw(svga_t *svga, int displine) } offset++; - dat[0] <<= 1; - dat[1] <<= 1; } svga->hwcursor_latch.addr++; }