Merge remote-tracking branch 'origin/master' into version/4.1

This commit is contained in:
OBattler
2023-11-04 07:15:11 +01:00
16 changed files with 1683 additions and 648 deletions

View File

@@ -1656,9 +1656,6 @@ acpi_reset(void *priv)
dev->regs.gpi_val |= 0x00000004;
}
/* Power on always generates a resume event. */
dev->regs.pmsts |= 0x8100;
acpi_rtc_status = 0;
acpi_update_irq(dev);
@@ -1765,6 +1762,9 @@ acpi_init(const device_t *info)
acpi_reset(dev);
/* Power on always generates a resume event. */
dev->regs.pmsts |= 0x8100;
acpi_enabled = 1;
return dev;
}

View File

@@ -1172,8 +1172,6 @@ piix_read(int func, int addr, void *priv)
if ((func <= dev->max_func) || ((func == 1) && (dev->max_func == 0))) {
fregs = (uint8_t *) dev->regs[func];
ret = fregs[addr];
if ((func == 2) && (addr == 0xff))
ret |= 0xef;
piix_log("PIIX function %i read: %02X from %02X\n", func, ret, addr);
}

View File

@@ -33,7 +33,7 @@
#include <86box/chipset.h>
typedef struct opti499_t {
uint8_t idx,
uint8_t idx;
uint8_t regs[256];
uint8_t scratch[2];
} opti499_t;

File diff suppressed because it is too large Load Diff

View File

