Current WIP CD-ROM changes.

This commit is contained in:
OBattler
2025-02-09 20:06:15 +01:00
parent f679b46b65
commit 74e0408201
17 changed files with 1201 additions and 736 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -409,7 +409,7 @@ image_get_track_and_index(const cd_image_t *img, const uint32_t sector,
for (int i = 0; i < img->tracks_num; i++) { for (int i = 0; i < img->tracks_num; i++) {
track_t *ct = &(img->tracks[i]); track_t *ct = &(img->tracks[i]);
for (int j = 0; j < 3; j++) { if ((ct->point >= 1) && (ct->point <= 99)) for (int j = 0; j < 3; j++) {
track_index_t *ci = &(ct->idx[j]); track_index_t *ci = &(ct->idx[j]);
if ((ci->type >= INDEX_ZERO) && (ci->length != 0ULL) && if ((ci->type >= INDEX_ZERO) && (ci->length != 0ULL) &&
((sector + 150) >= ci->start) && ((sector + 150) <= (ci->start + ci->length - 1))) { ((sector + 150) >= ci->start) && ((sector + 150) <= (ci->start + ci->length - 1))) {

View File

@@ -241,6 +241,7 @@ int ide_qua_enabled = 0;
static void ide_atapi_callback(ide_t *ide); static void ide_atapi_callback(ide_t *ide);
static void ide_callback(void *priv); static void ide_callback(void *priv);
#define ENABLE_IDE_LOG 1
#ifdef ENABLE_IDE_LOG #ifdef ENABLE_IDE_LOG
int ide_do_log = ENABLE_IDE_LOG; int ide_do_log = ENABLE_IDE_LOG;
@@ -1028,8 +1029,7 @@ ide_atapi_command_bus(ide_t *ide)
static void static void
ide_atapi_callback(ide_t *ide) ide_atapi_callback(ide_t *ide)
{ {
int out; static int ret = 0;
int ret = 0;
ide_bm_t *bm = ide_boards[ide->board]->bm; ide_bm_t *bm = ide_boards[ide->board]->bm;
#ifdef ENABLE_IDE_LOG #ifdef ENABLE_IDE_LOG
char *phases[7] = { "Idle", "Command", "Data in", "Data out", "Data in DMA", "Data out DMA", char *phases[7] = { "Idle", "Command", "Data in", "Data out", "Data in DMA", "Data out DMA",
@@ -1056,14 +1056,17 @@ ide_atapi_callback(ide_t *ide)
switch (ide->sc->packet_status) { switch (ide->sc->packet_status) {
default: default:
ret = 0;
break; break;
case PHASE_IDLE: case PHASE_IDLE:
ret = 0;
ide->tf->pos = 0; ide->tf->pos = 0;
ide->tf->phase = 1; ide->tf->phase = 1;
ide->tf->atastat = READY_STAT | DRQ_STAT | (ide->tf->atastat & ERR_STAT); ide->tf->atastat = READY_STAT | DRQ_STAT | (ide->tf->atastat & ERR_STAT);
break; break;
case PHASE_COMMAND: case PHASE_COMMAND:
ret = 1;
ide->tf->atastat = BUSY_STAT | (ide->tf->atastat & ERR_STAT); ide->tf->atastat = BUSY_STAT | (ide->tf->atastat & ERR_STAT);
if (ide->packet_command) { if (ide->packet_command) {
ide->packet_command(ide->sc, ide->sc->atapi_cdb); ide->packet_command(ide->sc, ide->sc->atapi_cdb);
@@ -1073,6 +1076,7 @@ ide_atapi_callback(ide_t *ide)
break; break;
case PHASE_COMPLETE: case PHASE_COMPLETE:
case PHASE_ERROR: case PHASE_ERROR:
ret = 0;
ide->tf->atastat = READY_STAT; ide->tf->atastat = READY_STAT;
if (ide->sc->packet_status == PHASE_ERROR) if (ide->sc->packet_status == PHASE_ERROR)
ide->tf->atastat |= ERR_STAT; ide->tf->atastat |= ERR_STAT;
@@ -1082,19 +1086,30 @@ ide_atapi_callback(ide_t *ide)
break; break;
case PHASE_DATA_IN: case PHASE_DATA_IN:
case PHASE_DATA_OUT: case PHASE_DATA_OUT:
ret = 0;
ide->tf->atastat = READY_STAT | DRQ_STAT | (ide->tf->atastat & ERR_STAT); ide->tf->atastat = READY_STAT | DRQ_STAT | (ide->tf->atastat & ERR_STAT);
ide->tf->phase = !(ide->sc->packet_status & 0x01) << 1; ide->tf->phase = !(ide->sc->packet_status & 0x01) << 1;
ide_irq_raise(ide); ide_irq_raise(ide);
break; break;
case PHASE_DATA_IN_DMA: case PHASE_DATA_IN_DMA:
case PHASE_DATA_OUT_DMA:
out = (ide->sc->packet_status & 0x01);
if (!IDE_ATAPI_IS_EARLY && !ide_boards[ide->board]->force_ata3 && if (!IDE_ATAPI_IS_EARLY && !ide_boards[ide->board]->force_ata3 &&
(bm != NULL) && bm->dma) { (bm != NULL) && bm->dma) {
ret = bm->dma(ide->sc->temp_buffer, ide->sc->packet_len, out, bm->priv); if (ide->sc->block_len == 0)
ret = bm->dma(ide->sc->temp_buffer, ide->sc->packet_len, 0, bm->priv);
else {
ret = bm->dma(ide->sc->temp_buffer + ide->sc->buffer_pos -
ide->sc->block_len, ide->sc->block_len,
0, bm->priv);
if (ret == 1) {
if (ide->sc->sector_len == 0)
ret = 3;
else if (ide->read != NULL)
ide->read(ide->sc);
} }
/* Else, DMA command without a bus master, ret = 0 (default). */ }
} else
ret = 0;
switch (ret) { switch (ret) {
default: default:
@@ -1103,18 +1118,69 @@ ide_atapi_callback(ide_t *ide)
if (ide->bus_master_error) if (ide->bus_master_error)
ide->bus_master_error(ide->sc); ide->bus_master_error(ide->sc);
break; break;
case 1: case 2:
if (out && ide->phase_data_out) ide_atapi_command_bus(ide);
(void) ide->phase_data_out(ide->sc); break;
else if (!out && ide->command_stop) case 3:
ide->command_stop(ide->sc); /* Reached EOT - terminate the command as there's nothing
more to transfer. */
ide->sc->packet_status = PHASE_COMPLETE;
ide->sc->callback = 0.0;
if ((ide->sc->packet_status == PHASE_COMPLETE) && (ide->sc->callback == 0.0)) if (ide->command_stop != NULL)
ide->command_stop(ide->sc);
fallthrough;
case 1:
if ((ide->sc->packet_status == PHASE_COMPLETE) &&
(ide->sc->callback == 0.0))
ide_atapi_callback(ide); ide_atapi_callback(ide);
break; break;
}
break;
case PHASE_DATA_OUT_DMA:
if (!IDE_ATAPI_IS_EARLY && !ide_boards[ide->board]->force_ata3 &&
(bm != NULL) && bm->dma) {
if (ide->sc->block_len == 0)
ret = bm->dma(ide->sc->temp_buffer, ide->sc->packet_len, 1, bm->priv);
else {
ret = bm->dma(ide->sc->temp_buffer + ide->sc->buffer_pos,
ide->sc->block_len, 1, bm->priv);
if (ret & 1) {
if (ide->write != NULL)
ide->write(ide->sc);
if ((ret == 1) && (ide->sc->sector_len == 0))
ret = 3;
}
}
} else
ret = 0;
switch (ret) {
default:
break;
case 0:
if (ide->bus_master_error)
ide->bus_master_error(ide->sc);
break;
case 2: case 2:
ide_atapi_command_bus(ide); ide_atapi_command_bus(ide);
break; break;
case 3:
/* Reached EOT - terminate the command as there's nothing
more to transfer. */
ide->sc->packet_status = PHASE_COMPLETE;
ide->sc->callback = 0.0;
if (ide->phase_data_out != NULL)
(void) ide->phase_data_out(ide->sc);
fallthrough;
case 1:
if ((ide->sc->packet_status == PHASE_COMPLETE) &&
(ide->sc->callback == 0.0))
ide_atapi_callback(ide);
break;
} }
break; break;
} }
@@ -1134,22 +1200,37 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
ide_log("%i bytes %s, command done\n", ide->tf->pos, out ? "written" : "read"); ide_log("%i bytes %s, command done\n", ide->tf->pos, out ? "written" : "read");
ide->tf->pos = dev->request_pos = 0; ide->tf->pos = dev->request_pos = 0;
if (out && ide->phase_data_out)
if (dev->block_len != 0) {
if (out && (ide->write != NULL))
ide->write(dev);
else if (!out && (dev->sector_len != 0) && (ide->read != NULL))
ide->read(dev);
}
if ((dev->block_len == 0) || (dev->sector_len == 0)) {
if (out && (ide->phase_data_out != NULL))
ide->phase_data_out(dev); ide->phase_data_out(dev);
else if (!out && ide->command_stop) else if (!out && (ide->command_stop != NULL))
ide->command_stop(dev); ide->command_stop(dev);
if ((ide->sc->packet_status == PHASE_COMPLETE) && (ide->sc->callback == 0.0)) if ((ide->sc->packet_status == PHASE_COMPLETE) && (ide->sc->callback == 0.0))
ide_atapi_callback(ide); ide_atapi_callback(ide);
}
} else { } else {
ide_log("%i bytes %s, %i bytes are still left\n", ide->tf->pos, ide_log("%i bytes %s, %i bytes are still left\n", ide->tf->pos,
out ? "written" : "read", dev->packet_len - ide->tf->pos); out ? "written" : "read", dev->packet_len - ide->tf->pos);
/* If less than (packet length) bytes are remaining, update packet length /*
accordingly. */ If less than (packet length) bytes are remaining, update packet length
accordingly.
*/
if ((dev->packet_len - ide->tf->pos) < (dev->max_transfer_len)) { if ((dev->packet_len - ide->tf->pos) < (dev->max_transfer_len)) {
dev->max_transfer_len = dev->packet_len - ide->tf->pos; dev->max_transfer_len = dev->packet_len - ide->tf->pos;
/* Also update the request length so the host knows how many bytes to transfer. */ /*
Also update the request length so the host knows how many bytes to
transfer.
*/
ide->tf->request_length = dev->max_transfer_len; ide->tf->request_length = dev->max_transfer_len;
} }
ide_log("CD-ROM %i: Packet length %i, request length %i\n", dev->id, dev->packet_len, ide_log("CD-ROM %i: Packet length %i, request length %i\n", dev->id, dev->packet_len,
@@ -1157,10 +1238,20 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out)
dev->packet_status = PHASE_DATA_IN | out; dev->packet_status = PHASE_DATA_IN | out;
if (dev->block_len != 0) {
if (out && (ide->write != NULL))
ide->write(dev);
else if (!out && (dev->sector_len != 0) && (ide->read != NULL))
ide->read(dev);
}
ide->tf->atastat = BSY_STAT; ide->tf->atastat = BSY_STAT;
ide->tf->phase = 1; ide->tf->phase = 1;
if ((dev->block_len == 0) || (dev->sector_len == 0)) {
ide_atapi_callback(ide); ide_atapi_callback(ide);
ide_set_callback(ide, 0.0); ide_set_callback(ide, 0.0);
}
dev->request_pos = 0; dev->request_pos = 0;
} }
@@ -1179,19 +1270,26 @@ ide_atapi_packet_read(ide_t *ide)
bufferw = (uint16_t *) dev->temp_buffer; bufferw = (uint16_t *) dev->temp_buffer;
/* Make sure we return a 0 and don't attempt to read from the buffer if /*
Make sure we return a 0 and don't attempt to read from the buffer if
we're transferring bytes beyond it, which can happen when issuing media we're transferring bytes beyond it, which can happen when issuing media
access commands with an allocated length below minimum request length access commands with an allocated length below minimum request length
(which is 1 sector = 2048 bytes). */ (which is 1 sector = 2048 bytes).
*/
ret = (ide->tf->pos < dev->packet_len) ? bufferw[ide->tf->pos >> 1] : 0; ret = (ide->tf->pos < dev->packet_len) ? bufferw[ide->tf->pos >> 1] : 0;
ide->tf->pos += 2; ide->tf->pos += 2;
dev->request_pos += 2; dev->request_pos += 2;
if ((dev->request_pos >= dev->max_transfer_len) || (ide->tf->pos >= dev->packet_len)) { if ((dev->request_pos >= dev->max_transfer_len) ||
(ide->tf->pos >= dev->packet_len)) {
/* Time for a DRQ. */ /* Time for a DRQ. */
ide_atapi_pio_request(ide, 0); ide_atapi_pio_request(ide, 0);
} } else if ((dev->block_len != 0) &&
(dev->sector_len != 0) &&
((dev->request_pos % dev->block_len) == 0) &&
(ide->read != NULL))
ide->read(dev);
} }
return ret; return ret;
@@ -1221,10 +1319,14 @@ ide_atapi_packet_write(ide_t *ide, const uint16_t val)
dev->request_pos += 2; dev->request_pos += 2;
if (dev->packet_status == PHASE_DATA_OUT) { if (dev->packet_status == PHASE_DATA_OUT) {
if ((dev->request_pos >= dev->max_transfer_len) || (ide->tf->pos >= dev->packet_len)) { if ((dev->request_pos >= dev->max_transfer_len) ||
(ide->tf->pos >= dev->packet_len)) {
/* Time for a DRQ. */ /* Time for a DRQ. */
ide_atapi_pio_request(ide, 1); ide_atapi_pio_request(ide, 1);
} } else if ((dev->block_len != 0) &&
((dev->request_pos % dev->block_len) == 0) &&
(ide->write != NULL))
ide->write(dev);
} else if (dev->packet_status == PHASE_IDLE) { } else if (dev->packet_status == PHASE_IDLE) {
if (ide->tf->pos >= 12) { if (ide->tf->pos >= 12) {
ide->tf->pos = 0; ide->tf->pos = 0;
@@ -1287,7 +1389,7 @@ ide_writew(uint16_t addr, uint16_t val, void *priv)
ide = ide_drives[ch]; ide = ide_drives[ch];
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) #if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
ide_log("ide_writew(%04X, %04X, %08X)\n", addr, val, priv); ide_log("[%04X:%08X] ide_writew(%04X, %04X, %08X)\n", CS, cpu_state.pc, addr, val, priv);
#endif #endif
addr &= 0x7; addr &= 0x7;
@@ -1321,7 +1423,7 @@ ide_writel(uint16_t addr, uint32_t val, void *priv)
ide = ide_drives[ch]; ide = ide_drives[ch];
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) #if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
ide_log("ide_writel(%04X, %08X, %08X)\n", addr, val, priv); ide_log("[%04X:%08X] ide_writel(%04X, %08X, %08X)\n", CS, cpu_state.pc, addr, val, priv);
#endif #endif
addr &= 0x7; addr &= 0x7;
@@ -1371,9 +1473,9 @@ ide_write_devctl(UNUSED(uint16_t addr), uint8_t val, void *priv)
ide = ide_drives[ch]; ide = ide_drives[ch];
ide_other = ide_drives[ch ^ 1]; ide_other = ide_drives[ch ^ 1];
ide_log("ide_write_devctl(%04X, %02X, %08X)\n", addr, val, priv); ide_log("[%04X:%08X] ide_write_devctl(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv);
if ((ide->type == IDE_NONE) && (ide_other->type == IDE_NONE)) if ((addr & 0x0001) || ((ide->type == IDE_NONE) && (ide_other->type == IDE_NONE)))
return; return;
dev->diag = 0; dev->diag = 0;
@@ -1481,7 +1583,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
ide = ide_drives[ch]; ide = ide_drives[ch];
ide_other = ide_drives[ch ^ 1]; ide_other = ide_drives[ch ^ 1];
ide_log("ide_writeb(%04X, %02X, %08X)\n", addr, val, priv); ide_log("[%04X:%08X] ide_writeb(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv);
addr &= 0x7; addr &= 0x7;
@@ -1831,7 +1933,7 @@ ide_read_data(ide_t *ide)
const uint16_t *idebufferw = ide->buffer; const uint16_t *idebufferw = ide->buffer;
uint16_t ret = 0x0000; uint16_t ret = 0x0000;
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) #if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 3)
ide_log("ide_read_data(): ch = %i, board = %i, type = %i\n", ide->channel, ide_log("ide_read_data(): ch = %i, board = %i, type = %i\n", ide->channel,
ide->board, ide->type); ide->board, ide->type);
#endif #endif
@@ -2010,7 +2112,7 @@ ide_readb(uint16_t addr, void *priv)
break; break;
} }
ide_log("ide_readb(%04X, %08X) = %02X\n", addr, priv, ret); ide_log("[%04X:%08X] ide_readb(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret);
return ret; return ret;
} }
@@ -2022,12 +2124,14 @@ ide_read_alt_status(UNUSED(const uint16_t addr), void *priv)
const int ch = dev->cur_dev; const int ch = dev->cur_dev;
ide_t * ide = ide_drives[ch]; ide_t * ide = ide_drives[ch];
uint8_t ret = 0xff;
/* Per the Seagate ATA-3 specification: /* Per the Seagate ATA-3 specification:
Reading the alternate status does *NOT* clear the IRQ. */ Reading the alternate status does *NOT* clear the IRQ. */
const uint8_t ret = ide_status(ide, ide_drives[ch ^ 1], ch); if (!(addr & 0x0001))
ret = ide_status(ide, ide_drives[ch ^ 1], ch);
ide_log("ide_read_alt_status(%04X, %08X) = %02X\n", addr, priv, ret); ide_log("[%04X:%08X] ide_read_alt_status(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret);
return ret; return ret;
} }
@@ -2053,7 +2157,7 @@ ide_readw(uint16_t addr, void *priv)
} }
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) #if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
ide_log("ide_readw(%04X, %08X) = %04X\n", addr, priv, ret); ide_log("[%04X:%08X] ide_readw(%04X, %08X) = %04X\n", CS, cpu_state.pc, addr, priv, ret);
#endif #endif
return ret; return ret;
} }
@@ -2084,7 +2188,7 @@ ide_readl(uint16_t addr, void *priv)
} }
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) #if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
ide_log("ide_readl(%04X, %08X) = %04X\n", addr, priv, ret); ide_log("[%04X:%08X] ide_readl(%04X, %08X) = %04X\n", CS, cpu_state.pc, addr, priv, ret);
#endif #endif
return ret; return ret;
} }
@@ -2270,7 +2374,7 @@ ide_callback(void *priv)
ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
ide_set_callback(ide, 6.0 * IDE_TIME); ide_set_callback(ide, 6.0 * IDE_TIME);
return; return;
} else if (ret == 1) { } else if (ret & 1) {
/* DMA successful */ /* DMA successful */
ide_log("IDE %i: DMA read successful\n", ide->channel); ide_log("IDE %i: DMA read successful\n", ide->channel);
@@ -2379,7 +2483,7 @@ ide_callback(void *priv)
ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
ide_set_callback(ide, 6.0 * IDE_TIME); ide_set_callback(ide, 6.0 * IDE_TIME);
return; return;
} else if (ret == 1) { } else if (ret & 1) {
/* DMA successful */ /* DMA successful */
ret = hdd_image_write(ide->hdd_num, ide_get_sector(ide), ret = hdd_image_write(ide->hdd_num, ide_get_sector(ide),
ide->sector_pos, ide->sector_buffer); ide->sector_pos, ide->sector_buffer);
@@ -2637,7 +2741,7 @@ ide_handlers(uint8_t board, int set)
} }
if (ide_boards[board]->base[1]) { if (ide_boards[board]->base[1]) {
io_handler(set, ide_boards[board]->base[1], 1, io_handler(set, ide_boards[board]->base[1], 2,
ide_read_alt_status, NULL, NULL, ide_read_alt_status, NULL, NULL,
ide_write_devctl, NULL, NULL, ide_write_devctl, NULL, NULL,
ide_boards[board]); ide_boards[board]);

View File

@@ -375,7 +375,7 @@ sff_bus_master_dma(uint8_t *data, int transfer_length, int out, void *priv)
} else if (dev->eot) { } else if (dev->eot) {
sff_log("Regular EOT\n"); sff_log("Regular EOT\n");
dev->status &= ~3; dev->status &= ~3;
return 1; /* We have regularly reached EOT - clear status and break. */ return 3; /* We have regularly reached EOT - clear status and break. */
} else { } else {
/* We have more to transfer and there are blocks left, get next block. */ /* We have more to transfer and there are blocks left, get next block. */
sff_bus_master_next_addr(dev); sff_bus_master_next_addr(dev);

View File

@@ -28,8 +28,9 @@
#define CD_STATUS_PLAYING 5 #define CD_STATUS_PLAYING 5
#define CD_STATUS_STOPPED 6 #define CD_STATUS_STOPPED 6
#define CD_STATUS_PLAYING_COMPLETED 7 #define CD_STATUS_PLAYING_COMPLETED 7
#define CD_STATUS_HAS_AUDIO 4 #define CD_STATUS_HOLD 8
#define CD_STATUS_MASK 7 #define CD_STATUS_HAS_AUDIO 0xc
#define CD_STATUS_MASK 0xf
/* Medium changed flag. */ /* Medium changed flag. */
#define CD_STATUS_TRANSITION 0x40 #define CD_STATUS_TRANSITION 0x40
@@ -50,8 +51,6 @@
#define CD_IMAGE_HISTORY 10 #define CD_IMAGE_HISTORY 10
#define BUF_SIZE 32768
#define CDROM_IMAGE 200 #define CDROM_IMAGE 200
/* This is so that if/when this is changed to something else, /* This is so that if/when this is changed to something else,
@@ -63,6 +62,8 @@
#define RAW_SECTOR_SIZE 2352 #define RAW_SECTOR_SIZE 2352
#define COOKED_SECTOR_SIZE 2048 #define COOKED_SECTOR_SIZE 2048
#define CD_BUF_SIZE (16 * RAW_SECTOR_SIZE)
#define DATA_TRACK 0x14 #define DATA_TRACK 0x14
#define AUDIO_TRACK 0x10 #define AUDIO_TRACK 0x10
@@ -105,9 +106,9 @@ enum {
#define CDV EMU_VERSION_EX #define CDV EMU_VERSION_EX
static const struct cdrom_drive_types_s { static const struct cdrom_drive_types_s {
const char vendor[9]; const char * vendor;
const char model[17]; const char * model;
const char revision[5]; const char * revision;
const char * internal_name; const char * internal_name;
const int bus_type; const int bus_type;
/* SCSI standard for SCSI (or both) devices, early for IDE. */ /* SCSI standard for SCSI (or both) devices, early for IDE. */
@@ -298,9 +299,7 @@ typedef struct cdrom {
void * priv; void * priv;
char image_path[1024]; char image_path[1024];
char prev_image_path[1024]; char prev_image_path[1280];
char * image_history[CD_IMAGE_HISTORY];
uint32_t sound_on; uint32_t sound_on;
uint32_t cdrom_capacity; uint32_t cdrom_capacity;
@@ -310,18 +309,21 @@ typedef struct cdrom {
uint32_t type; uint32_t type;
uint32_t sector_size; uint32_t sector_size;
int cd_buflen;
int audio_op;
int audio_muted_soft;
int sony_msf;
int real_speed;
int is_early;
int is_nec;
uint32_t inv_field; uint32_t inv_field;
int32_t cached_sector;
int32_t cd_buflen;
int32_t sony_msf;
int32_t real_speed;
int32_t is_early;
int32_t is_nec;
int32_t is_bcd;
int32_t cdrom_sector_size;
const cdrom_ops_t *ops; const cdrom_ops_t *ops;
char * image_history[CD_IMAGE_HISTORY];
void * local; void * local;
void * log; void * log;
@@ -330,22 +332,26 @@ typedef struct cdrom {
uint32_t (*get_volume)(void *p, int channel); uint32_t (*get_volume)(void *p, int channel);
uint32_t (*get_channel)(void *p, int channel); uint32_t (*get_channel)(void *p, int channel);
int16_t cd_buffer[BUF_SIZE]; int16_t cd_buffer[CD_BUF_SIZE];
uint8_t subch_buffer[96]; uint8_t subch_buffer[96];
int cdrom_sector_size;
/* Needs some extra breathing space in case of overflows. */ /* Needs some extra breathing space in case of overflows. */
uint8_t raw_buffer[4096]; uint8_t raw_buffer[2][4096];
uint8_t extra_buffer[296]; uint8_t extra_buffer[296];
int32_t is_chinon;
int32_t is_pioneer;
int32_t is_plextor;
int32_t is_sony;
int32_t is_toshiba;
int32_t c2_first;
int32_t cur_buf;
} cdrom_t; } cdrom_t;
extern cdrom_t cdrom[CDROM_NUM]; extern cdrom_t cdrom[CDROM_NUM];
/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong:
there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start
of the audio while audio still plays. With an absolute conversion, the counter is fine. */
#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) #define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
static __inline int static __inline int
@@ -366,8 +372,6 @@ extern char *cdrom_get_revision(const int type);
extern int cdrom_get_scsi_std(const int type); extern int cdrom_get_scsi_std(const int type);
extern int cdrom_is_early(const int type); extern int cdrom_is_early(const int type);
extern int cdrom_is_generic(const int type); extern int cdrom_is_generic(const int type);
extern int cdrom_has_date(const int type);
extern int cdrom_is_sony(const int type);
extern int cdrom_is_caddy(const int type); extern int cdrom_is_caddy(const int type);
extern int cdrom_get_speed(const int type); extern int cdrom_get_speed(const int type);
extern int cdrom_get_inquiry_len(const int type); extern int cdrom_get_inquiry_len(const int type);
@@ -384,6 +388,7 @@ extern void cdrom_set_type(const int model, const int type);
extern int cdrom_get_type(const int model); extern int cdrom_get_type(const int model);
extern int cdrom_lba_to_msf_accurate(const int lba); extern int cdrom_lba_to_msf_accurate(const int lba);
extern void cdrom_interleave_subch(uint8_t *d, const uint8_t *s);
extern double cdrom_seek_time(const cdrom_t *dev); extern double cdrom_seek_time(const cdrom_t *dev);
extern void cdrom_stop(cdrom_t *dev); extern void cdrom_stop(cdrom_t *dev);
extern void cdrom_seek(cdrom_t *dev, const uint32_t pos, const uint8_t vendor_type); extern void cdrom_seek(cdrom_t *dev, const uint32_t pos, const uint8_t vendor_type);
@@ -396,7 +401,7 @@ extern uint8_t cdrom_audio_track_search(cdrom_t *dev, const uint32_t pos
extern uint8_t cdrom_audio_track_search_pioneer(cdrom_t *dev, const uint32_t pos, const uint8_t playbit); extern uint8_t cdrom_audio_track_search_pioneer(cdrom_t *dev, const uint32_t pos, const uint8_t playbit);
extern uint8_t cdrom_audio_play_pioneer(cdrom_t *dev, const uint32_t pos); extern uint8_t cdrom_audio_play_pioneer(cdrom_t *dev, const uint32_t pos);
extern uint8_t cdrom_audio_play_toshiba(cdrom_t *dev, const uint32_t pos, const int type); extern uint8_t cdrom_audio_play_toshiba(cdrom_t *dev, const uint32_t pos, const int type);
extern uint8_t cdrom_audio_scan(cdrom_t *dev, const uint32_t pos, const int type); extern uint8_t cdrom_audio_scan(cdrom_t *dev, const uint32_t pos);
extern void cdrom_audio_pause_resume(cdrom_t *dev, const uint8_t resume); extern void cdrom_audio_pause_resume(cdrom_t *dev, const uint8_t resume);
extern uint8_t cdrom_get_current_status(const cdrom_t *dev); extern uint8_t cdrom_get_current_status(const cdrom_t *dev);
@@ -424,6 +429,7 @@ extern int cdrom_read_dvd_structure(const cdrom_t *dev, const uint8_
uint8_t *buffer, uint32_t *info); uint8_t *buffer, uint32_t *info);
extern void cdrom_read_disc_information(const cdrom_t *dev, uint8_t *buffer); extern void cdrom_read_disc_information(const cdrom_t *dev, uint8_t *buffer);
extern int cdrom_read_track_information(cdrom_t *dev, const uint8_t *cdb, uint8_t *buffer); extern int cdrom_read_track_information(cdrom_t *dev, const uint8_t *cdb, uint8_t *buffer);
extern uint8_t cdrom_get_current_mode(cdrom_t *dev);
extern void cdrom_set_empty(cdrom_t *dev); extern void cdrom_set_empty(cdrom_t *dev);
extern void cdrom_update_status(cdrom_t *dev); extern void cdrom_update_status(cdrom_t *dev);
extern int cdrom_load(cdrom_t *dev, const char *fn, const int skip_insert); extern int cdrom_load(cdrom_t *dev, const char *fn, const int skip_insert);

View File

@@ -118,16 +118,6 @@ enum {
#define BIOS_INTERLEAVED_INVERT 8 #define BIOS_INTERLEAVED_INVERT 8
#define BIOS_HIGH_BIT_INVERT 16 #define BIOS_HIGH_BIT_INVERT 16
#define device_common_config_t \
const char *name; \
const char *description; \
int type; \
const char *default_string; \
int default_int; \
const char *file_filter; \
const device_config_spinner_t spinner; \
const device_config_selection_t selection[32]
typedef struct device_config_selection_t { typedef struct device_config_selection_t {
const char *description; const char *description;
int value; int value;
@@ -139,10 +129,6 @@ typedef struct device_config_spinner_t {
int16_t step; int16_t step;
} device_config_spinner_t; } device_config_spinner_t;
typedef struct _device_dep_config_ {
device_common_config_t;
} device_dep_config_t;
typedef struct device_config_bios_t { typedef struct device_config_bios_t {
const char *name; const char *name;
const char *internal_name; const char *internal_name;
@@ -153,14 +139,17 @@ typedef struct device_config_bios_t {
void *dev1; void *dev1;
void *dev2; void *dev2;
const char *files[9]; const char *files[9];
/* Configuration options that depend on the device variant.
To prevent excessive nesting, there is no CONFIG_BIOS
option a dep_config struct */
const device_dep_config_t *dep_config;
} device_config_bios_t; } device_config_bios_t;
typedef struct _device_config_ { typedef struct _device_config_ {
device_common_config_t; const char *name;
const char *description;
int type;
const char *default_string;
int default_int;
const char *file_filter;
const device_config_spinner_t spinner;
const device_config_selection_t selection[32];
const device_config_bios_t bios[32]; const device_config_bios_t bios[32];
} device_config_t; } device_config_t;

View File

@@ -133,6 +133,8 @@ typedef struct ide_s {
uint8_t (*phase_data_out)(scsi_common_t *sc); uint8_t (*phase_data_out)(scsi_common_t *sc);
void (*command_stop)(scsi_common_t *sc); void (*command_stop)(scsi_common_t *sc);
void (*bus_master_error)(scsi_common_t *sc); void (*bus_master_error)(scsi_common_t *sc);
void (*read)(scsi_common_t *sc);
void (*write)(scsi_common_t *sc);
#else #else
void * get_max; void * get_max;
void * get_timings; void * get_timings;

View File

@@ -139,50 +139,58 @@ typedef struct hdd_zone_t {
/* Define the virtual Hard Disk. */ /* Define the virtual Hard Disk. */
typedef struct hard_disk_t { typedef struct hard_disk_t {
uint8_t id; uint8_t id;
union {
uint8_t channel; /* Needed for Settings to reduce the number of if's */
uint8_t mfm_channel; /* Should rename and/or unionize */ union {
/* Needed for Settings to reduce the number of if's */
uint8_t channel;
uint8_t mfm_channel;
uint8_t esdi_channel; uint8_t esdi_channel;
uint8_t xta_channel; uint8_t xta_channel;
uint8_t ide_channel; uint8_t ide_channel;
uint8_t scsi_id; uint8_t scsi_id;
}; };
uint8_t bus_type; uint8_t bus_type;
uint8_t bus_mode; /* Bit 0 = PIO suported; uint8_t bus_mode; /* Bit 0 = PIO suported;
Bit 1 = DMA supportd. */ Bit 1 = DMA supportd. */
uint8_t wp; /* Disk has been mounted READ-ONLY */ uint8_t wp; /* Disk has been mounted
READ-ONLY */
uint8_t pad; uint8_t pad;
uint8_t pad0; uint8_t pad0;
void * priv; void * priv;
char fn[1024]; /* Name of current image file */ char fn[1024]; /* Name of current image file */
char vhd_parent[1041]; /* Differential VHD parent file */ /* Differential VHD parent file */
char vhd_parent[1280];
uint32_t seek_pos; uint32_t seek_pos;
uint32_t seek_len; uint32_t seek_len;
uint32_t base; uint32_t base;
uint32_t spt; uint32_t spt; /* Physical geometry parameters */
uint32_t hpc; /* Physical geometry parameters */ uint32_t hpc;
uint32_t tracks; uint32_t tracks;
const char *model; uint32_t speed_preset;
hdd_zone_t zones[HDD_MAX_ZONES];
uint32_t num_zones; uint32_t num_zones;
hdd_cache_t cache;
uint32_t phy_cyl; uint32_t phy_cyl;
uint32_t phy_heads; uint32_t phy_heads;
uint32_t rpm; uint32_t rpm;
uint8_t max_multiple_block;
uint32_t cur_cylinder; uint32_t cur_cylinder;
uint32_t cur_track; uint32_t cur_track;
uint32_t cur_addr; uint32_t cur_addr;
uint32_t speed_preset;
uint32_t vhd_blocksize; uint32_t vhd_blocksize;
uint8_t max_multiple_block;
uint8_t pad1[3];
const char * model;
hdd_zone_t zones[HDD_MAX_ZONES];
hdd_cache_t cache;
double avg_rotation_lat_usec; double avg_rotation_lat_usec;
double full_stroke_usec; double full_stroke_usec;
double head_switch_usec; double head_switch_usec;

View File

@@ -51,9 +51,9 @@ static const mo_type_t mo_types[KNOWN_MO_TYPES] = {
}; };
typedef struct mo_drive_type_t { typedef struct mo_drive_type_t {
const char vendor[9]; const char *vendor;
const char model[16]; const char *model;
const char revision[5]; const char *revision;
int8_t supported_media[KNOWN_MO_TYPES]; int8_t supported_media[KNOWN_MO_TYPES];
} mo_drive_type_t; } mo_drive_type_t;
@@ -161,6 +161,7 @@ typedef struct mo_t {
uint32_t sector_pos; uint32_t sector_pos;
uint32_t sector_len; uint32_t sector_len;
uint32_t packet_len; uint32_t packet_len;
uint32_t block_len;
double callback; double callback;

View File

@@ -54,18 +54,24 @@ typedef struct scsi_cdrom_t {
int do_page_save; int do_page_save;
int unit_attention; int unit_attention;
int request_pos; int request_pos;
int old_len; int wait;
int media_status; int buffer_pos;
uint32_t sector_pos; uint32_t sector_pos;
uint32_t sector_len; uint32_t sector_len;
uint32_t packet_len; uint32_t packet_len;
uint32_t block_len;
double callback; double callback;
int is_sony; uint8_t (*ven_cmd)(void *sc, const uint8_t *cdb, int32_t *BufLen);
int use_cdb_9;
int use_cdb_9;
int was_cached;
int toc_cached;
int media_access;
uint8_t vendor_type;
uint8_t ven_cmd_is_data[256]; uint8_t ven_cmd_is_data[256];
mode_sense_pages_t ms_drive_status_pages_saved; mode_sense_pages_t ms_drive_status_pages_saved;
@@ -74,8 +80,6 @@ typedef struct scsi_cdrom_t {
mode_sense_pages_t ms_pages_default; mode_sense_pages_t ms_pages_default;
mode_sense_pages_t ms_pages_changeable; mode_sense_pages_t ms_pages_changeable;
uint8_t (*ven_cmd)(void *sc, const uint8_t *cdb, int32_t *BufLen);
} scsi_cdrom_t; } scsi_cdrom_t;
#endif #endif

View File

@@ -110,39 +110,40 @@
#define GPCMD_MECHANISM_STATUS 0xbd #define GPCMD_MECHANISM_STATUS 0xbd
#define GPCMD_READ_CD 0xbe #define GPCMD_READ_CD 0xbe
#define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to 86Box. */ #define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to 86Box. */
#define GPCMD_EJECT_CHINON 0xc0 /* Chinon Vendor Unique command */
#define GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA 0xc0 /* Toshiba Vendor Unique command */ #define GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA 0xc0 /* Toshiba Vendor Unique command */
#define GPCMD_SET_ADDRESS_FORMAT_SONY 0xc0 /* Sony Vendor Unique command */ #define GPCMD_EJECT_CHINON 0xc0 /* Chinon Vendor Unique command */
#define GPCMD_MAGAZINE_EJECT_PIONEER 0xc0 /* Pioneer Vendor Unique command */ #define GPCMD_MAGAZINE_EJECT_PIONEER 0xc0 /* Pioneer Vendor Unique command */
#define GPCMD_SET_ADDRESS_FORMAT_SONY 0xc0 /* Sony Vendor Unique command */
#define GPCMD_PLAY_AUDIO_TOSHIBA 0xc1 /* Toshiba Vendor Unique command */ #define GPCMD_PLAY_AUDIO_TOSHIBA 0xc1 /* Toshiba Vendor Unique command */
#define GPCMD_READ_TOC_SONY 0xc1 /* Sony Vendor Unique command */
#define GPCMD_READ_TOC_PIONEER 0xc1 /* Pioneer Vendor Unique command */ #define GPCMD_READ_TOC_PIONEER 0xc1 /* Pioneer Vendor Unique command */
#define GPCMD_READ_TOC_SONY 0xc1 /* Sony Vendor Unique command */
#define GPCMD_PAUSE_RESUME_ALT 0xc2 #define GPCMD_PAUSE_RESUME_ALT 0xc2
#define GPCMD_READ_SUBCHANNEL_MATSUSHITA 0xc2 /* Matsushita Vendor Unique command */ #define GPCMD_READ_SUBCHANNEL_MATSUSHITA 0xc2 /* Matsushita Vendor Unique command */
#define GPCMD_READ_SUBCODEQ_PIONEER 0xc2 /* Pioneer Vendor Unique command */
#define GPCMD_READ_SUBCHANNEL_SONY 0xc2 /* Sony Vendor Unique command */ #define GPCMD_READ_SUBCHANNEL_SONY 0xc2 /* Sony Vendor Unique command */
#define GPCMD_STILL_TOSHIBA 0xc2 /* Toshiba Vendor Unique command */ #define GPCMD_STILL_TOSHIBA 0xc2 /* Toshiba Vendor Unique command */
#define GPCMD_READ_SUBCODEQ_PIONEER 0xc2 /* Pioneer Vendor Unique command */
#define GPCMD_READ_TOC_MATSUSHITA 0xc3 /* Matsushita Vendor Unique command */ #define GPCMD_READ_TOC_MATSUSHITA 0xc3 /* Matsushita Vendor Unique command */
#define GPCMD_READ_HEADER_SONY 0xc3 /* Sony Vendor Unique command */ #define GPCMD_READ_HEADER_SONY 0xc3 /* Sony Vendor Unique command */
#define GPCMD_SET_STOP_TIME_TOSHIBA 0xc3 /* Toshiba Vendor Unique command */ #define GPCMD_SET_STOP_TIME_TOSHIBA 0xc3 /* Toshiba Vendor Unique command */
#define GPCMD_READ_HEADER_MATSUSHITA 0xc4 /* Matsushita Vendor Unique command */
#define GPCMD_PLAYBACK_STATUS_SONY 0xc4 /* Sony Vendor Unique command */
#define GPCMD_CADDY_EJECT_TOSHIBA 0xc4 /* Toshiba Vendor Unique command */ #define GPCMD_CADDY_EJECT_TOSHIBA 0xc4 /* Toshiba Vendor Unique command */
#define GPCMD_PLAYBACK_STATUS_SONY 0xc4 /* Sony Vendor Unique command */
#define GPCMD_READ_HEADER_MATSUSHITA 0xc4 /* Matsushita Vendor Unique command */
#define GPCMD_PAUSE_SONY 0xc5 /* Sony Vendor Unique command */ #define GPCMD_PAUSE_SONY 0xc5 /* Sony Vendor Unique command */
#define GPCMD_PLAY_AUDIO_MATSUSHITA 0xc5 /* Matsushita Vendor Unique command */ #define GPCMD_PLAY_AUDIO_MATSUSHITA 0xc5 /* Matsushita Vendor Unique command */
#define GPCMD_UNKNOWN_SCSI2_NEC 0xc5 /* NEC Vendor Unique Command */ #define GPCMD_UNKNOWN_SCSI2_NEC 0xc5 /* NEC Vendor Unique Command */
#define GPCMD_STOP_CHINON 0xc6 /* Chinon Vendor Unique command */
#define GPCMD_PLAY_TRACK_SONY 0xc6 /* Sony Vendor Unique command */ #define GPCMD_PLAY_TRACK_SONY 0xc6 /* Sony Vendor Unique command */
#define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA 0xc6 /* Toshiba Vendor Unique command */ #define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA 0xc6 /* Toshiba Vendor Unique command */
#define GPCMD_STOP_CHINON 0xc6 /* Chinon Vendor Unique command */
#define GPCMD_PLAY_AUDIO_MSF_MATSUSHITA 0xc7 /* Matsushita Vendor Unique command*/ #define GPCMD_PLAY_AUDIO_MSF_MATSUSHITA 0xc7 /* Matsushita Vendor Unique command*/
#define GPCMD_PLAY_MSF_SONY 0xc7 /* Sony Vendor Unique command*/ #define GPCMD_PLAY_MSF_SONY 0xc7 /* Sony Vendor Unique command*/
#define GPCMD_READ_DISC_INFORMATION_TOSHIBA 0xc7 /* Toshiba Vendor Unique command */ #define GPCMD_READ_DISC_INFORMATION_TOSHIBA 0xc7 /* Toshiba Vendor Unique command */
#define GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA 0xc8 /* Matsushita Vendor Unique command */
#define GPCMD_PLAY_AUDIO_SONY 0xc8 /* Sony Vendor Unique command */
#define GPCMD_AUDIO_TRACK_SEARCH_PIONEER 0xc8 /* Pioneer Vendor Unique command */ #define GPCMD_AUDIO_TRACK_SEARCH_PIONEER 0xc8 /* Pioneer Vendor Unique command */
#define GPCMD_PLAY_AUDIO_SONY 0xc8 /* Sony Vendor Unique command */
#define GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA 0xc8 /* Matsushita Vendor Unique command */
#define GPCMD_READ_CDROM_MODE_TOSHIBA 0xc8 /* Toshiba Vendor Unique command */
#define GPCMD_PLAY_AUDIO_PIONEER 0xc9 /* Pioneer Vendor Unique command */
#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA 0xc9 /* Matsushita Vendor Unique command */ #define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA 0xc9 /* Matsushita Vendor Unique command */
#define GPCMD_PLAYBACK_CONTROL_SONY 0xc9 /* Sony Vendor Unique command */ #define GPCMD_PLAYBACK_CONTROL_SONY 0xc9 /* Sony Vendor Unique command */
#define GPCMD_PLAY_AUDIO_PIONEER 0xc9 /* Pioneer Vendor Unique command */
#define GPCMD_PAUSE_PIONEER 0xca /* Pioneer Vendor Unique command */ #define GPCMD_PAUSE_PIONEER 0xca /* Pioneer Vendor Unique command */
#define GPCMD_PAUSE_RESUME_MATSUSHITA 0xcb /* Matsushita Vendor Unique command */ #define GPCMD_PAUSE_RESUME_MATSUSHITA 0xcb /* Matsushita Vendor Unique command */
#define GPCMD_STOP_PIONEER 0xcb /* Pioneer Vendor Unique command */ #define GPCMD_STOP_PIONEER 0xcb /* Pioneer Vendor Unique command */
@@ -151,8 +152,8 @@
#define GPCMD_READ_CD_MSF_OLD 0xd5 /* Should be equivalent to 0xb9 */ #define GPCMD_READ_CD_MSF_OLD 0xd5 /* Should be equivalent to 0xb9 */
#define GPCMD_AUDIO_TRACK_SEARCH_NEC 0xd8 /* NEC Vendor Unique command */ #define GPCMD_AUDIO_TRACK_SEARCH_NEC 0xd8 /* NEC Vendor Unique command */
#define GPCMD_PLAY_AUDIO_NEC 0xd9 /* NEC Vendor Unique command */ #define GPCMD_PLAY_AUDIO_NEC 0xd9 /* NEC Vendor Unique command */
#define GPCMD_STILL_NEC 0xda /* NEC Vendor Unique command */
#define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */ #define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */
#define GPCMD_STILL_NEC 0xda /* NEC Vendor Unique command */
#define GPCMD_SET_STOP_TIME_NEC 0xdb /* NEC Vendor Unique command */ #define GPCMD_SET_STOP_TIME_NEC 0xdb /* NEC Vendor Unique command */
#define GPCMD_CADDY_EJECT_NEC 0xdc /* NEC Vendor Unique command */ #define GPCMD_CADDY_EJECT_NEC 0xdc /* NEC Vendor Unique command */
#define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC 0xdd /* NEC Vendor Unique command */ #define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC 0xdd /* NEC Vendor Unique command */
@@ -409,12 +410,13 @@ typedef struct scsi_common_s {
int do_page_save; int do_page_save;
int unit_attention; int unit_attention;
int request_pos; int request_pos;
int old_len; int wait;
int media_status; int buffer_pos;
uint32_t sector_pos; uint32_t sector_pos;
uint32_t sector_len; uint32_t sector_len;
uint32_t packet_len; uint32_t packet_len;
uint32_t block_len;
double callback; double callback;

View File

@@ -53,6 +53,7 @@ typedef struct scsi_disk_t {
uint32_t sector_pos; uint32_t sector_pos;
uint32_t sector_len; uint32_t sector_len;
uint32_t packet_len; uint32_t packet_len;
uint32_t block_len;
double callback; double callback;

View File

@@ -108,6 +108,7 @@ typedef struct zip_t {
uint32_t sector_pos; uint32_t sector_pos;
uint32_t sector_len; uint32_t sector_len;
uint32_t packet_len; uint32_t packet_len;
uint32_t block_len;
double callback; double callback;

View File

@@ -65,6 +65,7 @@ extern void win_keyboard_handle(uint32_t scancode, int up, int e0, int e1);
#include "ui_qt_mainwindow.h" #include "ui_qt_mainwindow.h"
bool windows_is_light_theme() { bool windows_is_light_theme() {
return 0;
// based on https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application // based on https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application
// The value is expected to be a REG_DWORD, which is a signed 32-bit little-endian // The value is expected to be a REG_DWORD, which is a signed 32-bit little-endian

View File

@@ -91,6 +91,20 @@ ioctl_open_handle(ioctl_t *ioctl)
ioctl_log(ioctl->log, "handle=%p, error=%x\n", ioctl_log(ioctl->log, "handle=%p, error=%x\n",
ioctl->handle, (unsigned int) GetLastError()); ioctl->handle, (unsigned int) GetLastError());
if (ioctl->handle != INVALID_HANDLE_VALUE) {
CDROM_SET_SPEED set_speed = { 0 };
set_speed.RequestType = CdromSetSpeed;
set_speed.ReadSpeed = 0xffff;
set_speed.WriteSpeed = 0xffff;
set_speed.RotationControl = CdromDefaultRotation;
(void) DeviceIoControl(ioctl->handle, IOCTL_CDROM_SET_SPEED,
&set_speed, sizeof(set_speed),
NULL, 0,
0, NULL);
}
return (ioctl->handle != INVALID_HANDLE_VALUE); return (ioctl->handle != INVALID_HANDLE_VALUE);
} }

File diff suppressed because it is too large Load Diff

View File

@@ -274,15 +274,17 @@ sound_cd_thread(UNUSED(void *param))
temp_buffer[0] = temp_buffer[1] = 0; temp_buffer[0] = temp_buffer[1] = 0;
for (uint8_t i = 0; i < CDROM_NUM; i++) { for (uint8_t i = 0; i < CDROM_NUM; i++) {
if ((cdrom[i].bus_type == CDROM_BUS_DISABLED) || (cdrom[i].cd_status == CD_STATUS_EMPTY)) /* Just in case the thread is in a loop when it gets terminated. */
continue; if (!cdaudioon)
const uint32_t lba = cdrom[i].seek_pos; break;
const int r = cdrom_audio_callback(&(cdrom[i]), cd_buffer[i], CD_BUFLEN * 2);
if (!cdrom[i].sound_on || !r)
continue;
const int pre = cdrom_is_pre(&(cdrom[i]), lba);
if ((cdrom[i].bus_type == CDROM_BUS_DISABLED) ||
(cdrom[i].cd_status != CD_STATUS_PLAYING))
continue;
const int ret = cdrom_audio_callback(&(cdrom[i]), cd_buffer[i],
CD_BUFLEN * 2);
if (ret) {
if (cdrom[i].get_volume) { if (cdrom[i].get_volume) {
audio_vol_l = cd_audio_volume_lut[cdrom[i].get_volume(cdrom[i].priv, 0)]; audio_vol_l = cd_audio_volume_lut[cdrom[i].get_volume(cdrom[i].priv, 0)];
audio_vol_r = cd_audio_volume_lut[cdrom[i].get_volume(cdrom[i].priv, 1)]; audio_vol_r = cd_audio_volume_lut[cdrom[i].get_volume(cdrom[i].priv, 1)];
@@ -299,46 +301,49 @@ sound_cd_thread(UNUSED(void *param))
channel_select[1] = 2; channel_select[1] = 2;
} }
// uint16_t *cddab = (uint16_t *) cdrom[i].raw_buffer;
for (int c = 0; c < CD_BUFLEN * 2; c += 2) { for (int c = 0; c < CD_BUFLEN * 2; c += 2) {
/* Apply ATAPI channel select */ /* Apply ATAPI channel select */
cd_buffer_temp[0] = cd_buffer_temp[1] = 0.0; cd_buffer_temp[0] = cd_buffer_temp[1] = 0.0;
if ((audio_vol_l != 0.0) && (channel_select[0] != 0)) { if ((audio_vol_l != 0.0) && (channel_select[0] != 0)) {
if (channel_select[0] & 1) if (channel_select[0] & 1)
cd_buffer_temp[0] += ((double) cd_buffer[i][c]); /* Channel 0 => Port 0 */ /* Channel 0 => Port 0 */
cd_buffer_temp[0] += ((double) cd_buffer[i][c]);
if (channel_select[0] & 2) if (channel_select[0] & 2)
cd_buffer_temp[0] += ((double) cd_buffer[i][c + 1]); /* Channel 1 => Port 0 */ /* Channel 1 => Port 0 */
cd_buffer_temp[0] += ((double) cd_buffer[i][c + 1]);
cd_buffer_temp[0] *= audio_vol_l; /* Multiply Port 0 by Port 0 volume */ /* Multiply Port 0 by Port 0 volume */
cd_buffer_temp[0] *= audio_vol_l;
if (pre)
cd_buffer_temp[0] = deemph_iir(0, cd_buffer_temp[0]); /* De-emphasize if necessary */
} }
if ((audio_vol_r != 0.0) && (channel_select[1] != 0)) { if ((audio_vol_r != 0.0) && (channel_select[1] != 0)) {
if (channel_select[1] & 1) if (channel_select[1] & 1)
cd_buffer_temp[1] += ((double) cd_buffer[i][c]); /* Channel 0 => Port 1 */ /* Channel 0 => Port 1 */
cd_buffer_temp[1] += ((double) cd_buffer[i][c]);
if (channel_select[1] & 2) if (channel_select[1] & 2)
cd_buffer_temp[1] += ((double) cd_buffer[i][c + 1]); /* Channel 1 => Port 1 */ /* Channel 1 => Port 1 */
cd_buffer_temp[1] += ((double) cd_buffer[i][c + 1]);
cd_buffer_temp[1] *= audio_vol_r; /* Multiply Port 1 by Port 1 volume */ /* Multiply Port 1 by Port 1 volume */
cd_buffer_temp[1] *= audio_vol_r;
if (pre)
cd_buffer_temp[1] = deemph_iir(1, cd_buffer_temp[1]); /* De-emphasize if necessary */
} }
/* Apply sound card CD volume and filters */ /* Apply sound card CD volume and filters */
if (filter_cd_audio != NULL) { if (filter_cd_audio != NULL) {
filter_cd_audio(0, &(cd_buffer_temp[0]), filter_cd_audio_p); filter_cd_audio(0, &(cd_buffer_temp[0]),
filter_cd_audio(1, &(cd_buffer_temp[1]), filter_cd_audio_p); filter_cd_audio_p);
filter_cd_audio(1, &(cd_buffer_temp[1]),
filter_cd_audio_p);
} }
if (sound_is_float) { if (sound_is_float) {
cd_out_buffer[c] += (float) (cd_buffer_temp[0] / 32768.0); cd_out_buffer[c] += (float) (cd_buffer_temp[0] / 32768.0);
cd_out_buffer[c + 1] += (float) (cd_buffer_temp[1] / 32768.0); cd_out_buffer[c + 1] += (float) (cd_buffer_temp[1] / 32768.0);
} else { } else {
temp_buffer[0] += (int) trunc(cd_buffer_temp[0]); temp_buffer[0] = (int) trunc(cd_buffer_temp[0]);
temp_buffer[1] += (int) trunc(cd_buffer_temp[1]); temp_buffer[1] = (int) trunc(cd_buffer_temp[1]);
if (temp_buffer[0] > 32767) if (temp_buffer[0] > 32767)
temp_buffer[0] = 32767; temp_buffer[0] = 32767;
@@ -349,8 +354,9 @@ sound_cd_thread(UNUSED(void *param))
if (temp_buffer[1] < -32768) if (temp_buffer[1] < -32768)
temp_buffer[1] = -32768; temp_buffer[1] = -32768;
cd_out_buffer_int16[c] = (int16_t) temp_buffer[0]; cd_out_buffer_int16[c] += (int16_t) temp_buffer[0];
cd_out_buffer_int16[c + 1] = (int16_t) temp_buffer[1]; cd_out_buffer_int16[c + 1] += (int16_t) temp_buffer[1];
}
} }
} }
} }