ATAPI DMA is now scatter gather-aware.
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
25
src/cdrom.c
25
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;
|
||||
}
|
||||
}
|
||||
|
58
src/piix.c
58
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))
|
||||
{
|
||||
|
Reference in New Issue
Block a user