@@ -82,23 +82,23 @@
#define WIN_SEEK 0x70
#define WIN_DRIVE_DIAGNOSTICS 0x90 /* Execute Drive Diagnostics */
#define WIN_SPECIFY 0x91 /* Initialize Drive Parameters */
#define WIN_PACKETCMD 0xA0 /* Send a packet command. */
#define WIN_PIDENTIFY 0xA1 /* Identify ATAPI device */
#define WIN_READ_MULTIPLE 0xC4
#define WIN_WRITE_MULTIPLE 0xC5
#define WIN_SET_MULTIPLE_MODE 0xC6
#define WIN_READ_DMA 0xC8
#define WIN_READ_DMA_ALT 0xC9
#define WIN_WRITE_DMA 0xCA
#define WIN_WRITE_DMA_ALT 0xCB
#define WIN_STANDBYNOW1 0xE0
#define WIN_IDLENOW1 0xE1
#define WIN_SETIDLE1 0xE3
#define WIN_CHECKPOWERMODE1 0xE5
#define WIN_SLEEP1 0xE6
#define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */
#define WIN_SET_FEATURES 0xEF
#define WIN_READ_NATIVE_MAX 0xF8
#define WIN_PACKETCMD 0xa0 /* Send a packet command. */
#define WIN_PIDENTIFY 0xa1 /* Identify ATAPI device */
#define WIN_READ_MULTIPLE 0xc4
#define WIN_WRITE_MULTIPLE 0xc5
#define WIN_SET_MULTIPLE_MODE 0xc6
#define WIN_READ_DMA 0xc8
#define WIN_READ_DMA_ALT 0xc9
#define WIN_WRITE_DMA 0xcA
#define WIN_WRITE_DMA_ALT 0xcB
#define WIN_STANDBYNOW1 0xe0
#define WIN_IDLENOW1 0xe1
#define WIN_SETIDLE1 0xe3
#define WIN_CHECKPOWERMODE1 0xe5
#define WIN_SLEEP1 0xe6
#define WIN_IDENTIFY 0xeC /* Ask drive to identify itself */
#define WIN_SET_FEATURES 0xeF
#define WIN_READ_NATIVE_MAX 0xf8
#define FEATURE_SET_TRANSFER_MODE 0x03
#define FEATURE_ENABLE_IRQ_OVERLAPPED 0x5d
@@ -138,50 +138,90 @@ typedef struct ide_board_t {
ide_board_t *ide_boards[IDE_BUS_MAX];
static uint8_t ide_ter_pnp_rom[] = {
0x09, 0xf8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, /* BOX0001, serial 0, dummy checksum (filled in by isapnp_add_card) */
0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */
0x82, 0x0e, 0x00, 'I', 'D', 'E', ' ', 'C', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', /* ANSI identifier */
/* BOX0001, serial 0, dummy checksum (filled in by isapnp_add_card) */
0x09, 0xf8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
/* PnP version 1.0, vendor version 1.0 */
0x0a, 0x10, 0x10,
/* ANSI identifier */
0x82, 0x0e, 0x00, 'I', 'D', 'E', ' ', 'C', 'o', 'n', 't', 'r', 'o',
'l', 'l', 'e', 'r',
0x15, 0x09, 0xf8, 0x00, 0x01, 0x00, /* logical device BOX0001 */
0x1c, 0x41, 0xd0, 0x06, 0x00, /* compatible device PNP0600 */
0x31, 0x00, /* start dependent functions, preferred */
0x22, 0x00, 0x08, /* IRQ 11 */
0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */
0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x01, /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 1 address */
0x30, /* start dependent functions, acceptable */
0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */
0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */
0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x01, /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 1 address */
0x30, /* start dependent functions, acceptable */
0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */
0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */
0x47, 0x01, 0x00, 0x01, 0xff, 0xff, 0x01, 0x01, /* I/O 0x100-0xFFFF, decodes 16-bit, 1-byte alignment, 1 address */
0x38, /* end dependent functions */
/* Logical device BOX0001 */
0x15, 0x09, 0xf8, 0x00, 0x01, 0x00,
/* Compatible device PNP0600 */
0x1c, 0x41, 0xd0, 0x06, 0x00,
/* Start dependent functions, preferred */
0x31, 0x00,
/* IRQ 11 */
0x22, 0x00, 0x08,
/* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */
0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08,
/* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 1 address */
0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x01,
/* Start dependent functions, acceptable */
0x30,
/* IRQ 3/4/5/7/9/10/11/12 */
0x22, 0xb8, 0x1e,
/* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */
0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08,
/* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 1 address */
0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x01,
/* Start dependent functions, acceptable */
0x30,
/* IRQ 3/4/5/7/9/10/11/12 */
0x22, 0xb8, 0x1e,
/* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */
0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08,
/* I/O 0x100-0xFFFF, decodes 16-bit, 1-byte alignment, 1 address */
0x47, 0x01, 0x00, 0x01, 0xff, 0xff, 0x01, 0x01,
/* End dependent functions */
0x38,
0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */
/* End tag, dummy checksum (filled in by isapnp_add_card) */
0x79, 0x00
};
static uint8_t ide_qua_pnp_rom[] = {
0x09, 0xf8, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, /* BOX0001, serial 1, dummy checksum (filled in by isapnp_add_card) */
0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */
0x82, 0x0e, 0x00, 'I', 'D', 'E', ' ', 'C', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', /* ANSI identifier */
/* BOX0001, serial 1, dummy checksum (filled in by isapnp_add_card) */
0x09, 0xf8, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
/* PnP version 1.0, vendor version 1.0 */
0x0a, 0x10, 0x10,
/* ANSI identifier */
0x82, 0x0e, 0x00, 'I', 'D', 'E', ' ', 'C', 'o', 'n', 't', 'r', 'o',
'l', 'l', 'e', 'r',
0x15, 0x09, 0xf8, 0x00, 0x01, 0x00, /* logical device BOX0001 */
0x1c, 0x41, 0xd0, 0x06, 0x00, /* compatible device PNP0600 */
0x31, 0x00, /* start dependent functions, preferred */
0x22, 0x00, 0x04, /* IRQ 10 */
0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */
0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x01, /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 1 address */
0x30, /* start dependent functions, acceptable */
0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */
0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */
0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x01, /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 1 address */
0x30, /* start dependent functions, acceptable */
0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */
0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */
0x47, 0x01, 0x00, 0x01, 0xff, 0xff, 0x01, 0x01, /* I/O 0x100-0xFFFF, decodes 16-bit, 1-byte alignment, 1 address */
0x38, /* end dependent functions */
/* Logical device BOX0001 */
0x15, 0x09, 0xf8, 0x00, 0x01, 0x00,
/* Compatible device PNP0600 */
0x1c, 0x41, 0xd0, 0x06, 0x00,
/* Start dependent functions, preferred */
0x31, 0x00,
/* IRQ 10 */
0x22, 0x00, 0x04,
/* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */
0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08,
/* I/O 0x36E, decodes 16-bit, 1-byte alignment, 1 address */
0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x01,
/* Start dependent functions, acceptable */
0x30,
/* IRQ 3/4/5/7/9/10/11/12 */
0x22, 0xb8, 0x1e,
/* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */
0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08,
/* I/O 0x36E, decodes 16-bit, 1-byte alignment, 1 address */
0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x01,
/* Start dependent functions, acceptable */
0x30,
/* IRQ 3/4/5/7/9/10/11/12 */
0x22, 0xb8, 0x1e,
/* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */
0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08,
/* I/O 0x100-0xFFFF, decodes 16-bit, 1-byte alignment, 1 address */
0x47, 0x01, 0x00, 0x01, 0xff, 0xff, 0x01, 0x01,
/* End dependent functions */
0x38,
0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */
/* End tag, dummy checksum (filled in by isapnp_add_card) */
0x79, 0x00
};
ide_t *ide_drives[IDE_NUM];
@@ -336,7 +376,7 @@ ide_atapi_get_period(uint8_t channel)
}
static void
ide_irq_update(ide_board_t *dev)
ide_irq_update(ide_board_t *dev, int log)
{
ide_t *ide;
uint8_t set;
@@ -344,7 +384,10 @@ ide_irq_update(ide_board_t *dev)
if (dev == NULL)
return;
ide_log("IDE %i: IRQ update (%i)\n", dev->cur_dev >> 1, dev->irq);
#ifdef ENABLE_IDE_LOG
if (log)
ide_log("IDE %i: IRQ update (%i)\n", dev->cur_dev >> 1, dev->irq);
#endif
ide = ide_drives[dev->cur_dev];
set = !(ide_boards[ide->board]->devctl & 2) && ide->irqstat;
@@ -356,32 +399,22 @@ ide_irq_update(ide_board_t *dev)
}
void
ide_irq_raise(ide_t *ide)
ide_irq(ide_t *ide, int set, int log)
{
if (!ide_boards[ide->board])
return;
ide_log("IDE %i: IRQ raise\n", ide->channel);
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
ide_log("IDE %i: IRQ %s\n", ide->channel, set ? "raise" : "lower");
#endif
ide->irqstat = 1;
ide->service = 1;
ide->irqstat = set;
if (set)
ide->service = 1;
if (ide->selected)
ide_irq_update(ide_boards[ide->board]);
}
void
ide_irq_lower(ide_t *ide)
{
if (!ide_boards[ide->board])
return;
ide_log("IDE %i: IRQ lower\n", ide->channel);
ide->irqstat = 0;
if (ide->selected)
ide_irq_update(ide_boards[ide->board]);
ide_irq_update(ide_boards[ide->board], log);
}
/**
@@ -590,7 +623,7 @@ ide_identify(ide_t *ide)
if (ide->type == IDE_ATAPI)
ide->identify(ide, !IDE_ATAPI_IS_EARLY && !ide_boards[ide->board]->force_ata3 && (bm != NULL));
else if (ide->type != IDE_NONE)
else if (ide->type == IDE_HDD)
ide_hd_identify(ide);
else {
fatal("IDE IDENTIFY or IDENTIFY PACKET DEVICE on non-attached IDE device\n");
@@ -682,15 +715,15 @@ ide_get_sector(ide_t *ide)
uint32_t heads;
uint32_t sectors;
if (ide->lba)
if (ide->tf->lba)
return (off64_t) ide->lba_addr;
else {
heads = ide->cfg_hpc;
sectors = ide->cfg_spt;
uint8_t sector = ide->sector ? (ide->sector - 1) : 0;
uint8_t sector = ide->tf->sector ? (ide->tf->sector - 1) : 0;
return ((((off64_t) ide->tf->cylinder * heads) + (off64_t) ide->head) * sectors) +
return ((((off64_t) ide->tf->cylinder * heads) + (off64_t) ide->tf->head) * sectors) +
(off64_t) sector;
}
}
@@ -701,15 +734,15 @@ ide_get_sector(ide_t *ide)
static void
ide_next_sector(ide_t *ide)
{
if (ide->lba)
if (ide->tf->lba)
ide->lba_addr++;
else {
ide->sector++;
if ((ide->sector == 0) || (ide->sector == (ide->cfg_spt + 1))) {
ide->sector = 1;
ide->head++;
if ((ide->head == 0) || (ide->head == ide->cfg_hpc)) {
ide->head = 0;
ide->tf->sector++;
if ((ide->tf->sector == 0) || (ide->tf->sector == (ide->cfg_spt + 1))) {
ide->tf->sector = 1;
ide->tf->head++;
if ((ide->tf->head == 0) || (ide->head == ide->cfg_hpc)) {
ide->tf->head = 0;
ide->tf->cylinder++;
}
}
@@ -736,13 +769,12 @@ loadhd(ide_t *ide, int d, UNUSED(const char *fn))
void
ide_set_signature(ide_t *ide)
{
uint16_t ide_signatures[3] = { /* 0xffff */ 0x7f7f, 0x0000, 0xeb14 };
uint16_t ide_signatures[4] = { 0x7f7f, 0x0000, 0xeb14, 0x7f7f };
ide->sector = 1;
ide->head = 0;
ide->tf->secount = 1;
ide->tf->cylinder = ide_signatures[ide->type];
ide->tf->sector = 1;
ide->tf->head = 0;
ide->tf->secount = 1;
ide->tf->cylinder = ide_signatures[ide->type & ~IDE_SHADOW];
if (ide->type == IDE_HDD)
ide->drive = 0;
@@ -846,16 +878,16 @@ ide_set_sector(ide_t *ide, int64_t sector_num)
{
unsigned int cyl;
unsigned int r;
if (ide->lba) {
ide->head = (sector_num >> 24) & 0xff;
if (ide->tf->lba) {
ide->tf->head = (sector_num >> 24) & 0xff;
ide->tf->cylinder = (sector_num >> 8) & 0xffff;
ide->sector = sector_num & 0xff;
ide->tf->sector = sector_num & 0xff;
} else {
cyl = sector_num / (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt);
r = sector_num % (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt);
ide->tf->cylinder = cyl & 0xffff;
ide->head = ((r / hdd[ide->hdd_num].spt) & 0x0f) & 0xff;
ide->sector = ((r % hdd[ide->hdd_num].spt) + 1) & 0xff;
ide->tf->head = ((r / hdd[ide->hdd_num].spt) & 0x0f) & 0xff;
ide->tf->sector = ((r % hdd[ide->hdd_num].spt) + 1) & 0xff;
}
}
@@ -961,14 +993,20 @@ ide_atapi_callback(ide_t *ide)
"Complete" };
char *phase;
if (ide->sc->packet_status <= PHASE_COMPLETE)
phase = phases[ide->sc->packet_status];
else if (ide->sc->packet_status == PHASE_ERROR)
phase = "Error";
else if (ide->sc->packet_status == PHASE_NONE)
phase = "None";
else
phase = "Unknown";
switch (ide->sc->packet_status) {
default:
phase = "Unknown";
break;
case PHASE_IDLE ... PHASE_COMPLETE:
phase = phases[ide->sc->packet_status];
break;
case PHASE_ERROR:
phase = "Error";
break;
case PHASE_NONE:
phase = "None";
break;
}
ide_log("Phase: %02X (%s)\n", ide->sc->packet_status, phase);
#endif
@@ -1169,36 +1207,38 @@ ide_write_data(ide_t *ide, uint16_t val, int length)
uint8_t *idebufferb = (uint8_t *) ide->buffer;
uint16_t *idebufferw = ide->buffer;
if (ide->command == WIN_PACKETCMD) {
if (ide->type == IDE_ATAPI)
ide_atapi_packet_write(ide, val, length);
else
ide->tf->pos = 0;
} else {
if (length == 2) {
idebufferw[ide->tf->pos >> 1] = val & 0xffff;
ide->tf->pos += 2;
if ((ide->type != IDE_NONE) && !(ide->type & IDE_SHADOW) && ide->buffer) {
if (ide->command == WIN_PACKETCMD) {
if (ide->type == IDE_ATAPI)
ide_atapi_packet_write(ide, val, length);
else
ide->tf->pos = 0;
} else {
idebufferb[ide->tf->pos] = val & 0xff;
ide->tf->pos++;
}
if (length == 2) {
idebufferw[ide->tf->pos >> 1] = val & 0xffff;
ide->tf->pos += 2;
} else {
idebufferb[ide->tf->pos] = val & 0xff;
ide->tf->pos++;
}
if (ide->tf->pos >= 512) {
ide->tf->pos = 0;
ide->tf->atastat = BSY_STAT;
double seek_time = hdd_timing_write(&hdd[ide->hdd_num], ide_get_sector(ide), 1);
double xfer_time = ide_get_xfer_time(ide, 512);
double wait_time = seek_time + xfer_time;
if (ide->command == WIN_WRITE_MULTIPLE) {
if ((ide->blockcount + 1) >= ide->blocksize || ide->tf->secount == 1) {
ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay);
ide->pending_delay = 0;
} else {
ide->pending_delay += wait_time;
ide_callback(ide);
}
} else
ide_set_callback(ide, wait_time);
if (ide->tf->pos >= 512) {
ide->tf->pos = 0;
ide->tf->atastat = BSY_STAT;
double seek_time = hdd_timing_write(&hdd[ide->hdd_num], ide_get_sector(ide), 1);
double xfer_time = ide_get_xfer_time(ide, 512);
double wait_time = seek_time + xfer_time;
if (ide->command == WIN_WRITE_MULTIPLE) {
if ((ide->blockcount + 1) >= ide->blocksize || ide->tf->secount == 1) {
ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay);
ide->pending_delay = 0;
} else {
ide->pending_delay += wait_time;
ide_callback(ide);
}
} else
ide_set_callback(ide, wait_time);
}
}
}
}
@@ -1214,7 +1254,9 @@ ide_writew(uint16_t addr, uint16_t val, void *priv)
ch = dev->cur_dev;
ide = ide_drives[ch];
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
ide_log("ide_writew(%04X, %04X, %08X)\n", addr, val, priv);
#endif
addr &= 0x7;
@@ -1246,7 +1288,9 @@ ide_writel(uint16_t addr, uint32_t val, void *priv)
ch = dev->cur_dev;
ide = ide_drives[ch];
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
ide_log("ide_writel(%04X, %08X, %08X)\n", addr, val, priv);
#endif
addr &= 0x7;
@@ -1292,6 +1336,10 @@ ide_write_devctl(UNUSED(uint16_t addr), uint8_t val, void *priv)
uint8_t old;
ch = dev->cur_dev;
/* ATA/ATAPI specification: On a slave with non-present master, pretend the
master is selected. */
if (ide_drives[ch]->type & IDE_SHADOW)
ch ^= 1;
ide = ide_drives[ch];
ide_other = ide_drives[ch ^ 1];
@@ -1361,22 +1409,22 @@ ide_write_devctl(UNUSED(uint16_t addr), uint8_t val, void *priv)
old = dev->devctl;
dev->devctl = val;
if (!(val & 0x02) && (old & 0x02))
ide_irq_update(ide_boards[ide->board]);
ide_irq_update(ide_boards[ide->board], 1);
}
static void
ide_reset_registers(ide_t *ide)
{
uint16_t ide_signatures[3] = { /* 0xffff */ 0x7f7f, 0x0000, 0xeb14 };
uint16_t ide_signatures[4] = { 0x7f7f, 0x0000, 0xeb14, 0x7f7f };
ide->tf->atastat = DRDY_STAT | DSC_STAT;
ide->tf->error = 1;
ide->tf->secount = 1;
ide->tf->cylinder = ide_signatures[ide->type];
ide->tf->cylinder = ide_signatures[ide->type & ~IDE_SHADOW];
ide->tf->sector = 1;
ide->tf->head = 0;
ide->sector = 1;
ide->head = 0;
ide->reset = 0;
ide->reset = 0;
if (ide->type == IDE_ATAPI)
ide->sc->callback = 0.0;
@@ -1391,7 +1439,6 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
ide_t *ide;
ide_t *ide_other;
int ch;
int absent = 0;
int bad = 0;
int reset = 0;
@@ -1399,64 +1446,74 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
ide = ide_drives[ch];
ide_other = ide_drives[ch ^ 1];
/* Absent and is master or both are absent. */
if ((ide->type == IDE_NONE) && ((ide_drives[ch ^ 1]->type == IDE_NONE) || !(ch & 1)))
absent = 1;
/* Absent and is slave and master is present. */
else if ((ide->type == IDE_NONE) && (ch & 1))
absent = 2;
ide_log("ide_writeb(%04X, %02X, %08X)\n", addr, val, priv);
addr &= 0x7;
if ((absent != 1) || ((addr != 0x0) && (addr != 0x7))) switch (addr) {
if ((ide->type != IDE_NONE) || ((addr != 0x0) && (addr != 0x7))) switch (addr) {
case 0x0: /* Data */
if (absent == 0)
ide_write_data(ide, val | (val << 8), 2);
ide_write_data(ide, val | (val << 8), 2);
break;
/* Note to self: for ATAPI, bit 0 of this is DMA if set, PIO if clear. */
case 0x1: /* Features */
ide->tf->cylprecomp = val;
if (ide->type == IDE_ATAPI)
ide_log("ATAPI transfer mode: %s\n", (val & 1) ? "DMA" : "PIO");
if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) {
ide->tf->cylprecomp = val;
if (ide->type == IDE_ATAPI)
ide_log("ATAPI transfer mode: %s\n", (val & 1) ? "DMA" : "PIO");
}
/* The ATA-3 specification says this register is the parameter for the
command and is unclear as to whether or not it's written to both
devices at once. Writing it to both devices at once breaks CD boot
on the AMI Apollo. */
#ifdef WRITE_PARAM_TO_BOTH_DEVICES
ide_other->tf->cylprecomp = val;
#endif
return;
if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT)))
ide_other->tf->cylprecomp = val;
break;
case 0x2: /* Sector count */
ide->tf->secount = val;
ide_other->tf->secount = val;
if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT)))
ide->tf->secount = val;
if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT)))
ide_other->tf->secount = val;
break;
case 0x3: /* Sector */
ide->sector = val;
ide->lba_addr = (ide->lba_addr & 0xfffff00) | val;
ide_other->sector = val;
ide_other->lba_addr = (ide_other->lba_addr & 0xfffff00) | val;
if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) {
ide->tf->sector = val;
ide->lba_addr = (ide->lba_addr & 0xfffff00) | val;
}
if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) {
ide_other->tf->sector = val;
ide_other->lba_addr = (ide_other->lba_addr & 0xfffff00) | val;
}
break;
case 0x4: /* Cylinder low */
ide->tf->cylinder = (ide->tf->cylinder & 0xff00) | val;
ide->lba_addr = (ide->lba_addr & 0xfff00ff) | (val << 8);
if (ide->type & IDE_SHADOW)
break;
ide_other->tf->cylinder = (ide_other->tf->cylinder & 0xff00) | val;
ide_other->lba_addr = (ide_other->lba_addr & 0xfff00ff) | (val << 8);
if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) {
ide->tf->cylinder = (ide->tf->cylinder & 0xff00) | val;
ide->lba_addr = (ide->lba_addr & 0xfff00ff) | (val << 8);
}
if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) {
ide_other->tf->cylinder = (ide_other->tf->cylinder & 0xff00) | val;
ide_other->lba_addr = (ide_other->lba_addr & 0xfff00ff) | (val << 8);
}
break;
case 0x5: /* Cylinder high */
ide->tf->cylinder = (ide->tf->cylinder & 0xff) | (val << 8);
ide->lba_addr = (ide->lba_addr & 0xf00ffff) | (val << 16);
if (ide->type & IDE_SHADOW)
break;
ide_other->tf->cylinder = (ide_other->tf->cylinder & 0xff) | (val << 8);
ide_other->lba_addr = (ide_other->lba_addr & 0xf00ffff) | (val << 16);
if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) {
ide->tf->cylinder = (ide->tf->cylinder & 0xff) | (val << 8);
ide->lba_addr = (ide->lba_addr & 0xf00ffff) | (val << 16);
}
if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) {
ide_other->tf->cylinder = (ide_other->tf->cylinder & 0xff) | (val << 8);
ide_other->lba_addr = (ide_other->lba_addr & 0xf00ffff) | (val << 16);
}
break;
case 0x6: /* Drive/Head */
@@ -1482,20 +1539,29 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
ide_set_board_callback(ide->board, 0.0);
reset = 1;
} else
ide_irq_update(ide_boards[ide->board]);
ide_irq_update(ide_boards[ide->board], 1);
}
if (!reset) {
ide->head = ide_other->head = val & 0xF;
ide->lba = ide_other->lba = val & 0x40;
if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) {
ide->tf->drvsel = val & 0xef;
ide->lba_addr = (ide->lba_addr & 0x0ffffff) |
(ide->tf->head << 24);
}
ide->lba_addr = (ide->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24);
ide_other->lba_addr = (ide_other->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24);
if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) {
ide_other->tf->drvsel = val & 0xef;
ide_other->lba_addr = (ide_other->lba_addr & 0x0ffffff) |
(ide->tf->head << 24);
}
}
break;
case 0x7: /* Command register */
if (absent != 0)
if (ide->tf->atastat & (BSY_STAT | DRQ_STAT))
break;
if ((ide->type == IDE_NONE) || ((ide->type & IDE_SHADOW) && (val != WIN_DRIVE_DIAGNOSTICS)))
break;
ide_irq_lower(ide);
@@ -1721,70 +1787,70 @@ ide_read_data(ide_t *ide, int length)
{
const uint8_t *idebufferb = (uint8_t *) ide->buffer;
const uint16_t *idebufferw = ide->buffer;
int ch = ide->channel;
uint16_t ret = 0;
double seek_us;
double xfer_us;
/* Absent and is master or both are absent. */
if ((ide->type == IDE_NONE) && ((ide_drives[ch ^ 1]->type == IDE_NONE) || !(ch & 1))) {
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
ide_log("ide_read_data(): ch = %i, board = %i, type = %i\n", ch,
ide->board, ide->type);
#endif
if ((ide->type == IDE_NONE) || (ide->type & IDE_SHADOW) || !ide->buffer) {
if (length == 2)
ret = 0xff7f;
else
ret = 0x7f;
/* Absent and is slave and master is present. */
} else if ((ide->type != IDE_NONE) || !(ch & 1)) {
if (!ide->buffer) {
if (length == 2)
ret = 0xffff;
else
ret = 0xff;
} else if (ide->command == WIN_PACKETCMD) {
if (ide->type == IDE_ATAPI)
ret = ide_atapi_packet_read(ide, length);
else {
ide_log("Drive not ATAPI (position: %i)\n", ide->tf->pos);
ide->tf->pos = 0;
}
} else if (ide->command == WIN_PACKETCMD) {
if (ide->type == IDE_ATAPI)
ret = ide_atapi_packet_read(ide, length);
else {
ide_log("Drive not ATAPI (position: %i)\n", ide->tf->pos);
ide->tf->pos = 0;
}
} else {
if (length == 2) {
ret = idebufferw[ide->tf->pos >> 1];
ide->tf->pos += 2;
} else {
if (length == 2) {
ret = idebufferw[ide->tf->pos >> 1];
ide->tf->pos += 2;
} else {
ret = idebufferb[ide->tf->pos];
ide->tf->pos++;
}
ret = idebufferb[ide->tf->pos];
ide->tf->pos++;
}
if (ide->tf->pos >= 512) {
ide->tf->pos = 0;
ide->tf->atastat = DRDY_STAT | DSC_STAT;
if (ide->type == IDE_ATAPI)
ide->sc->packet_status = PHASE_IDLE;
if (ide->tf->pos >= 512) {
ide->tf->pos = 0;
ide->tf->atastat = DRDY_STAT | DSC_STAT;
if (ide->type == IDE_ATAPI)
ide->sc->packet_status = PHASE_IDLE;
if ((ide->command == WIN_READ) || (ide->command == WIN_READ_NORETRY) ||
(ide->command == WIN_READ_MULTIPLE)) {
ide->tf->secount--;
if ((ide->command == WIN_READ) ||
(ide->command == WIN_READ_NORETRY) ||
(ide->command == WIN_READ_MULTIPLE)) {
ide->tf->secount--;
if (ide->tf->secount) {
ide_next_sector(ide);
ide->tf->atastat = BSY_STAT | READY_STAT | DSC_STAT;
if (ide->command == WIN_READ_MULTIPLE) {
if (!ide->blockcount) {
uint32_t sec_count = ide->tf->secount ? ide->tf->secount : 256;
if (sec_count > ide->blocksize)
sec_count = ide->blocksize;
double seek_time = hdd_timing_read(&hdd[ide->hdd_num],
ide_get_sector(ide), sec_count);
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
ide_set_callback(ide, seek_time + xfer_time);
} else
ide_callback(ide);
} else {
double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), 1);
double xfer_time = ide_get_xfer_time(ide, 512);
ide_set_callback(ide, seek_time + xfer_time);
}
} else
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
}
if (ide->tf->secount) {
ide_next_sector(ide);
ide->tf->atastat = BSY_STAT | READY_STAT | DSC_STAT;
if (ide->command == WIN_READ_MULTIPLE) {
if (!ide->blockcount) {
uint32_t cnt = ide->tf->secount ?
ide->tf->secount : 256;
if (cnt > ide->blocksize)
cnt = ide->blocksize;
seek_us = hdd_timing_read(&hdd[ide->hdd_num],
ide_get_sector(ide), cnt);
xfer_us = ide_get_xfer_time(ide, 512 * cnt);
ide_set_callback(ide, seek_us + xfer_us);
} else
ide_callback(ide);
} else {
seek_us = hdd_timing_read(&hdd[ide->hdd_num],
ide_get_sector(ide), 1);
xfer_us = ide_get_xfer_time(ide, 512);
ide_set_callback(ide, seek_us + xfer_us);
}
} else
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
}
}
}
@@ -1798,11 +1864,11 @@ ide_status(ide_t *ide, ide_t *ide_other, int ch)
uint8_t ret;
/* Absent and is master or both are absent. */
if ((ide->type == IDE_NONE) && ((ide_drives[ch ^ 1]->type == IDE_NONE) || !(ch & 1))) {
if (ide->type == IDE_NONE) {
/* Bit 7 pulled down, all other bits pulled up, per the spec. */
ret = 0x7f;
/* Absent and is slave and master is present. */
} else if ((ide->type == IDE_NONE) && (ch & 1)) {
} else if (ide->type & IDE_SHADOW) {
/* On real hardware, a slave with a present master always
returns a status of 0x00.
Confirmed by the ATA-3 and ATA-4 specifications. */
@@ -1821,21 +1887,11 @@ ide_readb(uint16_t addr, void *priv)
{
const ide_board_t *dev = (ide_board_t *) priv;
int ch;
int absent = 0;
ide_t *ide;
ide_t *ide_other;
uint8_t ret = 0xff;
ch = dev->cur_dev;
ide = ide_drives[ch];
ide_other = ide_drives[ch ^ 1];
/* Absent and is master or both are absent. */
if ((ide->type == IDE_NONE) && ((ide_drives[ch ^ 1]->type == IDE_NONE) || !(ch & 1)))
absent = 1;
/* Absent and is slave and master is present. */
else if ((ide->type == IDE_NONE) && (ch & 1))
absent = 2;
switch (addr & 0x7) {
case 0x0: /* Data */
@@ -1846,7 +1902,7 @@ ide_readb(uint16_t addr, void *priv)
Bit 2 = ABRT (aborted command), Bit 1 = EOM (end of media),
and Bit 0 = ILI (illegal length indication). */
case 0x1: /* Error */
if (absent == 1)
if (ide->type == IDE_NONE)
ret = 0x7f;
else
ret = ide->tf->error;
@@ -1866,52 +1922,52 @@ ide_readb(uint16_t addr, void *priv)
0 1 0 Data from host
1 0 1 Status. */
case 0x2: /* Sector count */
if (absent == 1)
if (ide->type == IDE_NONE)
ret = 0x7f;
else if (absent == 2)
ret = ide_other->tf->secount;
else
ret = ide->tf->secount;
break;
case 0x3: /* Sector */
if (absent == 1)
if (ide->type == IDE_NONE)
ret = 0x7f;
else if (absent == 2)
ret = (uint8_t) ide_other->sector;
else
ret = (uint8_t) ide->sector;
ret = (uint8_t) ide->tf->sector;
break;
case 0x4: /* Cylinder low */
if (absent == 1)
if (ide->type == IDE_NONE)
ret = 0x7f;
else if (absent == 2)
ret = ide_other->tf->cylinder & 0xff;
else
ret = ide->tf->cylinder & 0xff;
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
ide_log("Cylinder low @ board %i, channel %i: ide->type = %i, "
"ret = %02X\n", ide->board, ide->channel, ide->type, ret);
#endif
break;
case 0x5: /* Cylinder high */
if (absent == 1)
if (ide->type == IDE_NONE)
ret = 0x7f;
else if (absent == 2)
ret = ide_other->tf->cylinder >> 8;
else
ret = ide->tf->cylinder >> 8;
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
pclog("Cylinder high @ board %i, channel %i: ide->type = %i, "
"ret = %02X\n", ide->board, ide->channel, ide->type, ret);
#endif
break;
case 0x6: /* Drive/Head */
if (absent == 1)
if (ide->type == IDE_NONE)
ret = 0x7f;
else
ret = (uint8_t) (ide->head | ((ch & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0);
ret = ide->tf->drvsel | ((ch & 1) ? 0xb0 : 0xa0);
break;
/* For ATAPI: Bit 5 is DMA ready, but without overlapped or interlaved DMA, it is
DF (drive fault). */
case 0x7: /* Status */
ide_irq_lower(ide);
ide_irq(ide, 0, 0);
ret = ide_status(ide, ide_drives[ch ^ 1], ch);
break;
@@ -1969,7 +2025,9 @@ ide_readw(uint16_t addr, void *priv)
break;
}
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
ide_log("ide_readw(%04X, %08X) = %04X\n", addr, priv, ret);
#endif
return ret;
}
@@ -2002,7 +2060,9 @@ ide_readl(uint16_t addr, void *priv)
break;
}
#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2)
ide_log("ide_readl(%04X, %08X) = %04X\n", addr, priv, ret);
#endif
return ret;
}
@@ -2012,9 +2072,7 @@ ide_board_callback(void *priv)
ide_board_t *dev = (ide_board_t *) priv;
ide_t *ide;
#ifdef ENABLE_IDE_LOG
ide_log("ide_board_callback(%i)\n", dev->cur_dev >> 1);
#endif
for (uint8_t i = 0; i < 2; i++) {
ide = dev->ide[i];
@@ -2060,13 +2118,13 @@ ide_callback(void *priv)
ide_log("ide_callback(%i): %02X\n", ide->channel, ide->command);
switch (ide->command) {
case WIN_SEEK ... 0x7F:
chk_chs = !ide->lba;
case WIN_SEEK ... 0x7f:
chk_chs = !ide->tf->lba;
if (ide->type == IDE_ATAPI)
atapi_error_no_ready(ide);
else {
if (chk_chs && ((ide->tf->cylinder >= ide->tracks) || (ide->head >= ide->hpc) ||
!ide->sector || (ide->sector > ide->spt)))
if (chk_chs && ((ide->tf->cylinder >= ide->tracks) || (ide->tf->head >= ide->hpc) ||
!ide->tf->sector || (ide->tf->sector > ide->spt)))
err = IDNF_ERR;
else {
ide->tf->atastat = DRDY_STAT | DSC_STAT;
@@ -2075,7 +2133,7 @@ ide_callback(void *priv)
}
break;
case WIN_RECAL ... 0x1F:
case WIN_RECAL ... 0x1f:
if (ide->type == IDE_ATAPI)
atapi_error_no_ready(ide);
else {
@@ -2091,7 +2149,7 @@ ide_callback(void *priv)
ide->tf->error = 1; /*Device passed*/
ide->tf->secount = 1;
ide->sector = 1;
ide->tf->sector = 1;
ide_set_signature(ide);
@@ -2129,7 +2187,7 @@ ide_callback(void *priv)
if (ide->type == IDE_ATAPI) {
ide_set_signature(ide);
err = ABRT_ERR;
} else if (!ide->lba && (ide->cfg_spt == 0))
} else if (!ide->tf->lba && (ide->cfg_spt == 0))
err = IDNF_ERR;
else {
if (ide->do_initial_read) {
@@ -2157,7 +2215,7 @@ ide_callback(void *priv)
if ((ide->type == IDE_ATAPI) || ide_boards[ide->board]->force_ata3 || (bm == NULL)) {
ide_log("IDE %i: DMA read aborted (bad device or board)\n", ide->channel);
err = ABRT_ERR;
} else if (!ide->lba && (ide->cfg_spt == 0)) {
} else if (!ide->tf->lba && (ide->cfg_spt == 0)) {
ide_log("IDE %i: DMA read aborted (SPECIFY failed)\n", ide->channel);
err = IDNF_ERR;
} else {
@@ -2207,7 +2265,7 @@ ide_callback(void *priv)
mand error. */
if ((ide->type == IDE_ATAPI) || !ide->blocksize)
err = ABRT_ERR;
else if (!ide->lba && (ide->cfg_spt == 0))
else if (!ide->tf->lba && (ide->cfg_spt == 0))
err = IDNF_ERR;
else {
if (ide->do_initial_read) {
@@ -2235,7 +2293,7 @@ ide_callback(void *priv)
case WIN_WRITE_NORETRY:
if (ide->type == IDE_ATAPI)
err = ABRT_ERR;
else if (!ide->lba && (ide->cfg_spt == 0))
else if (!ide->tf->lba && (ide->cfg_spt == 0))
err = IDNF_ERR;
else {
hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
@@ -2258,7 +2316,7 @@ ide_callback(void *priv)
if ((ide->type == IDE_ATAPI) || ide_boards[ide->board]->force_ata3 || (bm == NULL)) {
ide_log("IDE %i: DMA write aborted (bad device type or board)\n", ide->channel);
err = ABRT_ERR;
} else if (!ide->lba && (ide->cfg_spt == 0)) {
} else if (!ide->tf->lba && (ide->cfg_spt == 0)) {
ide_log("IDE %i: DMA write aborted (SPECIFY failed)\n", ide->channel);
err = IDNF_ERR;
} else {
@@ -2307,7 +2365,7 @@ ide_callback(void *priv)
mand error. */
if ((ide->type == IDE_ATAPI) || !ide->blocksize)
err = ABRT_ERR;
else if (!ide->lba && (ide->cfg_spt == 0))
else if (!ide->tf->lba && (ide->cfg_spt == 0))
err = IDNF_ERR;
else {
hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
@@ -2332,7 +2390,7 @@ ide_callback(void *priv)
case WIN_VERIFY_ONCE:
if (ide->type == IDE_ATAPI)
err = ABRT_ERR;
else if (!ide->lba && (ide->cfg_spt == 0))
else if (!ide->tf->lba && (ide->cfg_spt == 0))
err = IDNF_ERR;
else {
ide->tf->pos = 0;
@@ -2345,7 +2403,7 @@ ide_callback(void *priv)
case WIN_FORMAT:
if (ide->type == IDE_ATAPI)
err = ABRT_ERR;
else if (!ide->lba && (ide->cfg_spt == 0))
else if (!ide->tf->lba && (ide->cfg_spt == 0))
err = IDNF_ERR;
else {
hdd_image_zero(ide->hdd_num, ide_get_sector(ide), ide->tf->secount);
@@ -2364,7 +2422,7 @@ ide_callback(void *priv)
if (ide->cfg_spt == 0) {
/* Only accept after RESET or DIAG. */
ide->cfg_spt = ide->tf->secount;
ide->cfg_hpc = ide->head + 1;
ide->cfg_hpc = ide->tf->head + 1;
}
ide->command = 0x00;
ide->tf->atastat = DRDY_STAT | DSC_STAT;
@@ -2863,8 +2921,14 @@ ide_drive_reset(int d)
{
ide_log("Resetting IDE drive %i...\n", d);
if ((d & 1) && (ide_drives[d]->type == IDE_NONE) && (ide_drives[d ^ 1]->type != IDE_NONE)) {
ide_drives[d]->type = ide_drives[d ^ 1]->type | IDE_SHADOW;
free(ide_drives[d]->tf);
ide_drives[d]->tf = ide_drives[d ^ 1]->tf;
} else
ide_drives[d]->tf->atastat = DRDY_STAT | DSC_STAT;
ide_drives[d]->channel = d;
ide_drives[d]->tf->atastat = DRDY_STAT | DSC_STAT;
ide_drives[d]->service = 0;
ide_drives[d]->board = d >> 1;
ide_drives[d]->selected = !(d & 1);

View File

@@ -27,7 +27,9 @@
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/cdrom.h>
#include <86box/hdd.h>
#include <86box/scsi_device.h>
#include <86box/scsi_disk.h>
#include <86box/scsi_cdrom.h>
#include <86box/dma.h>
#include <86box/io.h>
@@ -389,7 +391,6 @@ sff_bus_master_set_irq(uint8_t status, void *priv)
{
sff8038i_t *dev = (sff8038i_t *) priv;
uint8_t irq = !!(status & 0x04);
int irq_shift = 0;
if (!(dev->status & 0x04) || (status & 0x04))
dev->status = (dev->status & ~0x04) | status;
@@ -410,16 +411,12 @@ sff_bus_master_set_irq(uint8_t status, void *priv)
else
pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state);
break;
case IRQ_MODE_MIRQ_0:
case IRQ_MODE_MIRQ_1:
/* MIRQ 0 or 1. */
case IRQ_MODE_MIRQ_2:
case IRQ_MODE_MIRQ_3:
/* MIRQ 2 or 3. */
case IRQ_MODE_MIRQ_0 ... IRQ_MODE_MIRQ_3:
/* MIRQ 0, 1, 2, or 3. */
if (irq)
pci_set_mirq((dev->irq_mode & 3) + irq_shift, 0, &dev->irq_state);
pci_set_mirq(dev->irq_mode & 3, 0, &dev->irq_state);
else
pci_clear_mirq((dev->irq_mode & 3) + irq_shift, 0, &dev->irq_state);
pci_clear_mirq(dev->irq_mode & 3, 0, &dev->irq_state);
break;
/* TODO: Redo this as a MIRQ. */
case IRQ_MODE_PCI_IRQ_LINE:
@@ -477,6 +474,10 @@ sff_reset(void *priv)
sff_log("SFF8038i: Reset\n");
#endif
for (uint8_t i = 0; i < HDD_NUM; i++) {
if ((hdd[i].bus == HDD_BUS_ATAPI) && (hdd[i].ide_channel < 4) && hdd[i].priv)
scsi_disk_reset((scsi_common_t *) hdd[i].priv);
}
for (uint8_t i = 0; i < CDROM_NUM; i++) {
if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv)
scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv);
@@ -522,21 +523,15 @@ sff_set_irq_mode(sff8038i_t *dev, int irq_mode)
default:
case IRQ_MODE_LEGACY:
/* Legacy IRQ mode. */
sff_log("[%08X] Setting IRQ mode to legacy IRQ %i\n", dev, 14 + channel);
sff_log("[%08X] Setting IRQ mode to legacy IRQ %i\n", dev, dev->irq_line);
break;
case IRQ_MODE_PCI_IRQ_PIN:
/* Native PCI IRQ mode with interrupt pin. */
sff_log("[%08X] Setting IRQ mode to native PCI INT%c\n", dev, 0x40 + dev->irq_pin);
break;
case IRQ_MODE_MIRQ_0:
case IRQ_MODE_MIRQ_1:
/* MIRQ 0 or 1. */
sff_log("[%08X] Setting IRQ mode to PCI MIRQ%i\n", dev, irq_mode & 1);
break;
case IRQ_MODE_MIRQ_2:
case IRQ_MODE_MIRQ_3:
/* MIRQ 0 or 1. */
sff_log("[%08X] Setting IRQ mode to PCI MIRQ%i\n", dev, (irq_mode & 1) + 1);
case IRQ_MODE_MIRQ_0 ... IRQ_MODE_MIRQ_3:
/* MIRQ 0, 1, 2, or 3. */
sff_log("[%08X] Setting IRQ mode to PCI MIRQ%i\n", dev, dev->irq_mode & 3);
break;
case IRQ_MODE_PCI_IRQ_LINE:
/* Native PCI IRQ mode with specified interrupt line. */

View File

@@ -36,9 +36,13 @@
#define HDC_QUATERNARY_IRQ 10
enum {
IDE_NONE = 0,
IDE_HDD,
IDE_ATAPI
IDE_NONE = 0, /* Absent master or both. */
IDE_HDD, /* Hard disk. */
IDE_ATAPI, /* ATAPI device. */
IDE_RESERVED, /* Reserved, do not use. */
IDE_SHADOW, /* Shadow flag, do not assign on is own. */
IDE_HDD_SHADOW, /* Shadow of a hard disk. */
IDE_ATAPI_SHADOW /* Shadow of an ATAPI device. */
};
typedef struct ide_tf_s {
@@ -59,28 +63,26 @@ typedef struct ide_tf_s {
uint8_t status;
};
uint8_t error;
uint16_t pad;
uint8_t sector;
union {
uint8_t drvsel;
struct {
uint8_t head :4;
uint8_t pad :2;
uint8_t lba :1;
uint8_t pad0 :1;
};
};
uint32_t pos;
} ide_tf_t;
#ifdef _TIMER_H_
typedef struct ide_s {
#ifdef ANCIENT_CODE
/* Task file. */
uint8_t cylprecomp;
uint8_t secount;
uint16_t cylinder;
uint8_t atastat;
uint8_t error;
uint16_t pad;
uint32_t pos;
#endif
/* The rest. */
uint8_t selected;
uint8_t command;
uint8_t head;
uint8_t sector;
uint8_t pad;
int type;
int board;
int irqstat;
@@ -90,7 +92,6 @@ typedef struct ide_s {
int hdd_num;
int channel;
int sector_pos;
int lba;
int reset;
int mdma_mode;
int do_initial_read;
@@ -179,8 +180,7 @@ extern int ide_qua_enabled;
#ifdef SCSI_DEVICE_H
extern ide_t *ide_get_drive(int ch);
extern void ide_irq_raise(ide_t *ide);
extern void ide_irq_lower(ide_t *ide);
extern void ide_irq(ide_t *ide, int set, int log);
extern void ide_allocate_buffer(ide_t *dev);
extern void ide_atapi_attach(ide_t *dev);
#endif
@@ -224,6 +224,9 @@ extern uint8_t ide_read_ali_75(void);
extern uint8_t ide_read_ali_76(void);
/* Legacy #define's. */
#define ide_irq_raise(ide) ide_irq(ide, 1, 1)
#define ide_irq_lower(ide) ide_irq(ide, 0, 1)
#define ide_set_base(board, port) ide_set_base_addr(board, 0, port)
#define ide_set_side(board, port) ide_set_base_addr(board, 1, port)

View File

@@ -68,6 +68,8 @@ typedef struct scsi_disk_t {
extern scsi_disk_t *scsi_disk[HDD_NUM];
extern void scsi_disk_reset(scsi_common_t *sc);
extern void scsi_disk_hard_reset(void);
extern void scsi_disk_close(void);

View File

@@ -388,9 +388,9 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit
/* Determine the DRB register to write. */
if (two_step)
drb = reg_min + row;
else
drb = reg_min + (row << 1);
else
drb = reg_min + row;
if (apollo && ((drb & 0xf) < 0xa))
drb = apollo + (drb & 0xf);

View File

@@ -653,7 +653,7 @@ msgid "ZIP images"
msgstr "ZIP 映像"
msgid "86Box could not find any usable ROM images.\n\nPlease <a href=\"https://github.com/86Box/roms/releases/latest\">download</a> a ROM set and extract it into the \"roms\" directory."
msgstr "86Box 找不到任何可用的 ROM 映像。\n\n请<a href=\"https://github.com/86Box/roms/releases/latest\">下载</a>ROM 包并将其解压到 \"roms\" 文件夹中。"
msgstr "86Box 找不到任何可用的 ROM 映像。\n\n请<a href=\"https://github.com/86Box/roms/releases/latest\">下载</a> ROM 包并将其解压到 \"roms\" 文件夹中。"
msgid "(empty)"
msgstr "(空)"

View File

@@ -144,7 +144,10 @@ int ignoreNextMouseEvent = 1;
void
RendererStack::mouseReleaseEvent(QMouseEvent *event)
{
if (this->geometry().contains(event->pos()) && (event->button() == Qt::LeftButton) && !mouse_capture && (isMouseDown & 1) && (kbd_req_capture || (mouse_get_buttons() != 0)) && (mouse_input_mode == 0)) {
if (!dopause && this->geometry().contains(event->pos()) &&
(event->button() == Qt::LeftButton) && !mouse_capture &&
(isMouseDown & 1) && (kbd_req_capture || (mouse_get_buttons() != 0)) &&
(mouse_input_mode == 0)) {
plat_mouse_capture(1);
this->setCursor(Qt::BlankCursor);
if (!ignoreNextMouseEvent)

View File

@@ -627,7 +627,7 @@ sdl_main()
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
{
if ((event.button.button == SDL_BUTTON_LEFT)
if (!dopause && (event.button.button == SDL_BUTTON_LEFT)
&& !(mouse_capture || video_fullscreen)
&& event.button.state == SDL_RELEASED
&& mouse_inside) {

View File

@@ -128,7 +128,6 @@ static void scsi_disk_command_complete(scsi_disk_t *dev);
static void scsi_disk_mode_sense_load(scsi_disk_t *dev);
static void scsi_disk_init(scsi_disk_t *dev);
static void scsi_disk_reset(scsi_common_t *sc);
#ifdef ENABLE_SCSI_DISK_LOG
int scsi_disk_do_log = ENABLE_SCSI_DISK_LOG;
@@ -787,7 +786,7 @@ scsi_disk_rezero(scsi_disk_t *dev)
scsi_disk_seek(dev, 0);
}
static void
void
scsi_disk_reset(scsi_common_t *sc)
{
scsi_disk_t *dev = (scsi_disk_t *) sc;

View File

@@ -427,7 +427,8 @@ writegus(uint16_t addr, uint8_t val, void *priv)
if (gus->voices < 14)
gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / 44100.0));
else
gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14]));
gus->samp_latch = (uint64_t) (TIMER_USEC *
(1000000.0 / gusfreqs[gus->voices - 14]));
break;
case 0x41: /*DMA*/
@@ -437,15 +438,28 @@ writegus(uint16_t addr, uint8_t val, void *priv)
while (c < 65536) {
int dma_result;
if (val & 0x04) {
uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1);
d = gus->ram[gus_addr] | (gus->ram[gus_addr + 1] << 8);
uint32_t gus_addr = (gus->dmaaddr & 0xc0000) |
((gus->dmaaddr & 0x1ffff) << 1);
if (gus_addr < gus->gus_end_ram)
d = gus->ram[gus_addr];
else
d = 0x00;
if ((gus_addr + 1) < gus->gus_end_ram)
d |= (gus->ram[gus_addr + 1] << 8);
if (val & 0x80)
d ^= 0x8080;
dma_result = dma_channel_write(gus->dma, d);
if (dma_result == DMA_NODATA)
break;
} else {
d = gus->ram[gus->dmaaddr];
if (gus->dmaaddr < gus->gus_end_ram)
d = gus->ram[gus->dmaaddr];
else
d = 0x00;
if (val & 0x80)
d ^= 0x80;
dma_result = dma_channel_write(gus->dma, d);
@@ -453,7 +467,7 @@ writegus(uint16_t addr, uint8_t val, void *priv)
break;
}
gus->dmaaddr++;
gus->dmaaddr &= 0xFFFFF;
gus->dmaaddr &= 0xfffff;
c++;
if (dma_result & DMA_OVER)
break;
@@ -467,18 +481,25 @@ writegus(uint16_t addr, uint8_t val, void *priv)
if (d == DMA_NODATA)
break;
if (val & 0x04) {
uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1);
uint32_t gus_addr = (gus->dmaaddr & 0xc0000) |
((gus->dmaaddr & 0x1ffff) << 1);
if (val & 0x80)
d ^= 0x8080;
gus->ram[gus_addr] = d & 0xff;
gus->ram[gus_addr + 1] = (d >> 8) & 0xff;
if (gus_addr < gus->gus_end_ram)
gus->ram[gus_addr] = d & 0xff;
if ((gus_addr + 1) < gus->gus_end_ram)
gus->ram[gus_addr + 1] = (d >> 8) & 0xff;
} else {
if (val & 0x80)
d ^= 0x80;
gus->ram[gus->dmaaddr] = d;
if (gus->dmaaddr < gus->gus_end_ram)
gus->ram[gus->dmaaddr] = d;
}
gus->dmaaddr++;
gus->dmaaddr &= 0xFFFFF;
gus->dmaaddr &= 0xfffff;
c++;
if (d & DMA_OVER)
break;
@@ -494,28 +515,20 @@ writegus(uint16_t addr, uint8_t val, void *priv)
break;
case 0x43: /*Address low*/
gus->addr = (gus->addr & 0xF00FF) | (val << 8);
gus->addr = (gus->addr & 0xf00ff) | (val << 8);
break;
case 0x44: /*Address high*/
gus->addr = (gus->addr & 0xFFFF) | ((val << 16) & 0xF0000);
gus->addr = (gus->addr & 0x0ffff) | ((val << 16) & 0xf0000);
break;
case 0x45: /*Timer control*/
if (!(val & 4))
gus->irqstatus &= ~4;
if (!(val & 8))
gus->irqstatus &= ~8;
if (!(val & 0x20)) {
if (!(val & 0x20))
gus->ad_status &= ~0x18;
#ifdef OLD_NMI_BEHAVIOR
nmi = 0;
#endif
}
if (!(val & 0x02)) {
if (!(val & 0x02))
gus->ad_status &= ~0x01;
#ifdef OLD_NMI_BEHAVIOR
nmi = 0;
#endif
}
gus->tctrl = val;
gus->sb_ctrl = val;
gus_update_int_status(gus);
@@ -540,7 +553,7 @@ writegus(uint16_t addr, uint8_t val, void *priv)
case 0x307: /*DRAM access*/
if (gus->addr < gus->gus_end_ram)
gus->ram[gus->addr] = val;
gus->addr &= 0xFFFFF;
gus->addr &= 0xfffff;
break;
case 0x208:
case 0x388:
@@ -874,8 +887,7 @@ readgus(uint16_t addr, void *priv)
break;
case 0x307: /*DRAM access*/
val = gus->ram[gus->addr];
gus->addr &= 0xFFFFF;
gus->addr &= 0xfffff;
if (gus->addr < gus->gus_end_ram)
val = gus->ram[gus->addr];
else
@@ -1034,21 +1046,41 @@ gus_poll_wave(void *priv)
if (gus->ctrl[d] & 4) {
addr = gus->cur[d] >> 9;
addr = (addr & 0xC0000) | ((addr << 1) & 0x3FFFE);
if (!(gus->freq[d] >> 10)) /*Interpolate*/
{
vl = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80) * (511 - (gus->cur[d] & 511));
vl += (int16_t) (int8_t) ((gus->ram[(addr + 3) & 0xFFFFF] ^ 0x80) - 0x80) * (gus->cur[d] & 511);
if (!(gus->freq[d] >> 10)) {
/* Interpolate */
if (((addr + 1) & 0xfffff) < gus->gus_end_ram)
vl = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xfffff] ^ 0x80) - 0x80) *
(511 - (gus->cur[d] & 511));
else
vl = 0;
if (((addr + 3) & 0xfffff) < gus->gus_end_ram)
vl += (int16_t) (int8_t) ((gus->ram[(addr + 3) & 0xfffff] ^ 0x80) - 0x80) *
(gus->cur[d] & 511);
v = vl >> 9;
} else
v = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80);
} else if (((addr + 1) & 0xfffff) < gus->gus_end_ram)
v = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xfffff] ^ 0x80) - 0x80);
else
v = 0x0000;
} else {
if (!(gus->freq[d] >> 10)) /*Interpolate*/
{
vl = ((int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80)) * (511 - (gus->cur[d] & 511));
vl += ((int8_t) ((gus->ram[((gus->cur[d] >> 9) + 1) & 0xFFFFF] ^ 0x80) - 0x80)) * (gus->cur[d] & 511);
if (!(gus->freq[d] >> 10)) {
/* Interpolate */
if (((gus->cur[d] >> 9) & 0xfffff) < gus->gus_end_ram)
vl = ((int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xfffff] ^ 0x80) - 0x80)) *
(511 - (gus->cur[d] & 511));
else
vl = 0;
if ((((gus->cur[d] >> 9) + 1) & 0xfffff) < gus->gus_end_ram)
vl += ((int8_t) ((gus->ram[((gus->cur[d] >> 9) + 1) & 0xfffff] ^ 0x80) - 0x80)) *
(gus->cur[d] & 511);
v = vl >> 9;
} else
v = (int16_t) (int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80);
} else if (((gus->cur[d] >> 9) & 0xfffff) < gus->gus_end_ram)
v = (int16_t) (int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xfffff] ^ 0x80) - 0x80);
else
v = 0x0000;
}
if ((gus->rcur[d] >> 14) > 4095)

View File

@@ -954,7 +954,9 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv)
Seen values: 20, 05, 04, 03
*/
sb_dsp_setdma16_enabled(&sb->dsp, !(val & 0x20));
#ifdef TOGGLABLE_TRANSLATION
sb_dsp_setdma16_translate(&sb->dsp, val & 0x02);
#endif
}
break;

View File

@@ -852,7 +852,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
s3->accel.cmd = (s3->accel.cmd & 0xff) | (val << 8);
s3->accel.ssv_state = 0;
s3_accel_start(-1, 0, 0xffffffff, 0, s3);
s3->accel.multifunc[0xe] &= ~0x10; /*hack*/
break;
case 0x994a:
@@ -887,202 +886,167 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
case 0xa148:
case 0xa2e8:
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xff00ffff) | (val << 16);
else
s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val;
s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffffff00) | val;
break;
case 0xa149:
case 0xa2e9:
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.bkgd_color = (s3->accel.bkgd_color & 0x00ffffff) | (val << 24);
else
s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8);
s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffff00ff) | (val << 8);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
break;
case 0xa14a:
case 0xa2ea:
if (s3->accel.multifunc[0xe] & 0x200)
s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16);
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16);
else
s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val;
}
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffffff00) | val;
else
s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xff00ffff) | (val << 16);
break;
case 0xa14b:
case 0xa2eb:
if (s3->accel.multifunc[0xe] & 0x200)
s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24);
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24);
else
s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffff00ff) | (val << 8);
else
s3->accel.bkgd_color = (s3->accel.bkgd_color & 0x00ffffff) | (val << 24);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
}
break;
case 0xa548:
case 0xa6e8:
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.frgd_color = (s3->accel.frgd_color & 0xff00ffff) | (val << 16);
else
s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val;
s3->accel.frgd_color = (s3->accel.frgd_color & 0xffffff00) | val;
break;
case 0xa549:
case 0xa6e9:
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.frgd_color = (s3->accel.frgd_color & 0x00ffffff) | (val << 24);
else
s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8);
s3->accel.frgd_color = (s3->accel.frgd_color & 0xffff00ff) | (val << 8);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
break;
case 0xa54a:
case 0xa6ea:
if (s3->accel.multifunc[0xe] & 0x200)
s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16);
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16);
else
s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val;
}
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.frgd_color = (s3->accel.frgd_color & 0xffffff00) | val;
else
s3->accel.frgd_color = (s3->accel.frgd_color & 0xff00ffff) | (val << 16);
break;
case 0xa54b:
case 0xa6eb:
if (s3->accel.multifunc[0xe] & 0x200)
s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24);
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24);
else
s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.frgd_color = (s3->accel.frgd_color & 0xffff00ff) | (val << 8);
else
s3->accel.frgd_color = (s3->accel.frgd_color & 0x00ffffff) | (val << 24);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
}
break;
case 0xa948:
case 0xaae8:
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xff00ffff) | (val << 16);
else
s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val;
s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffffff00) | val;
break;
case 0xa949:
case 0xaae9:
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.wrt_mask = (s3->accel.wrt_mask & 0x00ffffff) | (val << 24);
else
s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8);
s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffff00ff) | (val << 8);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
break;
case 0xa94a:
case 0xaaea:
if (s3->accel.multifunc[0xe] & 0x200)
s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16);
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16);
else
s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val;
}
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffffff00) | val;
else
s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xff00ffff) | (val << 16);
break;
case 0xa94b:
case 0xaaeb:
if (s3->accel.multifunc[0xe] & 0x200)
s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24);
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24);
else
s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffff00ff) | (val << 8);
else
s3->accel.wrt_mask = (s3->accel.wrt_mask & 0x00ffffff) | (val << 24);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
}
break;
case 0xad48:
case 0xaee8:
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.rd_mask = (s3->accel.rd_mask & 0xff00ffff) | (val << 16);
else
s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val;
s3->accel.rd_mask = (s3->accel.rd_mask & 0xffffff00) | val;
break;
case 0xad49:
case 0xaee9:
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.rd_mask = (s3->accel.rd_mask & 0x00ffffff) | (val << 24);
else
s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8);
s3->accel.rd_mask = (s3->accel.rd_mask & 0xffff00ff) | (val << 8);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
break;
case 0xad4a:
case 0xaeea:
if (s3->accel.multifunc[0xe] & 0x200)
s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16);
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16);
else
s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val;
}
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.rd_mask = (s3->accel.rd_mask & 0xffffff00) | val;
else
s3->accel.rd_mask = (s3->accel.rd_mask & 0xff00ffff) | (val << 16);
break;
case 0xad4b:
case 0xaeeb:
if (s3->accel.multifunc[0xe] & 0x200)
s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24);
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24);
else
s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.rd_mask = (s3->accel.rd_mask & 0xffff00ff) | (val << 8);
else
s3->accel.rd_mask = (s3->accel.rd_mask & 0x00ffffff) | (val << 24);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
}
break;
case 0xb148:
case 0xb2e8:
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.color_cmp = (s3->accel.color_cmp & 0xff00ffff) | (val << 16);
else
s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val;
s3->accel.color_cmp = (s3->accel.color_cmp & 0xffffff00) | val;
break;
case 0xb149:
case 0xb2e9:
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.color_cmp = (s3->accel.color_cmp & 0x00ffffff) | (val << 24);
else
s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8);
s3->accel.color_cmp = (s3->accel.color_cmp & 0xffff00ff) | (val << 8);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
break;
case 0xb14a:
case 0xb2ea:
if (s3->accel.multifunc[0xe] & 0x200)
s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16);
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16);
else
s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val;
}
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.color_cmp = (s3->accel.color_cmp & 0xffffff00) | val;
else
s3->accel.color_cmp = (s3->accel.color_cmp & 0xff00ffff) | (val << 16);
break;
case 0xb14b:
case 0xb2eb:
if (s3->accel.multifunc[0xe] & 0x200)
s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24);
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24);
else
s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.color_cmp = (s3->accel.color_cmp & 0xffff00ff) | (val << 8);
else
s3->accel.color_cmp = (s3->accel.color_cmp & 0x00ffffff) | (val << 24);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
}
break;
case 0xb548:
@@ -1115,42 +1079,35 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
break;
case 0xe548:
case 0xe6e8:
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xff00ffff) | (val << 16);
else
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val;
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffffff00) | val;
break;
case 0xe549:
case 0xe6e9:
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0x00ffffff) | (val << 24);
else
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8);
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffff00ff) | (val << 8);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
break;
case 0xe54a:
case 0xe6ea:
if (s3->accel.multifunc[0xe] & 0x200)
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16);
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16);
else
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val;
}
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffffff00) | val;
else
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xff00ffff) | (val << 16);
break;
case 0xe54b:
case 0xe6eb:
if (s3->accel.multifunc[0xe] & 0x200)
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24);
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24);
else
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffff00ff) | (val << 8);
else
s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0x00ffffff) | (val << 24);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
}
break;
case 0xe948:
case 0xeae8:
@@ -1170,42 +1127,35 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
break;
case 0xed48:
case 0xeee8:
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xff00ffff) | (val << 16);
else
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val;
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffffff00) | val;
break;
case 0xed49:
case 0xeee9:
if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0x00ffffff) | (val << 24);
else
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8);
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffff00ff) | (val << 8);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
break;
case 0xed4a:
case 0xeeea:
if (s3->accel.multifunc[0xe] & 0x200)
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16);
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16);
else
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val;
}
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffffff00) | val;
else
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xff00ffff) | (val << 16);
break;
case 0xed4b:
case 0xeeeb:
if (s3->accel.multifunc[0xe] & 0x200)
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24);
else if (s3->bpp == 3) {
if (s3->accel.multifunc[0xe] & 0x10)
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24);
else
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffff00ff) | (val << 8);
else
s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0x00ffffff) | (val << 24);
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
}
break;
case 0xe148:
@@ -3733,6 +3683,7 @@ s3_accel_in(uint16_t port, void *priv)
s3_t *s3 = (s3_t *) priv;
svga_t *svga = &s3->svga;
int temp;
uint8_t temp2;
if (!s3->enable_8514)
return 0xff;
@@ -3895,7 +3846,12 @@ s3_accel_in(uint16_t port, void *priv)
if (s3->chip >= S3_86C928) {
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.bkgd_color & 0xff;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.bkgd_color >> 16;
else
temp2 = s3->accel.bkgd_color & 0xff;
return temp2;
}
break;
case 0xa149:
@@ -3903,26 +3859,49 @@ s3_accel_in(uint16_t port, void *priv)
if (s3->chip >= S3_86C928) {
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.bkgd_color >> 8;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.bkgd_color >> 24;
else
temp2 = s3->accel.bkgd_color >> 8;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
}
break;
case 0xa14a:
case 0xa2ea:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.bkgd_color >> 16;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.bkgd_color & 0xff;
else
temp2 = s3->accel.bkgd_color >> 16;
return temp2;
case 0xa14b:
case 0xa2eb:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.bkgd_color >> 24;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.bkgd_color >> 8;
else
temp2 = s3->accel.bkgd_color >> 24;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
case 0xa548:
case 0xa6e8:
if (s3->chip >= S3_86C928) {
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.frgd_color & 0xff;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.frgd_color >> 16;
else
temp2 = s3->accel.frgd_color & 0xff;
return temp2;
}
break;
case 0xa549:
@@ -3930,26 +3909,50 @@ s3_accel_in(uint16_t port, void *priv)
if (s3->chip >= S3_86C928) {
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.frgd_color >> 8;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.frgd_color >> 24;
else
temp2 = s3->accel.frgd_color >> 8;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
}
break;
case 0xa54a:
case 0xa6ea:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.frgd_color >> 16;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.frgd_color & 0xff;
else
temp2 = s3->accel.frgd_color >> 16;
return temp2;
case 0xa54b:
case 0xa6eb:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.frgd_color >> 24;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.frgd_color >> 8;
else
temp2 = s3->accel.frgd_color >> 24;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
case 0xa948:
case 0xaae8:
if (s3->chip >= S3_86C928) {
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.wrt_mask & 0xff;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.wrt_mask >> 16;
else
temp2 = s3->accel.wrt_mask & 0xff;
return temp2;
}
break;
case 0xa949:
@@ -3957,50 +3960,101 @@ s3_accel_in(uint16_t port, void *priv)
if (s3->chip >= S3_86C928) {
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.wrt_mask >> 8;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.wrt_mask >> 24;
else
temp2 = s3->accel.wrt_mask >> 8;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
}
break;
case 0xa94a:
case 0xaaea:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.wrt_mask >> 16;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.wrt_mask & 0xff;
else
temp2 = s3->accel.wrt_mask >> 16;
return temp2;
case 0xa94b:
case 0xaaeb:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.wrt_mask >> 24;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.wrt_mask >> 8;
else
temp2 = s3->accel.wrt_mask >> 24;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
case 0xad48:
case 0xaee8:
if (s3->chip >= S3_86C928) {
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.rd_mask & 0xff;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.rd_mask >> 16;
else
temp2 = s3->accel.rd_mask & 0xff;
return temp2;
}
break;
case 0xad49:
case 0xaee9:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.rd_mask >> 8;
if (s3->chip >= S3_86C928) {
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.rd_mask >> 24;
else
temp2 = s3->accel.rd_mask >> 8;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
}
break;
case 0xad4a:
case 0xaeea:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.rd_mask >> 16;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.rd_mask & 0xff;
else
temp2 = s3->accel.rd_mask >> 16;
return temp2;
case 0xad4b:
case 0xaeeb:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.rd_mask >> 24;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.rd_mask >> 8;
else
temp2 = s3->accel.rd_mask >> 24;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
case 0xb148:
case 0xb2e8:
if (s3->chip >= S3_86C928) {
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.color_cmp & 0xff;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.color_cmp >> 16;
else
temp2 = s3->accel.color_cmp & 0xff;
return temp2;
}
break;
case 0xb149:
@@ -4008,19 +4062,38 @@ s3_accel_in(uint16_t port, void *priv)
if (s3->chip >= S3_86C928) {
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.color_cmp >> 8;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.color_cmp >> 24;
else
temp2 = s3->accel.color_cmp >> 8;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
}
break;
case 0xb14a:
case 0xb2ea:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.color_cmp >> 16;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.color_cmp & 0xff;
else
temp2 = s3->accel.color_cmp >> 16;
return temp2;
case 0xb14b:
case 0xb2eb:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.color_cmp >> 24;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.color_cmp >> 8;
else
temp2 = s3->accel.color_cmp >> 24;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
case 0xb548:
case 0xb6e8:
@@ -4130,25 +4203,49 @@ s3_accel_in(uint16_t port, void *priv)
case 0xe6e8:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.pat_bg_color & 0xff;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_bg_color >> 16;
else
temp2 = s3->accel.pat_bg_color & 0xff;
return temp2;
case 0xe549:
case 0xe6e9:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.pat_bg_color >> 8;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_bg_color >> 24;
else
temp2 = s3->accel.pat_bg_color >> 8;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
case 0xe54a:
case 0xe6ea:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.pat_bg_color >> 16;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_bg_color & 0xff;
else
temp2 = s3->accel.pat_bg_color >> 16;
return temp2;
case 0xe54b:
case 0xe6eb:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.pat_bg_color >> 24;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_bg_color >> 8;
else
temp2 = s3->accel.pat_bg_color >> 24;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
case 0xe948:
case 0xeae8:
@@ -4178,25 +4275,49 @@ s3_accel_in(uint16_t port, void *priv)
case 0xeee8:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.pat_fg_color & 0xff;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_fg_color >> 16;
else
temp2 = s3->accel.pat_fg_color & 0xff;
return temp2;
case 0xed49:
case 0xeee9:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.pat_fg_color >> 8;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_fg_color >> 24;
else
temp2 = s3->accel.pat_fg_color >> 8;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
case 0xed4a:
case 0xeeea:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.pat_fg_color >> 16;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_fg_color & 0xff;
else
temp2 = s3->accel.pat_fg_color >> 16;
return temp2;
case 0xed4b:
case 0xeeeb:
if (s3_enable_fifo(s3))
s3_wait_fifo_idle(s3);
return s3->accel.pat_fg_color >> 24;
if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200))
temp2 = s3->accel.pat_fg_color >> 8;
else
temp2 = s3->accel.pat_fg_color >> 24;
if (!(s3->accel.multifunc[0xe] & 0x200))
s3->accel.multifunc[0xe] ^= 0x10;
return temp2;
case 0xe148:
case 0xe2e8:
@@ -6182,21 +6303,20 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
uint32_t srcbase;
uint32_t dstbase;
if ((s3->chip >= S3_TRIO64 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (s3->accel.cmd & (1 << 11))) {
if ((s3->chip >= S3_TRIO64 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (s3->accel.cmd & (1 << 11)))
cmd |= 8;
}
// SRC-BASE/DST-BASE
if ((s3->accel.multifunc[0xd] >> 4) & 7) {
if ((s3->accel.multifunc[0xd] >> 4) & 7)
srcbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 4) & 3);
} else {
else
srcbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 2) & 3);
}
if ((s3->accel.multifunc[0xd] >> 0) & 7) {
if ((s3->accel.multifunc[0xd] >> 0) & 7)
dstbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 0) & 3);
} else {
else
dstbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 0) & 3);
}
if (s3->bpp == 1) {
srcbase >>= 1;
dstbase >>= 1;
@@ -6205,9 +6325,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
dstbase >>= 2;
}
if ((s3->accel.cmd & 0x100) && (s3_cpu_src(s3) || (s3_cpu_dest(s3))) && (!cpu_input || (s3_enable_fifo(s3) == 0))) {
if ((s3->accel.cmd & 0x100) && (s3_cpu_src(s3) || (s3_cpu_dest(s3))) && (!cpu_input || (s3_enable_fifo(s3) == 0)))
s3->force_busy = 1;
}
if (!cpu_input)
s3->accel.dat_count = 0;
@@ -6225,7 +6344,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
}
if ((s3->bpp == 1) || s3->color_16bit)
count >>= 1;
if (s3->bpp == 3)
else if (s3->bpp == 3)
count >>= 2;
}
@@ -6236,7 +6355,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_
if ((s3->bpp == 0) && !s3->color_16bit)
compare &= 0xff;
if ((s3->bpp == 1) || s3->color_16bit)
else if ((s3->bpp == 1) || s3->color_16bit)
compare &= 0xffff;
switch (s3->accel.cmd & 0x600) {