More IDE/ATAPI DMA changes.
This commit is contained in:
@@ -9,7 +9,7 @@
|
|||||||
* Implementation of the IDE emulation for hard disks and ATAPI
|
* Implementation of the IDE emulation for hard disks and ATAPI
|
||||||
* CD-ROM devices.
|
* CD-ROM devices.
|
||||||
*
|
*
|
||||||
* Version: @(#)hdc_ide.c 1.0.57 2018/10/31
|
* Version: @(#)hdc_ide.c 1.0.58 2018/10/31
|
||||||
*
|
*
|
||||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||||
* Miran Grca, <mgrca8@gmail.com>
|
* Miran Grca, <mgrca8@gmail.com>
|
||||||
@@ -122,8 +122,7 @@ static ide_board_t *ide_boards[4];
|
|||||||
static int pio_override = 0;
|
static int pio_override = 0;
|
||||||
|
|
||||||
ide_t *ide_drives[IDE_NUM];
|
ide_t *ide_drives[IDE_NUM];
|
||||||
int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length, void *priv);
|
int (*ide_bus_master_dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv);
|
||||||
int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length, void *priv);
|
|
||||||
void (*ide_bus_master_set_irq)(int channel, void *priv);
|
void (*ide_bus_master_set_irq)(int channel, void *priv);
|
||||||
void *ide_bus_master_priv[2];
|
void *ide_bus_master_priv[2];
|
||||||
int ide_inited = 0;
|
int ide_inited = 0;
|
||||||
@@ -953,44 +952,10 @@ ide_atapi_command_bus(ide_t *ide)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
ide_atapi_dma(ide_t *ide, int out)
|
|
||||||
{
|
|
||||||
int ret = 1;
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
if (out && ide && ide_bus_master_write) {
|
|
||||||
ret = ide_bus_master_write(ide->board,
|
|
||||||
ide->sc->temp_buffer, ide->sc->packet_len,
|
|
||||||
ide_bus_master_priv[ide->board]);
|
|
||||||
} else if (!out && ide && ide_bus_master_read) {
|
|
||||||
ret = ide_bus_master_read(ide->board,
|
|
||||||
ide->sc->temp_buffer, ide->sc->packet_len,
|
|
||||||
ide_bus_master_priv[ide->board]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == 0) {
|
|
||||||
if (ide->bus_master_error)
|
|
||||||
ide->bus_master_error(ide->sc);
|
|
||||||
} else if (ret == 1) {
|
|
||||||
if (out && ide->phase_data_out)
|
|
||||||
ret = ide->phase_data_out(ide->sc);
|
|
||||||
else if (!out && ide->command_stop)
|
|
||||||
ide->command_stop(ide->sc);
|
|
||||||
|
|
||||||
if ((ide->sc->packet_status == PHASE_COMPLETE) && !ide->sc->callback)
|
|
||||||
ide_atapi_callback(ide);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ide_atapi_callback(ide_t *ide)
|
ide_atapi_callback(ide_t *ide)
|
||||||
{
|
{
|
||||||
int ret;
|
int out, ret = 0;
|
||||||
|
|
||||||
switch(ide->sc->packet_status) {
|
switch(ide->sc->packet_status) {
|
||||||
case PHASE_IDLE:
|
case PHASE_IDLE:
|
||||||
@@ -1020,12 +985,26 @@ ide_atapi_callback(ide_t *ide)
|
|||||||
return;
|
return;
|
||||||
case PHASE_DATA_IN_DMA:
|
case PHASE_DATA_IN_DMA:
|
||||||
case PHASE_DATA_OUT_DMA:
|
case PHASE_DATA_OUT_DMA:
|
||||||
ret = ide_atapi_dma(ide, ide->sc->packet_status & 0x01);
|
out = (ide->sc->packet_status & 0x01);
|
||||||
|
|
||||||
if (ret == 2)
|
ret = ide_bus_master_dma(ide->board,
|
||||||
|
ide->sc->temp_buffer, ide->sc->packet_len,
|
||||||
|
out, ide_bus_master_priv[ide->board]);
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
if (ide->bus_master_error)
|
||||||
|
ide->bus_master_error(ide->sc);
|
||||||
|
} else if (ret == 1) {
|
||||||
|
if (out && ide->phase_data_out)
|
||||||
|
ret = ide->phase_data_out(ide->sc);
|
||||||
|
else if (!out && ide->command_stop)
|
||||||
|
ide->command_stop(ide->sc);
|
||||||
|
|
||||||
|
if ((ide->sc->packet_status == PHASE_COMPLETE) && !ide->sc->callback)
|
||||||
|
ide_atapi_callback(ide);
|
||||||
|
} else if (ret == 2)
|
||||||
ide_atapi_command_bus(ide);
|
ide_atapi_command_bus(ide);
|
||||||
else if ((ide->sc->packet_status == PHASE_COMPLETE) && !ide->sc->callback)
|
|
||||||
ide_atapi_callback(ide);
|
|
||||||
return;
|
return;
|
||||||
case PHASE_ERROR:
|
case PHASE_ERROR:
|
||||||
ide->sc->status = READY_STAT | ERR_STAT;
|
ide->sc->status = READY_STAT | ERR_STAT;
|
||||||
@@ -2116,11 +2095,11 @@ ide_callback(void *priv)
|
|||||||
|
|
||||||
ide->pos=0;
|
ide->pos=0;
|
||||||
|
|
||||||
if (ide_bus_master_read) {
|
if (ide_bus_master_dma) {
|
||||||
/* We should not abort - we should simply wait for the host to start DMA. */
|
/* We should not abort - we should simply wait for the host to start DMA. */
|
||||||
ret = ide_bus_master_read(ide->board,
|
ret = ide_bus_master_dma(ide->board,
|
||||||
ide->sector_buffer, ide->sector_pos * 512,
|
ide->sector_buffer, ide->sector_pos * 512,
|
||||||
ide_bus_master_priv[ide->board]);
|
0, ide_bus_master_priv[ide->board]);
|
||||||
if (ret == 2) {
|
if (ret == 2) {
|
||||||
/* Bus master DMA disabled, simply wait for the host to enable DMA. */
|
/* Bus master DMA disabled, simply wait for the host to enable DMA. */
|
||||||
ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
|
ide->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
|
||||||
@@ -2210,15 +2189,15 @@ ide_callback(void *priv)
|
|||||||
goto id_not_found;
|
goto id_not_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ide_bus_master_write) {
|
if (ide_bus_master_dma) {
|
||||||
if (ide->secount)
|
if (ide->secount)
|
||||||
ide->sector_pos = ide->secount;
|
ide->sector_pos = ide->secount;
|
||||||
else
|
else
|
||||||
ide->sector_pos = 256;
|
ide->sector_pos = 256;
|
||||||
|
|
||||||
ret = ide_bus_master_write(ide->board,
|
ret = ide_bus_master_dma(ide->board,
|
||||||
ide->sector_buffer, ide->sector_pos * 512,
|
ide->sector_buffer, ide->sector_pos * 512,
|
||||||
ide_bus_master_priv[ide->board]);
|
1, ide_bus_master_priv[ide->board]);
|
||||||
|
|
||||||
if (ret == 2) {
|
if (ret == 2) {
|
||||||
/* Bus master DMA disabled, simply wait for the host to enable DMA. */
|
/* Bus master DMA disabled, simply wait for the host to enable DMA. */
|
||||||
@@ -2590,7 +2569,7 @@ ide_qua_close(void *priv)
|
|||||||
static void
|
static void
|
||||||
ide_clear_bus_master(void)
|
ide_clear_bus_master(void)
|
||||||
{
|
{
|
||||||
ide_bus_master_read = ide_bus_master_write = NULL;
|
ide_bus_master_dma = NULL;
|
||||||
ide_bus_master_set_irq = NULL;
|
ide_bus_master_set_irq = NULL;
|
||||||
ide_bus_master_priv[0] = ide_bus_master_priv[1] = NULL;
|
ide_bus_master_priv[0] = ide_bus_master_priv[1] = NULL;
|
||||||
}
|
}
|
||||||
@@ -2630,13 +2609,11 @@ ide_xtide_close(void)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_set_bus_master(int (*read)(int channel, uint8_t *data, int transfer_length, void *priv),
|
ide_set_bus_master(int (*dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv),
|
||||||
int (*write)(int channel, uint8_t *data, int transfer_length, void *priv),
|
|
||||||
void (*set_irq)(int channel, void *priv),
|
void (*set_irq)(int channel, void *priv),
|
||||||
void *priv0, void *priv1)
|
void *priv0, void *priv1)
|
||||||
{
|
{
|
||||||
ide_bus_master_read = read;
|
ide_bus_master_dma = dma;
|
||||||
ide_bus_master_write = write;
|
|
||||||
ide_bus_master_set_irq = set_irq;
|
ide_bus_master_set_irq = set_irq;
|
||||||
ide_bus_master_priv[0] = priv0;
|
ide_bus_master_priv[0] = priv0;
|
||||||
ide_bus_master_priv[1] = priv1;
|
ide_bus_master_priv[1] = priv1;
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
* Implementation of the IDE emulation for hard disks and ATAPI
|
* Implementation of the IDE emulation for hard disks and ATAPI
|
||||||
* CD-ROM devices.
|
* CD-ROM devices.
|
||||||
*
|
*
|
||||||
* Version: @(#)hdd_ide.h 1.0.14 2018/10/31
|
* Version: @(#)hdd_ide.h 1.0.15 2018/10/31
|
||||||
*
|
*
|
||||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||||
* Miran Grca, <mgrca8@gmail.com>
|
* Miran Grca, <mgrca8@gmail.com>
|
||||||
@@ -120,8 +120,7 @@ extern uint8_t ide_readb(uint16_t addr, void *priv);
|
|||||||
extern uint8_t ide_read_alt_status(uint16_t addr, void *priv);
|
extern uint8_t ide_read_alt_status(uint16_t addr, void *priv);
|
||||||
extern uint16_t ide_readw(uint16_t addr, void *priv);
|
extern uint16_t ide_readw(uint16_t addr, void *priv);
|
||||||
|
|
||||||
extern void ide_set_bus_master(int (*read)(int channel, uint8_t *data, int transfer_length, void *priv),
|
extern void ide_set_bus_master(int (*dmna)(int channel, uint8_t *data, int transfer_length, int out, void *priv),
|
||||||
int (*write)(int channel, uint8_t *data, int transfer_length, void *priv),
|
|
||||||
void (*set_irq)(int channel, void *priv),
|
void (*set_irq)(int channel, void *priv),
|
||||||
void *priv0, void *priv1);
|
void *priv0, void *priv1);
|
||||||
|
|
||||||
@@ -142,8 +141,7 @@ extern void secondary_ide_check(void);
|
|||||||
extern void ide_padstr(char *str, const char *src, int len);
|
extern void ide_padstr(char *str, const char *src, int len);
|
||||||
extern void ide_padstr8(uint8_t *buf, int buf_size, const char *src);
|
extern void ide_padstr8(uint8_t *buf, int buf_size, const char *src);
|
||||||
|
|
||||||
extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length, void *priv);
|
extern int (*ide_bus_master_dma)(int channel, uint8_t *data, int transfer_length, int out, void *priv);
|
||||||
extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length, void *priv);
|
|
||||||
extern void (*ide_bus_master_set_irq)(int channel, void *priv);
|
extern void (*ide_bus_master_set_irq)(int channel, void *priv);
|
||||||
extern void *ide_bus_master_priv[2];
|
extern void *ide_bus_master_priv[2];
|
||||||
|
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
* Implementation of the Iomega ZIP drive with SCSI(-like)
|
* Implementation of the Iomega ZIP drive with SCSI(-like)
|
||||||
* commands, for both ATAPI and SCSI usage.
|
* commands, for both ATAPI and SCSI usage.
|
||||||
*
|
*
|
||||||
* Version: @(#)zip.h 1.0.8 2018/10/28
|
* Version: @(#)zip.h 1.0.9 2018/10/31
|
||||||
*
|
*
|
||||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||||
*
|
*
|
||||||
@@ -104,11 +104,6 @@ extern uint8_t scsi_zip_drives[16];
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length, void *priv);
|
|
||||||
extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length, void *priv);
|
|
||||||
extern void (*ide_bus_master_set_irq)(int channel, void *priv);
|
|
||||||
extern void *ide_bus_master_priv[2];
|
|
||||||
|
|
||||||
extern void zip_disk_close(zip_t *dev);
|
extern void zip_disk_close(zip_t *dev);
|
||||||
extern void zip_disk_reload(zip_t *dev);
|
extern void zip_disk_reload(zip_t *dev);
|
||||||
extern void zip_insert(zip_t *dev);
|
extern void zip_insert(zip_t *dev);
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
* word 0 - base address
|
* word 0 - base address
|
||||||
* word 1 - bits 1-15 = byte count, bit 31 = end of transfer
|
* word 1 - bits 1-15 = byte count, bit 31 = end of transfer
|
||||||
*
|
*
|
||||||
* Version: @(#)intel_piix.c 1.0.21 2018/10/28
|
* Version: @(#)intel_piix.c 1.0.22 2018/10/31
|
||||||
*
|
*
|
||||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||||
* Miran Grca, <mgrca8@gmail.com>
|
* Miran Grca, <mgrca8@gmail.com>
|
||||||
@@ -609,7 +609,7 @@ piix_bus_master_readl(uint16_t port, void *priv)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
piix_bus_master_dma_op(int channel, uint8_t *data, int transfer_length, int out, void *priv)
|
piix_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, void *priv)
|
||||||
{
|
{
|
||||||
piix_busmaster_t *dev = (piix_busmaster_t *) priv;
|
piix_busmaster_t *dev = (piix_busmaster_t *) priv;
|
||||||
#ifdef ENABLE_PIIX_LOG
|
#ifdef ENABLE_PIIX_LOG
|
||||||
@@ -619,29 +619,29 @@ piix_bus_master_dma_op(int channel, uint8_t *data, int transfer_length, int out,
|
|||||||
int force_end = 0, buffer_pos = 0;
|
int force_end = 0, buffer_pos = 0;
|
||||||
|
|
||||||
#ifdef ENABLE_PIIX_LOG
|
#ifdef ENABLE_PIIX_LOG
|
||||||
sop = out ? "Writ" : "Read";
|
sop = out ? "Read" : "Writ";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!(dev->status & 1))
|
if (!(dev->status & 1))
|
||||||
return 2; /*DMA disabled*/
|
return 2; /*DMA disabled*/
|
||||||
|
|
||||||
piix_log("PIIX Bus master %s: %i bytes\n", out ? "read" : "write", transfer_length);
|
piix_log("PIIX Bus master %s: %i bytes\n", out ? "write" : "read", transfer_length);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (dev->count <= transfer_length) {
|
if (dev->count <= transfer_length) {
|
||||||
piix_log("%sing %i bytes to %08X\n", sop, dev->count, dev->addr);
|
piix_log("%sing %i bytes to %08X\n", sop, dev->count, dev->addr);
|
||||||
if (out)
|
if (out)
|
||||||
DMAPageWrite(dev->addr, (uint8_t *)(data + buffer_pos), dev->count);
|
|
||||||
else
|
|
||||||
DMAPageRead(dev->addr, (uint8_t *)(data + buffer_pos), dev->count);
|
DMAPageRead(dev->addr, (uint8_t *)(data + buffer_pos), dev->count);
|
||||||
|
else
|
||||||
|
DMAPageWrite(dev->addr, (uint8_t *)(data + buffer_pos), dev->count);
|
||||||
transfer_length -= dev->count;
|
transfer_length -= dev->count;
|
||||||
buffer_pos += dev->count;
|
buffer_pos += dev->count;
|
||||||
} else {
|
} else {
|
||||||
piix_log("%sing %i bytes to %08X\n", sop, transfer_length, dev->addr);
|
piix_log("%sing %i bytes to %08X\n", sop, transfer_length, dev->addr);
|
||||||
if (out)
|
if (out)
|
||||||
DMAPageWrite(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length);
|
|
||||||
else
|
|
||||||
DMAPageRead(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length);
|
DMAPageRead(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length);
|
||||||
|
else
|
||||||
|
DMAPageWrite(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length);
|
||||||
/* Increase addr and decrease count so that resumed transfers do not mess up. */
|
/* Increase addr and decrease count so that resumed transfers do not mess up. */
|
||||||
dev->addr += transfer_length;
|
dev->addr += transfer_length;
|
||||||
dev->count -= transfer_length;
|
dev->count -= transfer_length;
|
||||||
@@ -677,20 +677,6 @@ piix_bus_master_dma_op(int channel, uint8_t *data, int transfer_length, int out,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length, void *priv)
|
|
||||||
{
|
|
||||||
return piix_bus_master_dma_op(channel, data, transfer_length, 1, priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
piix_bus_master_dma_write(int channel, uint8_t *data, int transfer_length, void *priv)
|
|
||||||
{
|
|
||||||
return piix_bus_master_dma_op(channel, data, transfer_length, 0, priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
piix_bus_master_set_irq(int channel, void *priv)
|
piix_bus_master_set_irq(int channel, void *priv)
|
||||||
{
|
{
|
||||||
@@ -864,8 +850,7 @@ static void
|
|||||||
piix->type = info->local;
|
piix->type = info->local;
|
||||||
piix_reset_hard(piix);
|
piix_reset_hard(piix);
|
||||||
|
|
||||||
ide_set_bus_master(piix_bus_master_dma_read, piix_bus_master_dma_write,
|
ide_set_bus_master(piix_bus_master_dma, piix_bus_master_set_irq,
|
||||||
piix_bus_master_set_irq,
|
|
||||||
&piix->bm[0], &piix->bm[1]);
|
&piix->bm[0], &piix->bm[1]);
|
||||||
|
|
||||||
port_92_reset();
|
port_92_reset();
|
||||||
|
Reference in New Issue
Block a user