From a59dc8e43681b5a8aee139e0cfe90769e5b25ed2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 17 Mar 2018 20:32:20 +0100 Subject: [PATCH] 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=