From adf9c28e618f8f081a62a41f4cf364eeab42dc5a Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 8 Feb 2017 18:42:20 +0100 Subject: [PATCH] ATAPI DMA now tells the bus master the correct length to transfer; ATAPI DMA now transfers all blocks at once. --- src/cdrom.c | 23 +++++++++++++++++++++-- src/cdrom.h | 2 ++ src/ide.c | 10 ++++++---- src/piix.c | 8 ++++++-- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/cdrom.c b/src/cdrom.c index a71ba8b60..7e16287a3 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -973,6 +973,10 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al { SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = 0; } + else + { + cdrom[id].init_length = 0; + } cdrom_command_complete(id); } else @@ -985,6 +989,10 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al { SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = alloc_len; } + else + { + cdrom[id].init_length = alloc_len; + } cdrom_command_read_dma(id); } else @@ -1963,7 +1971,8 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } max_len = cdrom[id].sector_len; - if (cdrom_drives[id].bus_type) + // if (cdrom_drives[id].bus_type) + if (cdrom_current_mode(id) == 2) { cdrom[id].requested_blocks = max_len; } @@ -2732,6 +2741,14 @@ int cdrom_block_check(uint8_t id) int alloc_length = 0; int ret = 0; + if (!cdrom_drives[id].bus_type) + { + cdrom_log("CD-ROM %i: Lowering IDE IRQ\n", id); + ide_irq_lower(&(ide_drives[cdrom_drives[id].ide_channel])); + } + + cdrom[id].status = BUSY_STAT; + /* If this is a media access command, and we hit the end of the block but not the entire length, read the next block. */ if (cdrom_is_media_access(id)) @@ -2787,6 +2804,7 @@ void cdrom_callback(uint8_t id) /* Callback for non-Read CD commands */ int ret = 0; int old_pos = 0; +#if 0 if (!cdrom_drives[id].bus_type) { cdrom_log("CD-ROM %i: Lowering IDE IRQ\n", id); @@ -2794,6 +2812,7 @@ void cdrom_callback(uint8_t id) /* Callback for non-Read CD commands */ } cdrom[id].status = BUSY_STAT; +#endif if (cdrom[id].total_read >= cdrom[id].packet_len) { @@ -2963,7 +2982,7 @@ int cdrom_write_to_ide_dma(uint8_t channel) if (ide_bus_master_read) { - if (ide_bus_master_read(channel >> 1, cdbufferb, cdrom[id].request_length)) + if (ide_bus_master_read(channel >> 1, cdbufferb, cdrom[id].init_length)) { cdrom_data_phase_error(id); cdrom_phase_callback(id); diff --git a/src/cdrom.h b/src/cdrom.h index 08dc4ffc2..78731c317 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -112,6 +112,8 @@ typedef struct __attribute__((__packed__)) int old_len; int block_descriptor_len; + + int init_length; } cdrom_t; extern cdrom_t cdrom[CDROM_NUM]; diff --git a/src/ide.c b/src/ide.c index eb98e78d2..be9c920e0 100644 --- a/src/ide.c +++ b/src/ide.c @@ -206,10 +206,11 @@ void ide_irq_raise(IDE *ide) { if ((ide->board > 3) || ide->irqstat) { + // ide_log("Not raising IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); return; } - // ide_log("Raising IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); + ide_log("Raising IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); if (!(ide->fdisk&2)) { @@ -234,10 +235,11 @@ void ide_irq_lower(IDE *ide) { if ((ide->board > 3) || !(ide->irqstat)) { + // ide_log("Not lowering IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); return; } - // ide_log("Lowering IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); + ide_log("Lowering IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); picintc(1 << ide_irq[ide->board]); ide->irqstat=0; @@ -1393,7 +1395,7 @@ uint8_t readide(int ide_board, uint16_t addr) case 0x1F0: /* Data */ // temp = ide_read_data(ide_board, 1); tempw = readidew(ide_board); - // pclog("Read IDEW %04X\n", tempw); + // ide_log("Read IDEW %04X\n", tempw); temp = tempw & 0xff; break; @@ -1549,7 +1551,7 @@ uint16_t readidew(int ide_board) uint32_t readidel(int ide_board) { uint16_t temp; - // pclog("Read IDEl %i\n", ide_board); + // ide_log("Read IDEl %i\n", ide_board); temp = readidew(ide_board); return temp | (readidew(ide_board) << 16); } diff --git a/src/piix.c b/src/piix.c index d0672e63d..b6351e4a6 100644 --- a/src/piix.c +++ b/src/piix.c @@ -409,7 +409,7 @@ int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length) while (transferred < transfer_length) { if (piix_busmaster[channel].count < (transfer_length - transferred) && piix_busmaster[channel].eot) - fatal("DMA on channel %i - Read count less than transfer_length! Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); + fatal("DMA on channel %i - Read count less than %04X! Addr %08X Count %04X EOT %i\n", channel, transfer_length, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr + transfer_length - 1); @@ -451,14 +451,18 @@ int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length) int piix_bus_master_dma_write(int channel, uint8_t *data, int transfer_length) { int transferred = 0; + + // pclog("piix_bus_master_dma_write(%08X, %08X, %08X) on %08X data\n", channel, data, transfer_length, piix_busmaster[channel].count); if (!(piix_busmaster[channel].status & 1)) return 1; /*DMA disabled*/ + pclog("DMA not disabled\n"); + while (transferred < transfer_length) { if (piix_busmaster[channel].count < (transfer_length - transferred) && piix_busmaster[channel].eot) - fatal("DMA on channel %i - Write count less than transfer_length! Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); + fatal("DMA on channel %i - Write count less than %04X! Addr %08X Count %04X EOT %i\n", channel, transfer_length, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); if (piix_busmaster[channel].count < (transfer_length - transferred)) {