diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index f922dea9a..ba8d1f9c3 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -829,7 +829,7 @@ static void ioctl_validate_toc(uint8_t id) cdrom_ioctl[id].tocvalid=1; } -UCHAR buf[65536]; +UCHAR buf[262144]; static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len) { diff --git a/src/cdrom.c b/src/cdrom.c index 7e16287a3..b0acbe5c0 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -2973,6 +2973,12 @@ int cdrom_write_to_ide_dma(uint8_t channel) uint8_t id = atapi_cdrom_drives[channel]; + int transfer_length = 0; + int cdbufferb_pos = 0; + + int bus_master_len = 0; + int ret = 0; + if (id > CDROM_NUM) { return 0; @@ -2980,16 +2986,33 @@ int cdrom_write_to_ide_dma(uint8_t channel) cdbufferb = (uint8_t *) cdrom[id].buffer; + transfer_length = cdrom[id].init_length; + if (ide_bus_master_read) { - if (ide_bus_master_read(channel >> 1, cdbufferb, cdrom[id].init_length)) + while(transfer_length > 0) { + // pclog("CD-ROM %i: ATAPI DMA on position: %08X...\n", id, cdbufferb + cdbufferb_pos); + bus_master_len = piix_bus_master_get_count(channel >> 1); + ret = piix_bus_master_dma_read_ex(channel >> 1, cdbufferb + cdbufferb_pos); + if (ret != 0) + { + break; + } + transfer_length -= bus_master_len; + cdbufferb_pos += bus_master_len; + } + + if (ret > 0) + { + // pclog("CD-ROM %i: ATAPI DMA error\n", id); cdrom_data_phase_error(id); cdrom_phase_callback(id); return 0; } else { + // pclog("CD-ROM %i: ATAPI DMA successful\n", id); return 1; } } diff --git a/src/piix.c b/src/piix.c index b6351e4a6..4f81ffd2b 100644 --- a/src/piix.c +++ b/src/piix.c @@ -399,6 +399,46 @@ uint8_t piix_bus_master_read(uint16_t port, void *priv) return 0xff; } +int piix_bus_master_get_count(int channel) +{ + return piix_busmaster[channel].count; +} + +int piix_bus_master_get_eot(int channel) +{ + return piix_busmaster[channel].eot; +} + +int piix_bus_master_dma_read_ex(int channel, uint8_t *data) +{ + int transferred = 0; + + if (!(piix_busmaster[channel].status & 1)) + return 1; /*DMA disabled*/ + + mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr + piix_busmaster[channel].count - 1); + + // pclog("Transferring special - %i bytes\n", piix_busmaster[channel].count); + memcpy(&ram[piix_busmaster[channel].addr], data, piix_busmaster[channel].count); + transferred += piix_busmaster[channel].count; + piix_busmaster[channel].addr += piix_busmaster[channel].count; + piix_busmaster[channel].addr %= (mem_size * 1024); + piix_busmaster[channel].count = 0; + + if (piix_busmaster[channel].eot) /*End of transfer?*/ + { + // pclog("DMA on channel %i - transfer over\n", channel); + piix_busmaster[channel].status &= ~1; + return -1; + } + else + { + // pclog("DMA on channel %i - transfer continuing\n", channel); + piix_bus_master_next_addr(channel); + } + return 0; +} + int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length) { int transferred = 0; @@ -408,8 +448,10 @@ 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 %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)) && piix_busmaster[channel].eot && (transfer_length == 512)) + { + 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); @@ -431,14 +473,14 @@ int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length) transferred += (transfer_length - transferred); } -// pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); + // pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); if (!piix_busmaster[channel].count) { -// pclog("DMA on channel %i - block over\n", channel); + // pclog("DMA on channel %i - block over\n", channel); if (piix_busmaster[channel].eot) /*End of transfer?*/ { -// pclog("DMA on channel %i - transfer over\n", channel); + // pclog("DMA on channel %i - transfer over\n", channel); piix_busmaster[channel].status &= ~1; } else @@ -461,8 +503,10 @@ int piix_bus_master_dma_write(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 - 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)) && piix_busmaster[channel].eot && (transfer_length == 512)) + { + 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)) {