diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index e72c2f890..65743bead 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.32 2018/02/25 + * Version: @(#)cdrom.c 1.0.33 2018/02/27 * * Author: Miran Grca, * @@ -684,6 +684,7 @@ 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) { uint32_t bt; + cdrom[id].max_transfer_len = cdrom[id].request_length; /* For media access commands, make sure the requested DRQ length matches the block length. */ switch (cdrom[id].current_cdb[0]) { @@ -692,8 +693,8 @@ void cdrom_update_request_length(uint8_t id, int len, int block_len) case 0xa8: case 0xb9: case 0xbe: - if (cdrom[id].request_length < block_len) - cdrom[id].request_length = block_len; + if (cdrom[id].max_transfer_len < block_len) + cdrom[id].max_transfer_len = block_len; bt = (cdrom[id].requested_blocks * block_len); if (len > bt) len = bt; @@ -702,11 +703,13 @@ void cdrom_update_request_length(uint8_t id, int len, int block_len) break; } /* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */ - if ((cdrom[id].request_length & 1) && (cdrom[id].request_length < len)) - cdrom[id].request_length &= 0xfffe; + if ((cdrom[id].max_transfer_len & 1) && (cdrom[id].max_transfer_len < len)) + cdrom[id].max_transfer_len &= 0xfffe; /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ - if (len <= cdrom[id].request_length) - cdrom[id].request_length = len; + 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; return; } @@ -765,13 +768,6 @@ static void cdrom_command_write_dma(uint8_t id) cdrom_command_common(id); } -static int cdrom_request_length_is_zero(uint8_t id) -{ - if ((cdrom[id].request_length == 0) && (cdrom_drives[id].bus_type < CDROM_BUS_SCSI)) - return 1; - return 0; -} - /* id = Current CD-ROM device ID; len = Total transfer length; block_len = Length of a single block (why does it matter?!); @@ -786,7 +782,7 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al len = alloc_len; } } - if (cdrom_request_length_is_zero(id) || (len == 0) || (cdrom_current_mode(id) == 0)) { + if ((len == 0) || (cdrom_current_mode(id) == 0)) { if (cdrom_drives[id].bus_type != CDROM_BUS_SCSI) { cdrom[id].packet_len = 0; } @@ -2675,9 +2671,9 @@ void cdrom_pio_request(uint8_t id, uint8_t out) /* If less than (packet length) bytes are remaining, update packet length accordingly. */ - if ((cdrom[id].packet_len - cdrom[id].pos) < (cdrom[id].request_length)) - cdrom[id].request_length = 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].request_length); + 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); old_pos = cdrom[id].pos; cdrom[id].packet_status = out ? CDROM_PHASE_DATA_OUT : CDROM_PHASE_DATA_IN; @@ -2732,8 +2728,6 @@ int cdrom_read_from_dma(uint8_t id) int ret = 0; - int in_data_length = 0; - if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) ret = cdrom_read_from_scsi_dma(cdrom_drives[id].scsi_device_id, cdrom_drives[id].scsi_device_lun); else @@ -2742,13 +2736,10 @@ int cdrom_read_from_dma(uint8_t id) if (!ret) return 0; - if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { - in_data_length = *BufLen; - cdrom_log("CD-ROM %i: SCSI Input data length: %i\n", id, in_data_length); - } else { - in_data_length = cdrom[id].request_length; - cdrom_log("CD-ROM %i: ATAPI Input data length: %i\n", id, in_data_length); - } + 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); ret = cdrom_phase_data_out(id); if (!ret) { @@ -2936,7 +2927,7 @@ uint32_t cdrom_read(uint8_t channel, int length) } if (cdrom[id].packet_status == CDROM_PHASE_DATA_IN) { - if ((cdrom[id].request_pos >= cdrom[id].request_length) || (cdrom[id].pos >= cdrom[id].packet_len)) { + if ((cdrom[id].request_pos >= cdrom[id].max_transfer_len) || (cdrom[id].pos >= cdrom[id].packet_len)) { /* Time for a DRQ. */ // cdrom_log("CD-ROM %i: Issuing read callback\n", id); cdrom_pio_request(id, 0); @@ -2992,7 +2983,7 @@ void cdrom_write(uint8_t channel, uint32_t val, int length) } if (cdrom[id].packet_status == CDROM_PHASE_DATA_OUT) { - if ((cdrom[id].request_pos >= cdrom[id].request_length) || (cdrom[id].pos >= cdrom[id].packet_len)) { + if ((cdrom[id].request_pos >= cdrom[id].max_transfer_len) || (cdrom[id].pos >= cdrom[id].packet_len)) { /* Time for a DRQ. */ cdrom_pio_request(id, 1); } diff --git a/src/cdrom/cdrom.h b/src/cdrom/cdrom.h index ca6650621..bf208267f 100644 --- a/src/cdrom/cdrom.h +++ b/src/cdrom/cdrom.h @@ -103,6 +103,7 @@ typedef struct { uint8_t error; uint8_t features; uint16_t request_length; + uint16_t max_transfer_len; uint8_t status; uint8_t phase; diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index d215ec77c..0e2b8d09c 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.28 2018/02/25 + * Version: @(#)hdc_ide.c 1.0.29 2018/02/27 * * Authors: Sarah Walker, * Miran Grca, @@ -447,6 +447,7 @@ static void ide_atapi_identify(IDE *ide) ide->buffer[48] = 1; /*Dword transfers supported*/ ide->buffer[49] = 0x200; /* LBA supported */ ide->buffer[51] = 2 << 8; /*PIO timing mode*/ + ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ if (PCI && (ide->board < 2) && (cdrom_drives[cdrom_id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA)) { @@ -499,6 +500,8 @@ static void ide_atapi_zip_identify(IDE *ide) ide->buffer[48] = 1; /*Dword transfers supported*/ ide->buffer[51] = 2 << 8; /*PIO timing mode*/ + ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ + if (PCI && (ide->board < 2) && (zip_drives[zip_id].bus_type == ZIP_BUS_ATAPI_PIO_AND_DMA)) { ide->buffer[49] |= 0x100; /* DMA supported */ diff --git a/src/nvr_at.c b/src/nvr_at.c index 2f470b0f6..131d1415c 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -14,13 +14,13 @@ * of those batteries would create corrosion issues later on * in mainboard life... * - * Version: @(#)nvr_at.c 1.0.8 2017/11/22 + * Version: @(#)nvr_at.c 1.0.9 2018/02/27 * * Authors: 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. */ #include #include @@ -45,6 +45,8 @@ nvr_write(uint16_t addr, uint8_t val, void *priv) { nvr_t *nvr = (nvr_t *)priv; + cycles -= ISA_CYCLES(8); + if (! (addr & 1)) { nvr->addr = (val & nvr->mask); if (!(machines[machine].flags & MACHINE_MCA) && (romset != ROM_IBMPS1_2133)) @@ -64,6 +66,8 @@ nvr_read(uint16_t addr, void *priv) nvr_t *nvr = (nvr_t *)priv; uint8_t ret; + cycles -= ISA_CYCLES(8); + if (addr & 1) { /* Read from the chip's registers. */ ret = (*nvr->get)(nvr, nvr->addr); diff --git a/src/zip.c b/src/zip.c index f6726f413..0cbd43ce5 100644 --- a/src/zip.c +++ b/src/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.5 2018/02/15 + * Version: @(#)zip.c 1.0.6 2018/02/27 * * 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 @@ -903,14 +902,18 @@ uint32_t zip_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, ui void zip_update_request_length(uint8_t id, int len, int block_len) { uint32_t bt; + if (!zip[id].request_length) + zip[id].max_transfer_len = 65534; + else + zip[id].max_transfer_len = zip[id].request_length; /* For media access commands, make sure the requested DRQ length matches the block length. */ switch (zip[id].current_cdb[0]) { case 0x08: case 0x28: case 0xa8: - if (zip[id].request_length < block_len) - zip[id].request_length = block_len; + if (zip[id].max_transfer_len < block_len) + zip[id].max_transfer_len = block_len; bt = (zip[id].requested_blocks * block_len); if (len > bt) len = bt; @@ -919,11 +922,11 @@ void zip_update_request_length(uint8_t id, int len, int block_len) break; } /* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */ - if ((zip[id].request_length & 1) && (zip[id].request_length < len)) - zip[id].request_length &= 0xfffe; + if ((zip[id].max_transfer_len & 1) && (zip[id].max_transfer_len < len)) + zip[id].max_transfer_len &= 0xfffe; /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ - if (len <= zip[id].request_length) - zip[id].request_length = len; + if (len <= zip[id].max_transfer_len) + zip[id].max_transfer_len = len; return; } @@ -982,13 +985,6 @@ static void zip_command_write_dma(uint8_t id) zip_command_common(id); } -static int zip_request_length_is_zero(uint8_t id) -{ - if ((zip[id].request_length == 0) && (zip_drives[id].bus_type < ZIP_BUS_SCSI)) - return 1; - return 0; -} - /* id = Current ZIP device ID; len = Total transfer length; block_len = Length of a single block (why does it matter?!); @@ -1003,7 +999,7 @@ static void zip_data_command_finish(uint8_t id, int len, int block_len, int allo len = alloc_len; } } - if (zip_request_length_is_zero(id) || (len == 0) || (zip_current_mode(id) == 0)) { + if ((len == 0) || (zip_current_mode(id) == 0)) { if (zip_drives[id].bus_type != ZIP_BUS_SCSI) { zip[id].packet_len = 0; } @@ -2194,8 +2190,8 @@ void zip_pio_request(uint8_t id, uint8_t out) /* If less than (packet length) bytes are remaining, update packet length accordingly. */ - if ((zip[id].packet_len - zip[id].pos) < (zip[id].request_length)) - zip[id].request_length = zip[id].packet_len - zip[id].pos; + if ((zip[id].packet_len - zip[id].pos) < (zip[id].max_transfer_len)) + zip[id].max_transfer_len = zip[id].packet_len - zip[id].pos; old_pos = zip[id].pos; zip[id].packet_status = out ? ZIP_PHASE_DATA_OUT : ZIP_PHASE_DATA_IN; @@ -2263,7 +2259,7 @@ int zip_read_from_dma(uint8_t id) in_data_length = *BufLen; zip_log("ZIP %i: SCSI Input data length: %i\n", id, in_data_length); } else { - in_data_length = zip[id].request_length; + in_data_length = zip[id].max_transfer_len; zip_log("ZIP %i: ATAPI Input data length: %i\n", id, in_data_length); } @@ -2453,7 +2449,7 @@ uint32_t zip_read(uint8_t channel, int length) } if (zip[id].packet_status == ZIP_PHASE_DATA_IN) { - if ((zip[id].request_pos >= zip[id].request_length) || (zip[id].pos >= zip[id].packet_len)) { + if ((zip[id].request_pos >= zip[id].max_transfer_len) || (zip[id].pos >= zip[id].packet_len)) { /* Time for a DRQ. */ // zip_log("ZIP %i: Issuing read callback\n", id); zip_pio_request(id, 0); @@ -2509,7 +2505,7 @@ void zip_write(uint8_t channel, uint32_t val, int length) } if (zip[id].packet_status == ZIP_PHASE_DATA_OUT) { - if ((zip[id].request_pos >= zip[id].request_length) || (zip[id].pos >= zip[id].packet_len)) { + if ((zip[id].request_pos >= zip[id].max_transfer_len) || (zip[id].pos >= zip[id].packet_len)) { /* Time for a DRQ. */ zip_pio_request(id, 1); } diff --git a/src/zip.h b/src/zip.h index be5401f7d..5705b4a0a 100644 --- a/src/zip.h +++ b/src/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.1 2018/01/26 + * Version: @(#)zip.h 1.0.2 2018/02/27 * * Author: Miran Grca, * @@ -74,6 +74,7 @@ typedef struct { uint8_t error; uint8_t features; uint16_t request_length; + uint16_t max_transfer_len; uint8_t status; uint8_t phase;