From bab6695b2c85ae71c151f4c9946b19d785a768a1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 4 Mar 2018 13:59:39 +0000 Subject: [PATCH] CD-ROM emulation now reads multiple sectors at once. --- src/cdrom-image.cc | 4 +-- src/cdrom-ioctl-linux.c | 4 +-- src/cdrom-ioctl-osx.c | 2 +- src/cdrom-ioctl.c | 28 +++++++++++----- src/cdrom-null.c | 2 +- src/ide_atapi.h | 2 +- src/scsi_cd.c | 71 ++++++++++++++++++++--------------------- 7 files changed, 61 insertions(+), 52 deletions(-) diff --git a/src/cdrom-image.cc b/src/cdrom-image.cc index 23e3fcb..99ce8ad 100644 --- a/src/cdrom-image.cc +++ b/src/cdrom-image.cc @@ -284,10 +284,10 @@ static void image_load(void) { } -static int image_readsector(uint8_t *b, int sector) +static int image_readsector(uint8_t *b, int sector, int count) { if (!cdrom) return -1; - return !cdrom->ReadSector(b, false, sector); + return !cdrom->ReadSectors((PhysPt)b, false, sector, count); } static void image_readsector_raw(uint8_t *b, int sector) diff --git a/src/cdrom-ioctl-linux.c b/src/cdrom-ioctl-linux.c index 7b8ece1..5876eca 100644 --- a/src/cdrom-ioctl-linux.c +++ b/src/cdrom-ioctl-linux.c @@ -409,13 +409,13 @@ static void ioctl_load(void) cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); } -static int ioctl_readsector(uint8_t *b, int sector) +static int ioctl_readsector(uint8_t *b, int sector, int count) { if (ioctl_fd <= 0) return -1; lseek(ioctl_fd, sector*2048, SEEK_SET); - read(ioctl_fd, b, 2048); + read(ioctl_fd, b, count*2048); return 0; } diff --git a/src/cdrom-ioctl-osx.c b/src/cdrom-ioctl-osx.c index 7f1e750..37c800f 100644 --- a/src/cdrom-ioctl-osx.c +++ b/src/cdrom-ioctl-osx.c @@ -86,7 +86,7 @@ static void ioctl_load(void) { } -static int ioctl_readsector(uint8_t *b, int sector) +static int ioctl_readsector(uint8_t *b, int sector, int count) { return 0; } diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 58e05da..3ae7a23 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -432,11 +432,11 @@ typedef struct _SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER { UCHAR SenseBuf[32]; } SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER; -static int ioctl_readsector(uint8_t *b, int sector) +static int ioctl_readsector(uint8_t *b, int sector, int count) { LARGE_INTEGER pos; BOOL status; - long size; + long size = 0; if (!cdrom_drive) return -1; @@ -448,16 +448,18 @@ static int ioctl_readsector(uint8_t *b, int sector) pos.QuadPart=sector*2048; ioctl_open(0); SetFilePointer(hIOCTL,pos.LowPart,&pos.HighPart,FILE_BEGIN); - status = ReadFile(hIOCTL,b,2048,(LPDWORD)&size,NULL); + status = ReadFile(hIOCTL, b, count*2048, (LPDWORD)&size, NULL); ioctl_close(); /*If the read failed, try again using SPTI*/ - if (!status || size != 2048) + if (!status || size != count*2048) { uint8_t cmd[12] = { 0xbe, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }; SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb; DWORD returned; - uint8_t data_buffer[IOCTL_DATA_BUFFER]; + uint8_t *data_buffer;//[IOCTL_DATA_BUFFER]; + + data_buffer = malloc(count * IOCTL_DATA_BUFFER); ioctl_open(0); @@ -466,6 +468,9 @@ static int ioctl_readsector(uint8_t *b, int sector) cmd[3] = (uint8_t)(sector >> 16); cmd[4] = (uint8_t)(sector >> 8); cmd[5] = (uint8_t)(sector >> 0); + cmd[6] = (uint8_t)(count >> 16); + cmd[7] = (uint8_t)(count >> 8); + cmd[8] = (uint8_t)(count >> 0); memset(&swb, 0, sizeof (swb)); memcpy(swb.spt.Cdb, cmd, 12); @@ -473,9 +478,9 @@ static int ioctl_readsector(uint8_t *b, int sector) swb.spt.Length = sizeof (SCSI_PASS_THROUGH); swb.spt.CdbLength = 12; swb.spt.DataIn = SCSI_IOCTL_DATA_IN; - swb.spt.DataTransferLength = IOCTL_DATA_BUFFER; + swb.spt.DataTransferLength = count*IOCTL_DATA_BUFFER; swb.spt.DataBuffer = data_buffer; - memset(data_buffer, 0, IOCTL_DATA_BUFFER); + memset(data_buffer, 0, count*IOCTL_DATA_BUFFER); swb.spt.TimeOutValue = 80 * 60; swb.spt.SenseInfoOffset = (uintptr_t)&swb.SenseBuf - (uintptr_t)&swb;//offsetof(swb, SenseBuf); swb.spt.SenseInfoLength = 32; @@ -484,9 +489,16 @@ static int ioctl_readsector(uint8_t *b, int sector) &swb, sizeof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER), &swb, sizeof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER), &returned, NULL)) - memcpy(b, data_buffer, 2048); + { + memcpy(b, data_buffer, count*2048); + status = 1; + } + else + status = 0; ioctl_close(); + + free(data_buffer); } return !status; diff --git a/src/cdrom-null.c b/src/cdrom-null.c index 5ba7320..d62f28b 100644 --- a/src/cdrom-null.c +++ b/src/cdrom-null.c @@ -59,7 +59,7 @@ static void null_load(void) { } -static int null_readsector(uint8_t *b, int sector) +static int null_readsector(uint8_t *b, int sector, int count) { return 0; } diff --git a/src/ide_atapi.h b/src/ide_atapi.h index 517417a..c46511c 100644 --- a/src/ide_atapi.h +++ b/src/ide_atapi.h @@ -12,7 +12,7 @@ typedef struct ATAPI int (*readtoc_session)(uint8_t *b, int msf, int maxlen); int (*readtoc_raw)(uint8_t *b, int maxlen); uint8_t (*getcurrentsubchannel)(uint8_t *b, int msf); - int (*readsector)(uint8_t *b, int sector); + int (*readsector)(uint8_t *b, int sector, int count); void (*readsector_raw)(uint8_t *b, int sector); void (*playaudio)(uint32_t pos, uint32_t len, int ismsf); void (*seek)(uint32_t pos); diff --git a/src/scsi_cd.c b/src/scsi_cd.c index 718c3a9..f7721f5 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -12,7 +12,7 @@ #define BUFFER_SIZE (256*1024) -#define MAX_NR_SECTORS 2 +#define MAX_NR_SECTORS 16 enum { @@ -638,28 +638,32 @@ static int scsi_cd_command(uint8_t *cdb, void *p) return SCSI_PHASE_STATUS; } - for (c = 0; c < MAX_NR_SECTORS; c++) - { - if (rcdmode == 0x10) - { - if (atapi->readsector(&data->data_in[c*2048], data->cdpos)) - { -// pclog("Read sector failed\n"); - atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - } - } - else - { - atapi->readsector_raw(&data->data_in[c*2352], data->cdpos); - } - data->cdpos++; - data->cdlen--; - if (!data->cdlen) + if (rcdmode == 0x10) + { + c = MIN(data->cdlen, MAX_NR_SECTORS); + if (atapi->readsector(data->data_in, data->cdpos, c)) { - c++; - break; +// pclog("Read sector failed\n"); + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + } + data->cdpos += c; + data->cdlen -= c; + } + else + { + for (c = 0; c < MAX_NR_SECTORS; c++) + { + atapi->readsector_raw(&data->data_in[c*2352], data->cdpos); + + data->cdpos++; + data->cdlen--; + if (!data->cdlen) + { + c++; + break; + } } } readflash_set(READFLASH_HDC, data->id); @@ -704,23 +708,16 @@ static int scsi_cd_command(uint8_t *cdb, void *p) return SCSI_PHASE_STATUS; } readflash_set(READFLASH_HDC, data->id); - for (c = 0; c < MAX_NR_SECTORS; c++) + c = MIN(data->cdlen, MAX_NR_SECTORS); + if (atapi->readsector(data->data_in, data->cdpos, c)) { - if (atapi->readsector(&data->data_in[c*2048], data->cdpos)) - { - pclog("Read sector failed\n"); - atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - } - data->cdpos++; - data->cdlen--; - if (!data->cdlen) - { - c++; - break; - } +// pclog("Read sector failed\n"); + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; } + data->cdpos += c; + data->cdlen -= c; data->data_pos_read = 0; data->data_pos_write = c * 2048;