PCI and IRQ rework, pci.c rewritten from ground up, fixes numerous issues such as the bridge being added when the number of normal PCI devices equals the number of normal PCI slots, Windows 95 PCI operation on Intel 430NX, sharing of PCI IRQ's with non-PCI level-triggered devices, having both configuration mechanisms operating at the same time (ALi M1435), etc., and makes the code much more readable.

This commit is contained in:
OBattler
2023-08-07 03:04:52 +02:00
parent cb24ee27cb
commit c30d5d90b7
66 changed files with 1824 additions and 1643 deletions

View File

@@ -1048,19 +1048,9 @@ pc_reset_hard_init(void)
/* Initialize the actual machine and its basic modules. */
machine_init();
/* Reset and reconfigure the serial ports. */
serial_standalone_init();
serial_passthrough_init();
/* Reset and reconfigure the Sound Card layer. */
sound_card_reset();
/* Reset any ISA RTC cards. */
isartc_reset();
fdc_card_init();
fdd_reset();
/* Reset some basic devices. */
speaker_init();
shadowbios = 0;
/*
* Once the machine has been initialized, all that remains
@@ -1071,38 +1061,49 @@ pc_reset_hard_init(void)
* that will be a call to device_reset_all() later !
*/
/* Reset some basic devices. */
speaker_init();
lpt_devices_init();
shadowbios = 0;
/*
* Reset the mouse, this will attach it to any port needed.
*/
mouse_reset();
if (joystick_type)
gameport_update_joystick_type();
/* Reset and reconfigure the Sound Card layer. */
sound_card_reset();
/* Reset and reconfigure the Network Card layer. */
network_reset();
lpt_devices_init();
/* Reset and reconfigure the serial ports. */
serial_standalone_init();
serial_passthrough_init();
/* Reset the Hard Disk Controller module. */
hdc_reset();
fdc_card_init();
fdd_reset();
/* Reset the CD-ROM Controller module. */
cdrom_interface_reset();
/* Reset and reconfigure the SCSI layer. */
scsi_card_init();
cdrom_hard_reset();
scsi_disk_hard_reset();
zip_hard_reset();
cdrom_hard_reset();
mo_hard_reset();
scsi_disk_hard_reset();
zip_hard_reset();
/* Reset and reconfigure the Network Card layer. */
network_reset();
if (joystick_type)
gameport_update_joystick_type();
/* Reset any ISA RTC cards. */
isartc_reset();
ui_sb_update_panes();
@@ -1119,6 +1120,11 @@ pc_reset_hard_init(void)
if (postcard_enabled)
device_add(&postcard_device);
if (IS_ARCH(machine, MACHINE_BUS_PCI)) {
pci_register_cards();
device_reset_all(DEVICE_PCI);
}
/* Reset the CPU module. */
resetx86();
dma_reset();

View File

@@ -124,29 +124,29 @@ acpi_update_irq(acpi_t *dev)
if (sci_level) {
if (dev->irq_mode == 1)
pci_set_irq(dev->slot, dev->irq_pin);
pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state);
else if (dev->irq_mode == 2)
pci_set_mirq(5, dev->mirq_is_level);
pci_set_mirq(5, dev->mirq_is_level, &dev->irq_state);
else
pci_set_mirq(0xf0 | dev->irq_line, 1);
pci_set_mirq(PCI_DIRQ_BASE | dev->irq_line, 1, &dev->irq_state);
} else {
if (dev->irq_mode == 1)
pci_clear_irq(dev->slot, dev->irq_pin);
pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state);
else if (dev->irq_mode == 2)
pci_clear_mirq(5, dev->mirq_is_level);
pci_clear_mirq(5, dev->mirq_is_level, &dev->irq_state);
else
pci_clear_mirq(0xf0 | dev->irq_line, 1);
pci_clear_mirq(PCI_DIRQ_BASE | dev->irq_line, 1, &dev->irq_state);
}
acpi_timer_update(dev, (dev->regs.pmen & TMROF_EN) && !(dev->regs.pmsts & TMROF_STS));
}
void
acpi_raise_smi(void *priv, int do_smi)
static void
acpi_do_raise_smi(void *priv, int do_smi, int is_apm)
{
acpi_t *dev = (acpi_t *) priv;
if (dev->regs.glbctl & 0x01) {
if (is_apm || (dev->regs.glbctl & 0x01)) {
if ((dev->vendor == VEN_VIA) || (dev->vendor == VEN_VIA_596B)) {
if (!dev->regs.smi_lock || !dev->regs.smi_active) {
if (do_smi)
@@ -168,6 +168,12 @@ acpi_raise_smi(void *priv, int do_smi)
}
}
void
acpi_raise_smi(void *priv, int do_smi)
{
acpi_do_raise_smi(priv, do_smi, 0);
}
static uint32_t
acpi_reg_read_common_regs(UNUSED(int size), uint16_t addr, void *priv)
{
@@ -1582,7 +1588,7 @@ acpi_apm_out(uint16_t port, uint8_t val, void *priv)
dev->apm->cmd = val;
if (dev->vendor == VEN_INTEL)
dev->regs.glbsts |= 0x20;
acpi_raise_smi(dev, dev->apm->do_smi);
acpi_do_raise_smi(dev, dev->apm->do_smi, 1);
} else
dev->apm->stat = val;
}
@@ -1657,6 +1663,9 @@ acpi_reset(void *priv)
dev->regs.pmsts |= 0x8000;
acpi_rtc_status = 0;
acpi_update_irq(dev);
dev->irq_state = 0;
}
static void

View File

@@ -46,11 +46,12 @@
typedef struct ali_1435_t {
uint8_t index;
uint8_t cfg_locked;
uint8_t pci_slot;
uint8_t pad;
uint8_t regs[16];
uint8_t pci_regs[256];
} ali1435_t;
#define ENABLE_ALI1435_LOG 1
#ifdef ENABLE_ALI1435_LOG
int ali1435_do_log = ENABLE_ALI1435_LOG;
@@ -190,24 +191,20 @@ ali1435_write(uint16_t addr, uint8_t val, void *priv)
break;
case 0x23:
#if 0
#ifdef ENABLE_ALI1435_LOG
if (dev->index != 0x03)
ali1435_log("M1435: dev->regs[%02x] = %02x\n", dev->index, val);
#endif
#endif
if (dev->index == 0x03)
dev->cfg_locked = (val != 0x69);
#ifdef ENABLE_ALI1435_LOG
else
ali1435_log("M1435: dev->regs[%02x] = %02x\n", dev->index, val);
#endif
if (!dev->cfg_locked) {
pclog("M1435: dev->regs[%02x] = %02x\n", dev->index, val);
switch (dev->index) {
/* PCI Mechanism select? */
case 0x00:
dev->regs[dev->index] = val;
pclog("PMC = %i\n", val != 0xc8);
pci_set_pmc(val != 0xc8);
ali1435_log("PMC = %i\n", val != 0xc8);
pci_key_write(((val & 0xc8) == 0xc8) ? 0xf0 : 0x00);
break;
/* ???? */
@@ -253,8 +250,6 @@ ali1435_reset(void *priv)
dev->regs[0x00] = 0xff;
pci_set_pmc(0);
dev->cfg_locked = 1;
memset(dev->pci_regs, 0, 256);
@@ -298,17 +293,10 @@ ali1435_init(UNUSED(const device_t *info))
*/
io_sethandler(0x0022, 0x0002, ali1435_read, NULL, NULL, ali1435_write, NULL, NULL, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1435_pci_read, ali1435_pci_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1435_pci_read, ali1435_pci_write, dev, &dev->pci_slot);
ali1435_reset(dev);
#if 0
pci_set_irq_level(PCI_INTA, 0);
pci_set_irq_level(PCI_INTB, 0);
pci_set_irq_level(PCI_INTC, 0);
pci_set_irq_level(PCI_INTD, 0);
#endif
return dev;
}

View File

@@ -622,7 +622,7 @@ ali1489_init(UNUSED(const device_t *info))
io_sethandler(0x0fc, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev);
/* Dummy M1489 PCI device */
dev->pci_slot = pci_add_card(PCI_ADD_NORTHBRIDGE, ali1489_pci_read, ali1489_pci_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1489_pci_read, ali1489_pci_write, dev, &dev->pci_slot);
device_add(&ide_pci_2ch_device);

View File

@@ -35,6 +35,11 @@
#include <86box/chipset.h>
typedef struct ali1531_t {
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pad1;
uint8_t pci_conf[256];
smram_t *smram;
@@ -374,7 +379,7 @@ ali1531_init(UNUSED(const device_t *info))
ali1531_t *dev = (ali1531_t *) malloc(sizeof(ali1531_t));
memset(dev, 0, sizeof(ali1531_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1531_read, ali1531_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1531_read, ali1531_write, dev, &dev->pci_slot);
dev->smram = smram_add();

View File

@@ -35,6 +35,11 @@
#include <86box/chipset.h>
typedef struct ali1541_t {
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pad1;
uint8_t pci_conf[256];
smram_t *smram;
@@ -641,7 +646,7 @@ ali1541_init(UNUSED(const device_t *info))
ali1541_t *dev = (ali1541_t *) malloc(sizeof(ali1541_t));
memset(dev, 0, sizeof(ali1541_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1541_read, ali1541_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1541_read, ali1541_write, dev, &dev->pci_slot);
dev->smram = smram_add();

View File

@@ -47,6 +47,7 @@
#include <86box/chipset.h>
typedef struct ali1543_t {
uint8_t mirq_states[8];
uint8_t pci_conf[256];
uint8_t pmu_conf[256];
uint8_t usb_conf[256];
@@ -1474,12 +1475,12 @@ ali7101_read(int func, int addr, void *priv)
static void
ali5237_usb_update_interrupt(usb_t* usb, void *priv)
{
const ali1543_t *dev = (ali1543_t *) priv;
ali1543_t *dev = (ali1543_t *) priv;
if (usb->irq_level)
pci_set_mirq(4, !!(dev->pci_conf[0x74] & 0x10));
pci_set_mirq(4, !!(dev->pci_conf[0x74] & 0x10), &dev->mirq_states[4]);
else
pci_clear_mirq(4, !!(dev->pci_conf[0x74] & 0x10));
pci_clear_mirq(4, !!(dev->pci_conf[0x74] & 0x10), &dev->mirq_states[4]);
}
static void
@@ -1595,16 +1596,16 @@ ali1543_init(const device_t *info)
memset(dev, 0, sizeof(ali1543_t));
/* Device 02: M1533 Southbridge */
dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali1533_read, ali1533_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE, ali1533_read, ali1533_write, dev, &dev->pci_slot);
/* Device 0B: M5229 IDE Controller*/
dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, ali5229_read, ali5229_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, ali5229_read, ali5229_write, dev, &dev->ide_slot);
/* Device 0C: M7101 Power Managment Controller */
dev->pmu_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_PMU, ali7101_read, ali7101_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE_PMU, ali7101_read, ali7101_write, dev, &dev->pmu_slot);
/* Device 0F: M5237 USB */
dev->usb_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, ali5237_read, ali5237_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, ali5237_read, ali5237_write, dev, &dev->usb_slot);
/* ACPI */
dev->acpi = device_add(&acpi_ali_device);

View File

@@ -36,6 +36,11 @@
#include <86box/chipset.h>
typedef struct ali1621_t {
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pad1;
uint8_t pci_conf[256];
smram_t *smram[2];
@@ -671,7 +676,7 @@ ali1621_init(UNUSED(const device_t *info))
ali1621_t *dev = (ali1621_t *) malloc(sizeof(ali1621_t));
memset(dev, 0, sizeof(ali1621_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev, &dev->pci_slot);
dev->smram[0] = smram_add();
dev->smram[1] = smram_add();

View File

@@ -122,6 +122,9 @@
typedef struct ims8848_t {
uint8_t idx;
uint8_t access_data;
uint8_t pci_slot;
uint8_t pad;
uint8_t regs[256];
uint8_t pci_conf[256];
@@ -392,7 +395,7 @@ ims8848_init(UNUSED(const device_t *info))
PCI Device 0: IMS 8849 Dummy for compatibility reasons
*/
io_sethandler(0x0022, 0x0003, ims8848_read, NULL, NULL, ims8848_write, NULL, NULL, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ims8849_pci_read, ims8849_pci_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ims8849_pci_read, ims8849_pci_write, dev, &dev->pci_slot);
dev->smram = smram_add();
smram_set_separate_smram(1);

View File

@@ -52,6 +52,9 @@
typedef struct i420ex_t {
uint8_t has_ide;
uint8_t smram_locked;
uint8_t pci_slot;
uint8_t pad;
uint8_t regs[256];
uint16_t timer_base;
@@ -534,7 +537,7 @@ i420ex_init(const device_t *info)
dev->smram = smram_add();
pci_add_card(PCI_ADD_NORTHBRIDGE, i420ex_read, i420ex_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, i420ex_read, i420ex_write, dev, &dev->pci_slot);
dev->has_ide = info->local;

View File

@@ -57,6 +57,9 @@ typedef struct i4x0_t {
uint8_t max_drb;
uint8_t drb_unit;
uint8_t drb_default;
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t regs[256];
uint8_t regs_locked[256];
uint8_t mem_state[256];
@@ -1241,12 +1244,12 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
switch (dev->type) {
case INTEL_440FX:
regs[0x93] = (val & 0x0f);
trc_write(0x0093, val & 0x06, NULL);
pci_write(0x0cf9, val & 0x06, NULL);
break;
case INTEL_440LX:
case INTEL_440EX:
regs[0x93] = (val & 0x0e);
trc_write(0x0093, val & 0x06, NULL);
pci_write(0x0cf9, val & 0x06, NULL);
break;
default:
break;
@@ -1518,7 +1521,7 @@ i4x0_read(int func, int addr, void *priv)
/* Special behavior for 440FX register 0x93 which is basically TRC in PCI space
with the addition of bits 3 and 0. */
if ((func == 0) && (addr == 0x93) && ((dev->type == INTEL_440FX) || (dev->type == INTEL_440LX) || (dev->type == INTEL_440EX)))
ret = (ret & 0xf9) | (trc_read(0x0093, NULL) & 0x06);
ret = (ret & 0xf9) | (pci_read(0x0cf9, NULL) & 0x06);
}
return ret;
@@ -1910,7 +1913,7 @@ i4x0_init(const device_t *info)
(dev->type >= INTEL_440BX) ? 0x38 : 0x00, dev);
}
pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev, &dev->pci_slot);
if ((dev->type >= INTEL_440BX) && !(regs[0x7a] & 0x02)) {
device_add((dev->type == INTEL_440GX) ? &i440gx_agp_device : &i440bx_agp_device);

View File

@@ -62,11 +62,15 @@ i450kx_log(const char *fmt, ...)
typedef struct i450kx_t {
smram_t *smram[2];
uint8_t bus_index;
uint8_t pb_slot;
uint8_t mc_slot;
uint8_t pad;
uint8_t pb_pci_conf[256];
uint8_t mc_pci_conf[256];
uint8_t mem_state[2][256];
uint8_t bus_index;
uint8_t mem_state[2][256];
} i450kx_t;
static void
@@ -801,8 +805,8 @@ i450kx_init(UNUSED(const device_t *info))
{
i450kx_t *dev = (i450kx_t *) malloc(sizeof(i450kx_t));
memset(dev, 0, sizeof(i450kx_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev); /* Device 19h: Intel 450KX PCI Bridge PB */
pci_add_card(PCI_ADD_AGPBRIDGE, mc_read, mc_write, dev); /* Device 14h: Intel 450KX Memory Controller MC */
pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev, &dev->pb_slot); /* Device 19h: Intel 450KX PCI Bridge PB */
pci_add_card(PCI_ADD_NORTHBRIDGE_SEC, mc_read, mc_write, dev, &dev->mc_slot); /* Device 14h: Intel 450KX Memory Controller MC */
dev->smram[0] = smram_add();
dev->smram[1] = smram_add();

View File

@@ -66,7 +66,7 @@ typedef struct _piix_ {
uint8_t max_func;
uint8_t pci_slot;
uint8_t no_mirq0;
uint8_t pad;
uint8_t usb_irq_state;
uint8_t regs[4][256];
uint8_t readout_regs[256];
uint8_t board_config[2];
@@ -1446,12 +1446,12 @@ piix_fast_off_count(void *priv)
static void
piix_usb_update_interrupt(usb_t* usb, void *priv)
{
const piix_t *dev = (piix_t *) priv;
piix_t *dev = (piix_t *) priv;
if (usb->irq_level)
pci_set_irq(dev->pci_slot, PCI_INTD);
pci_set_irq(dev->pci_slot, PCI_INTD, &dev->usb_irq_state);
else
pci_clear_irq(dev->pci_slot, PCI_INTD);
pci_clear_irq(dev->pci_slot, PCI_INTD, &dev->usb_irq_state);
}
static void
@@ -1574,7 +1574,7 @@ piix_init(const device_t *info)
dev->no_mirq0 = (info->local >> 12) & 0x0f;
dev->func0_id = info->local >> 16;
dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, piix_read, piix_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE, piix_read, piix_write, dev, &dev->pci_slot);
piix_log("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot);
piix_log("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot);

View File

@@ -37,6 +37,10 @@
typedef struct sio_t {
uint8_t id;
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t regs[256];
uint16_t timer_base;
@@ -507,7 +511,7 @@ sio_init(const device_t *info)
sio_t *dev = (sio_t *) malloc(sizeof(sio_t));
memset(dev, 0, sizeof(sio_t));
pci_add_card(PCI_ADD_SOUTHBRIDGE, sio_read, sio_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE, sio_read, sio_write, dev, &dev->pci_slot);
dev->id = info->local;

View File

@@ -43,6 +43,10 @@
typedef struct opti822_t {
uint8_t irq_convert;
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pci_regs[256];
} opti822_t;
@@ -393,7 +397,7 @@ opti822_init(UNUSED(const device_t *info))
opti822_t *dev = (opti822_t *) malloc(sizeof(opti822_t));
memset(dev, 0, sizeof(opti822_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_pci_read, opti822_pci_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_pci_read, opti822_pci_write, dev, &dev->pci_slot);
opti822_reset(dev);

View File

@@ -66,13 +66,15 @@ sis_5511_log(const char *fmt, ...)
#endif
typedef struct sis_5511_t {
uint8_t pci_conf[256];
uint8_t pci_conf_sb[2][256];
uint8_t index;
uint8_t nb_slot;
uint8_t sb_slot;
uint8_t pad;
uint8_t regs[16];
int nb_pci_slot;
int sb_pci_slot;
uint8_t pci_conf[256];
uint8_t pci_conf_sb[2][256];
sff8038i_t *ide_drive[2];
smram_t *smram;
@@ -713,8 +715,8 @@ sis_5511_reset(void *priv)
dev->pci_conf_sb[1][0x0a] = 1;
dev->pci_conf_sb[1][0x0b] = 1;
dev->pci_conf_sb[1][0x0e] = 0x80;
sff_set_slot(dev->ide_drive[0], dev->sb_pci_slot);
sff_set_slot(dev->ide_drive[1], dev->sb_pci_slot);
sff_set_slot(dev->ide_drive[0], dev->sb_slot);
sff_set_slot(dev->ide_drive[1], dev->sb_slot);
sff_bus_master_reset(dev->ide_drive[0], BUS_MASTER_BASE);
sff_bus_master_reset(dev->ide_drive[1], BUS_MASTER_BASE + 8);
}
@@ -734,8 +736,8 @@ sis_5511_init(UNUSED(const device_t *info))
sis_5511_t *dev = (sis_5511_t *) malloc(sizeof(sis_5511_t));
memset(dev, 0, sizeof(sis_5511_t));
dev->nb_pci_slot = pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev); /* Device 0: SiS 5511 */
dev->sb_pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev); /* Device 1: SiS 5513 */
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev, &dev->nb_slot); /* Device 0: SiS 5511 */
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev, &dev->sb_slot); /* Device 1: SiS 5513 */
io_sethandler(0x0022, 0x0002, sis_5513_isa_read, NULL, NULL, sis_5513_isa_write, NULL, NULL, dev); /* Ports 22h-23h: SiS 5513 ISA */
/* MIRQ */

View File

@@ -75,12 +75,14 @@ sis_5571_log(const char *fmt, ...)
#endif
typedef struct sis_5571_t {
uint8_t nb_slot;
uint8_t sb_slot;
uint8_t pad;
uint8_t usb_irq_state;
uint8_t pci_conf[256];
uint8_t pci_conf_sb[3][256];
int nb_pci_slot;
int sb_pci_slot;
port_92_t *port_92;
sff8038i_t *ide_drive[2];
smram_t *smram;
@@ -670,7 +672,7 @@ pci_isa_bridge_read(int func, int addr, void *priv)
static void
sis_5571_usb_update_interrupt(usb_t* usb, void* priv)
{
const sis_5571_t *dev = (sis_5571_t *) priv;
sis_5571_t *dev = (sis_5571_t *) priv;
if (dev->pci_conf_sb[0][0x68] & 0x80) {
/* TODO: Is the normal PCI interrupt inhibited when USB IRQ remapping is enabled? */
@@ -691,9 +693,9 @@ sis_5571_usb_update_interrupt(usb_t* usb, void* priv)
}
} else {
if (usb->irq_level)
pci_set_irq(dev->sb_pci_slot, PCI_INTA);
pci_set_irq(dev->sb_slot, PCI_INTA, &dev->usb_irq_state);
else
pci_clear_irq(dev->sb_pci_slot, PCI_INTA);
pci_clear_irq(dev->sb_slot, PCI_INTA, &dev->usb_irq_state);
}
}
@@ -739,8 +741,8 @@ sis_5571_reset(void *priv)
dev->pci_conf_sb[1][0x0b] = 0x01;
dev->pci_conf_sb[1][0x0e] = 0x80;
dev->pci_conf_sb[1][0x4a] = 0x06;
sff_set_slot(dev->ide_drive[0], dev->sb_pci_slot);
sff_set_slot(dev->ide_drive[1], dev->sb_pci_slot);
sff_set_slot(dev->ide_drive[0], dev->sb_slot);
sff_set_slot(dev->ide_drive[1], dev->sb_slot);
sff_bus_master_reset(dev->ide_drive[0], BUS_MASTER_BASE);
sff_bus_master_reset(dev->ide_drive[1], BUS_MASTER_BASE + 8);
@@ -773,8 +775,8 @@ sis_5571_init(UNUSED(const device_t *info))
sis_5571_t *dev = (sis_5571_t *) malloc(sizeof(sis_5571_t));
memset(dev, 0x00, sizeof(sis_5571_t));
dev->nb_pci_slot = pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev);
dev->sb_pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev, &dev->nb_slot);
pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev, &dev->sb_slot);
/* MIRQ */
pci_enable_mirq(0);

View File

@@ -45,9 +45,13 @@
typedef struct sis_85c496_t {
uint8_t cur_reg;
uint8_t rmsmiblk_count;
uint8_t pci_slot;
uint8_t pad;
#ifndef USE_DRB_HACK
uint8_t drb_default;
uint8_t drb_bits;
uint8_t pad0;
uint8_t pad1;
#endif
uint8_t regs[127];
uint8_t pci_conf[256];
@@ -648,7 +652,7 @@ static void
dev->pci_conf[0xd0] = 0x78; /* ROM at E0000-FFFFF, Flash enable. */
dev->pci_conf[0xd1] = 0xff;
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c49x_pci_read, sis_85c49x_pci_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c49x_pci_read, sis_85c49x_pci_write, dev, &dev->pci_slot);
#if 0
sis_85c497_isa_reset(dev);

View File

@@ -59,6 +59,10 @@ sis_85c50x_log(const char *fmt, ...)
typedef struct sis_85c50x_t {
uint8_t index;
uint8_t nb_slot;
uint8_t sb_slot;
uint8_t pad;
uint8_t pci_conf[256];
uint8_t pci_conf_sb[256];
uint8_t regs[256];
@@ -426,10 +430,10 @@ sis_85c50x_init(UNUSED(const device_t *info))
memset(dev, 0x00, sizeof(sis_85c50x_t));
/* 501/502 (Northbridge) */
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c50x_read, sis_85c50x_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c50x_read, sis_85c50x_write, dev, &dev->nb_slot);
/* 503 (Southbridge) */
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_85c50x_sb_read, sis_85c50x_sb_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_85c50x_sb_read, sis_85c50x_sb_write, dev, &dev->sb_slot);
io_sethandler(0x0022, 0x0002, sis_85c50x_isa_read, NULL, NULL, sis_85c50x_isa_write, NULL, NULL, dev);
dev->smram[0] = smram_add();

View File

@@ -45,6 +45,11 @@
#define STPC_CLIENT 0x100e55cc
typedef struct stpc_t {
uint8_t nb_slot;
uint8_t sb_slot;
uint8_t ide_slot;
uint8_t usb_slot;
uint32_t local;
/* Main registers (port 22h/23h) */
@@ -54,19 +59,19 @@ typedef struct stpc_t {
/* Host bus interface */
uint16_t host_base;
uint8_t host_offset;
uint8_t usb_irq_state;
uint8_t host_regs[256];
/* Local bus */
uint16_t localbus_base;
uint8_t localbus_offset;
uint8_t pad0;
uint8_t localbus_regs[256];
/* PCI devices */
uint8_t pci_conf[4][256];
smram_t *smram;
usb_t *usb;
int ide_slot;
int usb_slot;
sff8038i_t *bm[2];
/* Miscellaneous */
@@ -896,12 +901,12 @@ stpc_setup(stpc_t *dev)
static void
stpc_usb_update_interrupt(usb_t* usb, void* priv)
{
const stpc_t *dev = (stpc_t *) priv;
stpc_t *dev = (stpc_t *) priv;
if (usb->irq_level)
pci_set_irq(dev->usb_slot, PCI_INTA);
pci_set_irq(dev->usb_slot, PCI_INTA, &dev->usb_irq_state);
else
pci_clear_irq(dev->usb_slot, PCI_INTA);
pci_clear_irq(dev->usb_slot, PCI_INTA, &dev->usb_irq_state);
}
static void
@@ -926,16 +931,16 @@ stpc_init(const device_t *info)
dev->local = info->local;
pci_add_card(PCI_ADD_NORTHBRIDGE, stpc_nb_read, stpc_nb_write, dev);
dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_isab_read, stpc_isab_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, stpc_nb_read, stpc_nb_write, dev, &dev->nb_slot);
pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_isab_read, stpc_isab_write, dev, &dev->sb_slot);
if (dev->local == STPC_ATLAS) {
dev->usb_params.smi_handle = NULL;
dev->usb_params.update_interrupt = stpc_usb_update_interrupt;
dev->usb_params.parent_priv = dev;
dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_ide_read, stpc_ide_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, stpc_ide_read, stpc_ide_write, dev, &dev->ide_slot);
dev->usb = device_add_parameters(&usb_device, &dev->usb_params);
dev->usb_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_usb_read, stpc_usb_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, stpc_usb_read, stpc_usb_write, dev, &dev->usb_slot);
}
dev->bm[0] = device_add_inst(&sff8038i_device, 1);

View File

@@ -121,8 +121,13 @@ umc_8886_log(const char *fmt, ...)
#define SB_ID dev->sb_id
typedef struct umc_8886_t {
uint8_t max_func; /* Last function number */
uint8_t pci_conf_sb[2][256]; /* PCI Registers */
uint8_t max_func; /* Last function number */
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pci_conf_sb[2][256]; /* PCI Registers */
uint16_t sb_id; /* Southbridge Revision */
int has_ide; /* Check if Southbridge Revision is AF or F */
} umc_8886_t;
@@ -371,7 +376,7 @@ umc_8886_init(const device_t *info)
memset(dev, 0, sizeof(umc_8886_t));
dev->has_ide = !!(info->local == 0x886a);
pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev); /* Device 12: UMC 8886xx */
pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev, &dev->pci_slot); /* Device 12: UMC 8886xx */
/* Add IDE if UM8886AF variant */
if (HAS_IDE)

View File

@@ -146,6 +146,8 @@ typedef struct hb4_t {
uint8_t shadow;
uint8_t shadow_read;
uint8_t shadow_write;
uint8_t pci_slot;
uint8_t pci_conf[256]; /* PCI Registers */
int mem_state[9];
smram_t *smram[3]; /* SMRAM Handlers */
@@ -393,7 +395,7 @@ hb4_init(UNUSED(const device_t *info))
hb4_t *dev = (hb4_t *) malloc(sizeof(hb4_t));
memset(dev, 0, sizeof(hb4_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, hb4_read, hb4_write, dev); /* Device 10: UMC 8881x */
pci_add_card(PCI_ADD_NORTHBRIDGE, hb4_read, hb4_write, dev, &dev->pci_slot); /* Device 10: UMC 8881x */
/* Port 92 */
device_add(&port_92_pci_device);

View File

@@ -45,10 +45,15 @@
#define VIA_8601 0x86010500
typedef struct via_apollo_t {
uint32_t id;
uint8_t drb_unit;
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pci_conf[256];
uint32_t id;
smram_t *smram;
agpgart_t *agpgart;
} via_apollo_t;
@@ -715,7 +720,7 @@ via_apollo_init(const device_t *info)
if (dev->id != VIA_8601)
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
pci_add_card(PCI_ADD_NORTHBRIDGE, via_apollo_read, via_apollo_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, via_apollo_read, via_apollo_write, dev, &dev->pci_slot);
dev->id = info->local;

View File

@@ -117,9 +117,10 @@ typedef struct {
} pipc_io_trap_t;
typedef struct _pipc_ {
uint32_t local;
uint8_t max_func;
uint8_t max_pcs;
uint8_t pci_slot;
uint8_t pad;
uint8_t pci_isa_regs[256];
uint8_t ide_regs[256];
@@ -129,10 +130,11 @@ typedef struct _pipc_ {
uint8_t fmnmi_regs[4];
uint8_t fmnmi_status;
uint32_t local;
sff8038i_t *bm[2];
nvr_t *nvr;
int nvr_enabled;
int slot;
ddma_t *ddma;
smbus_piix4_t *smbus;
usb_t *usb[2];
@@ -1094,7 +1096,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
case 0x47:
if (val & 0x01)
trc_write(0x0047, (val & 0x80) ? 0x06 : 0x04, NULL);
pci_write(0x0cf9, (val & 0x80) ? 0x06 : 0x04, NULL);
pic_set_shadow(!!(val & 0x10));
pic_elcr_io_handler(!!(val & 0x20));
dev->pci_isa_regs[0x47] = val & 0xfe;
@@ -1620,6 +1622,14 @@ pipc_reset(void *priv)
pipc_write(0, 0x44, 0x00, priv);
pipc_write(0, 0x77, 0x00, priv);
sff_set_slot(dev->bm[0], dev->pci_slot);
sff_set_slot(dev->bm[1], dev->pci_slot);
if (dev->local >= VIA_PIPC_686A)
ac97_via_set_slot(dev->ac97, dev->pci_slot, PCI_INTC);
if (dev->acpi)
acpi_set_slot(dev->acpi, dev->pci_slot);
}
static void *
@@ -1631,16 +1641,14 @@ pipc_init(const device_t *info)
pipc_log("PIPC: init()\n");
dev->local = info->local;
dev->slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, pipc_read, pipc_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE, pipc_read, pipc_write, dev, &dev->pci_slot);
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
sff_set_slot(dev->bm[0], dev->slot);
sff_set_irq_mode(dev->bm[0], 0, 0);
sff_set_irq_mode(dev->bm[0], 1, 0);
sff_set_irq_pin(dev->bm[0], PCI_INTA);
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
sff_set_slot(dev->bm[1], dev->slot);
sff_set_irq_mode(dev->bm[1], 0, 0);
sff_set_irq_mode(dev->bm[1], 1, 0);
sff_set_irq_pin(dev->bm[1], PCI_INTA);
@@ -1665,7 +1673,6 @@ pipc_init(const device_t *info)
dev->usb[1] = device_add_inst(&usb_device, 2);
dev->ac97 = device_add(&ac97_via_device);
ac97_via_set_slot(dev->ac97, dev->slot, PCI_INTC);
dev->sb = device_add_inst(&sb_pro_compat_device, 2);
sound_add_handler(pipc_sb_get_buffer, dev);
@@ -1695,7 +1702,6 @@ pipc_init(const device_t *info)
dev->ddma = device_add(&ddma_device);
if (dev->acpi) {
acpi_set_slot(dev->acpi, dev->slot);
acpi_set_nvr(dev->acpi, dev->nvr);
acpi_init_gporeg(dev->acpi, 0xff, 0xbf, 0xff, 0x7f);

View File

@@ -32,6 +32,10 @@
typedef struct vt82c505_t {
uint8_t index;
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pci_conf[256];
} vt82c505_t;
@@ -203,7 +207,7 @@ vt82c505_init(UNUSED(const device_t *info))
vt82c505_t *dev = (vt82c505_t *) malloc(sizeof(vt82c505_t));
memset(dev, 0, sizeof(vt82c505_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, vt82c505_read, vt82c505_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, vt82c505_read, vt82c505_write, dev, &dev->pci_slot);
dev->pci_conf[0x00] = 0x06;
dev->pci_conf[0x01] = 0x11;

View File

@@ -128,6 +128,10 @@ typedef struct atkbc_t {
uint8_t channel;
uint8_t stat_hi;
uint8_t pending;
uint8_t irq_state;
uint8_t pad;
uint8_t pad0;
uint8_t pad1;
uint8_t mem[0x100];
@@ -347,15 +351,15 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi)
dev->status |= STAT_MFULL;
if (dev->mem[0x20] & 0x02)
picint_common(1 << 12, 0, 1);
picint_common(1 << 1, 0, 0);
picint_common(1 << 12, 0, 1, NULL);
picint_common(1 << 1, 0, 0, NULL);
} else {
if (dev->mem[0x20] & 0x01)
picint_common(1 << 1, 0, 1);
picint_common(1 << 12, 0, 0);
picint_common(1 << 1, 0, 1, NULL);
picint_common(1 << 12, 0, 0, NULL);
}
} else if (dev->mem[0x20] & 0x01)
picintlevel(1 << 1); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */
picintlevel(1 << 1, &dev->irq_state); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */
dev->ob = temp;
}
@@ -720,10 +724,10 @@ write_p2(atkbc_t *dev, uint8_t val)
/* PS/2: Handle IRQ's. */
if (dev->misc_flags & FLAG_PS2) {
/* IRQ 12 */
picint_common(1 << 12, 0, val & 0x20);
picint_common(1 << 12, 0, val & 0x20, NULL);
/* IRQ 1 */
picint_common(1 << 1, 0, val & 0x10);
picint_common(1 << 1, 0, val & 0x10, NULL);
}
#endif
@@ -1550,7 +1554,8 @@ kbc_at_process_cmd(void *priv)
/* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */
dev->p1 = dev->p1 & 0xff;
write_p2(dev, 0x4b);
picintc(0x1002);
picintc(0x1000);
picintc(0x0002);
}
dev->status = (dev->status & 0x0f) | 0x60;
@@ -1569,7 +1574,8 @@ kbc_at_process_cmd(void *priv)
/* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */
dev->p1 = dev->p1 & 0xff;
write_p2(dev, 0xcf);
picintc(0x0002);
picintclevel(0x0002, &dev->irq_state);
dev->irq_state = 0;
}
dev->status = (dev->status & 0x0f) | 0x60;
@@ -1852,7 +1858,7 @@ kbc_at_read(uint16_t port, void *priv)
/* TODO: IRQ is only tied to OBF on the AT KBC, on the PS/2 KBC, it is controlled by a P2 bit.
This also means that in AT mode, the IRQ is level-triggered. */
if (!(dev->misc_flags & FLAG_PS2))
picintc(1 << 1);
picintclevel(1 << 1, &dev->irq_state);
break;
case 0x64:
@@ -1901,8 +1907,13 @@ kbc_at_reset(void *priv)
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) {
dev->misc_flags |= FLAG_PS2;
kbc_at_do_poll = kbc_at_poll_ps2;
} else
picintc(0x1000);
picintc(0x0002);
} else {
kbc_at_do_poll = kbc_at_poll_at;
picintclevel(0x0002, &dev->irq_state);
dev->irq_state = 0;
}
dev->misc_flags |= FLAG_CACHE;
@@ -1924,8 +1935,6 @@ kbc_at_close(void *priv)
atkbc_t *dev = (atkbc_t *) priv;
int max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 2 : 1;
kbc_at_reset(dev);
/* Stop timers. */
timer_disable(&dev->send_delay_timer);

View File

@@ -54,7 +54,7 @@ typedef struct pci_bridge_t {
uint8_t regs[256];
uint8_t bus_index;
int slot;
uint8_t slot;
} pci_bridge_t;
#ifdef ENABLE_PCI_BRIDGE_LOG
@@ -493,7 +493,10 @@ pci_bridge_init(const device_t *info)
pci_bridge_reset(dev);
dev->slot = pci_add_card(AGP_BRIDGE(dev->local) ? PCI_ADD_AGPBRIDGE : PCI_ADD_BRIDGE, pci_bridge_read, pci_bridge_write, dev);
if (AGP_BRIDGE(dev->local))
pci_add_card(PCI_ADD_AGPBRIDGE, pci_bridge_read, pci_bridge_write, dev, &dev->slot);
else
dev->slot = pci_add_bridge(pci_bridge_read, pci_bridge_write, dev);
interrupt_count = sizeof(interrupts);
interrupt_mask = interrupt_count - 1;

View File

@@ -48,6 +48,8 @@ enum {
SERIAL_INT_TIMEOUT = 16
};
void serial_update_ints(serial_t *dev);
static int next_inst = 0;
static serial_device_t serial_devices[SERIAL_MAX];
@@ -84,6 +86,8 @@ serial_reset_port(serial_t *dev)
dev->out_new = 0xffff;
memset(dev->xmit_fifo, 0, 16);
memset(dev->rcvr_fifo, 0, 16);
serial_update_ints(dev);
dev->irq_state = 0;
}
void
@@ -133,11 +137,15 @@ serial_update_ints(serial_t *dev)
if (stat && (dev->irq != 0xff) && ((dev->mctrl & 8) || (dev->type == SERIAL_8250_PCJR))) {
if (dev->type >= SERIAL_16450)
picintlevel(1 << dev->irq);
else
picintlevel(1 << dev->irq, &dev->irq_state);
else
picint(1 << dev->irq);
} else
picintc(1 << dev->irq);
} else {
if (dev->type >= SERIAL_16450)
picintclevel(1 << dev->irq, &dev->irq_state);
else
picintc(1 << dev->irq);
}
}
static void

View File

@@ -42,9 +42,12 @@ typedef struct cmd640_t {
uint8_t id;
uint8_t in_cfg;
uint8_t channels;
uint8_t pci, regs[256];
uint8_t pci;
uint8_t irq_state;
uint8_t pci_slot;
uint8_t pad0;
uint8_t regs[256];
uint32_t local;
int slot;
int irq_mode[2];
int irq_pin;
int irq_line;
@@ -95,12 +98,12 @@ cmd640_set_irq(int channel, void *priv)
if (irq) {
if (dev->irq_mode[channel] == 1)
pci_set_irq(dev->slot, dev->irq_pin);
pci_set_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state);
else
picint(1 << (14 + channel));
} else {
if (dev->irq_mode[channel] == 1)
pci_clear_irq(dev->slot, dev->irq_pin);
pci_clear_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state);
else
picintc(1 << (14 + channel));
}
@@ -500,7 +503,10 @@ cmd640_init(const device_t *info)
if (info->flags & DEVICE_PCI) {
device_add(&ide_pci_2ch_device);
dev->slot = pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev);
if (info->local & 0x80000)
pci_add_card(PCI_ADD_NORMAL, cmd640_pci_read, cmd640_pci_write, dev, &dev->pci_slot);
else
pci_add_card(PCI_ADD_IDE, cmd640_pci_read, cmd640_pci_write, dev, &dev->pci_slot);
if (dev->channels & 0x01)
ide_set_bus_master(0, NULL, cmd640_set_irq, dev);

View File

@@ -41,11 +41,16 @@ typedef struct cmd646_t {
uint8_t vlb_idx;
uint8_t single_channel;
uint8_t in_cfg;
uint8_t pci_slot;
uint8_t regs[256];
uint32_t local;
int slot;
int irq_mode[2];
int irq_pin;
int irq_mode[2];
sff8038i_t *bm[2];
} cmd646_t;
@@ -102,6 +107,9 @@ cmd646_ide_handlers(cmd646_t *dev)
uint16_t side;
int irq_mode[2] = { 0, 0 };
sff_set_slot(dev->bm[0], dev->pci_slot);
sff_set_slot(dev->bm[1], dev->pci_slot);
ide_pri_disable();
if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) {
@@ -382,7 +390,10 @@ cmd646_init(const device_t *info)
device_add(&ide_pci_2ch_device);
dev->slot = pci_add_card(PCI_ADD_IDE, cmd646_pci_read, cmd646_pci_write, dev);
if (info->local & 0x80000)
pci_add_card(PCI_ADD_NORMAL, cmd646_pci_read, cmd646_pci_write, dev, &dev->pci_slot);
else
pci_add_card(PCI_ADD_IDE, cmd646_pci_read, cmd646_pci_write, dev, &dev->pci_slot);
dev->single_channel = !!(info->local & 0x20000);

View File

@@ -409,31 +409,31 @@ sff_bus_master_set_irq(int channel, void *priv)
case 1:
/* Native PCI IRQ mode with interrupt pin. */
if (irq)
pci_set_irq(dev->slot, dev->irq_pin);
pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state);
else
pci_clear_irq(dev->slot, dev->irq_pin);
pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state);
break;
case 2:
case 5:
/* MIRQ 0 or 1. */
if (irq)
pci_set_mirq(dev->irq_mode[channel] & 1, 0);
pci_set_mirq(dev->irq_mode[channel] & 1, 0, &dev->irq_state);
else
pci_clear_mirq(dev->irq_mode[channel] & 1, 0);
pci_clear_mirq(dev->irq_mode[channel] & 1, 0, &dev->irq_state);
break;
case 3:
/* Native PCI IRQ mode with specified interrupt line. */
if (irq)
picintlevel(1 << dev->irq_line);
picintlevel(1 << dev->irq_line, &dev->irq_state);
else
picintc(1 << dev->irq_line);
picintclevel(1 << dev->irq_line, &dev->irq_state);
break;
case 4:
/* ALi Aladdin Native PCI INTAJ mode. */
if (irq)
pci_set_mirq(channel + 2, dev->irq_level[channel]);
pci_set_mirq(channel + 2, dev->irq_level[channel], &dev->irq_state);
else
pci_clear_mirq(channel + 2, dev->irq_level[channel]);
pci_clear_mirq(channel + 2, dev->irq_level[channel], &dev->irq_state);
break;
}
}
@@ -456,6 +456,7 @@ sff_bus_master_reset(sff8038i_t *dev, uint16_t old_base)
dev->addr = 0x00000000;
dev->ptr0 = 0x00;
dev->count = dev->eot = 0x00000000;
dev->irq_state = 0;
ide_pri_disable();
ide_sec_disable();
@@ -570,6 +571,7 @@ sff_init(UNUSED(const device_t *info))
dev->irq_pin = PCI_INTA;
dev->irq_line = 14;
dev->irq_level[0] = dev->irq_level[1] = 0;
dev->irq_state = 0;
next_id++;

View File

@@ -113,7 +113,8 @@ typedef struct acpi_regs_t {
typedef struct acpi_t {
acpi_regs_t regs;
uint8_t gpireg2_default;
uint8_t pad[3];
uint8_t irq_state;
uint8_t pad[2];
uint8_t gporeg_default[4];
uint8_t suspend_types[8];
uint16_t io_base;

View File

@@ -26,11 +26,11 @@ typedef struct sff8038i_t {
uint8_t ptr0;
uint8_t enabled;
uint8_t dma_mode;
uint8_t irq_state;
uint8_t pad;
uint8_t pad0;
uint8_t pad1;
uint16_t base;
uint16_t pad2;
uint16_t pad1;
uint32_t ptr;
uint32_t ptr_cur;
uint32_t addr;

View File

@@ -11,146 +11,260 @@
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <https://pcem-emulator.co.uk/>
*
* Copyright 2016-2020 Miran Grca.
* Copyright 2017-2020 Fred N. van Kempen.
* Copyright 2008-2020 Sarah Walker.
* Copyright 2023 Miran Grca.
*/
#ifndef EMU_PCI_H
#define EMU_PCI_H
#define PCI_REG_COMMAND 0x04
#define PCI_REG_VENDOR_ID_L 0x00
#define PCI_REG_VENDOR_ID_H 0x01
#define PCI_REG_DEVICE_ID_L 0x02
#define PCI_REG_DEVICE_ID_H 0x03
#define PCI_REG_COMMAND_L 0x04
#define PCI_REG_COMMAND_H 0x05
#define PCI_REG_STATUS_L 0x06
#define PCI_REG_STATUS_H 0x07
#define PCI_REG_REVISION 0x08
#define PCI_REG_PROG_IF 0x09
#define PCI_REG_SUBCLASS 0x0a
#define PCI_REG_CLASS 0x0b
#define PCI_REG_CACHELINE_SIZE 0x0c
#define PCI_REG_LATENCY_TIMER 0x0d
#define PCI_REG_HEADER_TYPE 0x0e
#define PCI_REG_BIST 0x0f
#define PCI_COMMAND_IO 0x01
#define PCI_COMMAND_MEM 0x02
#define PCI_COMMAND_L_IO 0x01
#define PCI_COMMAND_L_MEM 0x02
#define PCI_COMMAND_L_BM 0x04
#define PCI_COMMAND_L_SPECIAL 0x08
#define PCI_COMMAND_L_MEM_WIEN 0x10
#define PCI_COMMAND_L_VGASNOOP 0x20
#define PCI_COMMAND_L_PARITY 0x40
#define PCI_NO_IRQ_STEERING 0x8000
#define PCI_CAN_SWITCH_TYPE 0x10000
#define PCI_NO_BRIDGES 0x20000
#define PCI_ALWAYS_EXPOSE_DEV0 0x40000
#define PCI_COMMAND_H_SERR 0x01
#define PCI_COMMAND_H_FAST_B2B 0x02
#define PCI_COMMAND_H_INT_DIS 0x04
#define PCI_CONFIG_TYPE_1 1
#define PCI_CONFIG_TYPE_2 2
#define PCI_STATUS_L_INT 0x08
#define PCI_STATUS_L_CAPAB 0x10
#define PCI_STATUS_L_66MHZ 0x20
#define PCI_STATUS_L_FAST_B2B 0x80
#define PCI_CONFIG_TYPE_MASK 0x7fff
#define PCI_STATUS_H_MDPERR 0x01 /* Master Data Parity Error */
#define PCI_STATUS_H_DEVSEL 0x06
#define PCI_STATUS_H_STA 0x08 /* Signaled Target Abort */
#define PCI_STATUS_H_RTA 0x10 /* Received Target Abort */
#define PCI_STATUS_H_RMA 0x20 /* Received Master Abort */
#define PCI_STATUS_H_SSE 0x40 /* Signaled System Error */
#define PCI_STATUS_H_DPERR 0x80 /* Detected Parity Error */
#define PCI_INTA 1
#define PCI_INTB 2
#define PCI_INTC 3
#define PCI_INTD 4
#define PCI_DEVSEL_FAST 0x00
#define PCI_DEVSEL_MEDIUM 0x02
#define PCI_DEVSEL_SLOW 0x04
#define PCI_MIRQ0 0
#define PCI_MIRQ1 1
#define PCI_MIRQ2 2
#define PCI_MIRQ3 3
#define PCI_MIRQ4 4
#define PCI_MIRQ5 5
#define PCI_MIRQ6 6
#define PCI_MIRQ7 7
#define FLAG_MECHANISM_1 0x00000001
#define FLAG_MECHANISM_2 0x00000002
#define FLAG_MECHANISM_SWITCH 0x00000004
#define FLAG_CONFIG_IO_ON 0x00000008
#define FLAG_CONFIG_DEV0_IO_ON 0x00000010
#define FLAG_CONFIG_M1_IO_ON 0x00000020
#define FLAG_NO_IRQ_STEERING 0x00000040
#define FLAG_NO_BRIDGES 0x00000080
#define PCI_IRQ_DISABLED -1
#define FLAG_MECHANISM_MASK FLAG_MECHANISM_1 | FLAG_MECHANISM_2
#define FLAG_MASK 0x0000007f
#define PCI_ADD_STRICT 0x80
#define PCI_INTA 1
#define PCI_INTB 2
#define PCI_INTC 3
#define PCI_INTD 4
#define PCI_MIRQ0 0
#define PCI_MIRQ1 1
#define PCI_MIRQ2 2
#define PCI_MIRQ3 3
#define PCI_MIRQ4 4
#define PCI_MIRQ5 5
#define PCI_MIRQ6 6
#define PCI_MIRQ7 7
#define PCI_IRQ_DISABLED -1
#define PCI_ADD_STRICT 0x40
#define PCI_ADD_MASK (PCI_ADD_STRICT - 1)
#define PCI_ADD_VFIO 0x80
#define PCI_ADD_VFIO_MASK (PCI_ADD_VFIO - 1)
#define PCI_CARD_VFIO PCI_ADD_VFIO
#define PCI_BUS_INVALID 0xff
#define PCI_IGNORE_NO_SLOT 0xff
/* The number of an invalid PCI card. */
#define PCI_CARD_INVALID 0xef
/* PCI cards (currently 32). */
#define PCI_CARDS_NUM 0x20
#define PCI_CARD_MAX (PCI_CARDS_NUM - 1)
/* The number of PCI card INT pins - always at 4 per the PCI specification. */
#define PCI_INT_PINS_NUM 4
/* The base for MIRQ lines accepted by pci_irq(). */
#define PCI_MIRQ_BASE PCI_CARDS_NUM
/* PCI MIRQ lines (currently 8, this many are needed by the ALi M1543(C). */
#define PCI_MIRQS_NUM 8
#define PCI_MIRQ_MAX (PCI_MIRQS_NUM - 1)
/* The base for direct IRQ lines accepted by pci_irq(). */
#define PCI_DIRQ_BASE 0xf0
/* PCI direct IRQ lines (currently 16 because we only emulate the legacy PIC). */
#define PCI_DIRQS_NUM 16
#define PCI_DIRQ_MAX (PCI_DIRQS_NUM - 1)
/* PCI IRQ routings (currently 16, this many are needed by the OPTi 822). */
#define PCI_IRQS_NUM 16
#define PCI_IRQ_MAX (PCI_IRQS_NUM - 1)
/* Legacy flags. */
#define PCI_REG_COMMAND PCI_REG_COMMAND_L
#define PCI_COMMAND_IO PCI_COMMAND_L_IO
#define PCI_COMMAND_MEM PCI_COMMAND_L_MEM
#define PCI_CONFIG_TYPE_1 FLAG_MECHANISM_1
#define PCI_CONFIG_TYPE_2 FLAG_MECHANISM_2
#define PCI_CAN_SWITCH_TYPE FLAG_MECHANISM_SWITCH
#define PCI_ALWAYS_EXPOSE_DEV0 FLAG_CONFIG_DEV0_IO_ON
#define PCI_NO_IRQ_STEERING FLAG_NO_IRQ_STEERING
#define PCI_NO_BRIDGES FLAG_NO_BRIDGES
#define PCI_CONFIG_TYPE_MASK FLAG_MECHANISM_MASK
#define bar_t pci_bar_t
#define trc_init pci_trc_init
#define pci_register_slot(card, type, inta, intb, intc, intd) \
pci_register_bus_slot(0, card, type, inta, intb, intc, intd)
#define pci_set_mirq(mirq, level, irq_state) \
pci_irq(PCI_MIRQ_BASE | mirq, 0, level, 1, irq_state)
#define pci_set_irq(slot, pci_int, irq_state) \
pci_irq(slot, pci_int, 0, 1, irq_state)
#define pci_clear_mirq(mirq, level, irq_state) \
pci_irq(PCI_MIRQ_BASE | mirq, 0, level, 0, irq_state)
#define pci_clear_irq(slot, pci_int, irq_state) \
pci_irq(slot, pci_int, 0, 0, irq_state)
enum {
PCI_CARD_NORTHBRIDGE = 0,
PCI_CARD_AGPBRIDGE = 1,
PCI_CARD_SOUTHBRIDGE = 2,
PCI_CARD_SOUTHBRIDGE_IDE = 3,
PCI_CARD_SOUTHBRIDGE_PMU = 4,
PCI_CARD_SOUTHBRIDGE_USB = 5,
PCI_CARD_NORTHBRIDGE_SEC = 1,
PCI_CARD_AGPBRIDGE = 2,
PCI_CARD_SOUTHBRIDGE = 3,
PCI_CARD_SOUTHBRIDGE_IDE = 4,
PCI_CARD_SOUTHBRIDGE_PMU = 5,
PCI_CARD_SOUTHBRIDGE_USB = 6,
PCI_CARD_AGP = 0x0f,
PCI_CARD_NORMAL = 0x10,
PCI_CARD_VIDEO = 0x11,
PCI_CARD_SCSI = 0x12,
PCI_CARD_SOUND = 0x13,
PCI_CARD_IDE = 0x14,
PCI_CARD_NETWORK = 0x15,
PCI_CARD_BRIDGE = 0x16
PCI_CARD_HANGUL = 0x12,
PCI_CARD_IDE = 0x13,
PCI_CARD_SCSI = 0x14,
PCI_CARD_SOUND = 0x15,
PCI_CARD_MODEM = 0x16,
PCI_CARD_NETWORK = 0x17,
PCI_CARD_UART = 0x18,
PCI_CARD_USB = 0x19,
PCI_CARD_BRIDGE = 0x1a
};
enum {
PCI_ADD_NORTHBRIDGE = 0,
PCI_ADD_AGPBRIDGE = 1,
PCI_ADD_SOUTHBRIDGE = 2,
PCI_ADD_SOUTHBRIDGE_IDE = 3,
PCI_ADD_SOUTHBRIDGE_PMU = 4,
PCI_ADD_SOUTHBRIDGE_USB = 5,
PCI_ADD_NORTHBRIDGE_SEC = 1,
PCI_ADD_AGPBRIDGE = 2,
PCI_ADD_SOUTHBRIDGE = 3,
PCI_ADD_SOUTHBRIDGE_IDE = 4,
PCI_ADD_SOUTHBRIDGE_PMU = 5,
PCI_ADD_SOUTHBRIDGE_USB = 6,
PCI_ADD_AGP = 0x0f,
PCI_ADD_NORMAL = 0x10,
PCI_ADD_VIDEO = 0x11,
PCI_ADD_SCSI = 0x12,
PCI_ADD_SOUND = 0x13,
PCI_ADD_IDE = 0x14,
PCI_ADD_NETWORK = 0x15,
PCI_ADD_BRIDGE = 0x16
PCI_ADD_HANGUL = 0x12,
PCI_ADD_IDE = 0x13,
PCI_ADD_SCSI = 0x14,
PCI_ADD_SOUND = 0x15,
PCI_ADD_MODEM = 0x16,
PCI_ADD_NETWORK = 0x17,
PCI_ADD_UART = 0x18,
PCI_ADD_USB = 0x19,
PCI_ADD_BRIDGE = 0x1a
};
typedef union {
uint32_t addr;
uint8_t addr_regs[4];
} bar_t;
} pci_bar_t;
extern int pci_burst_time;
extern int agp_burst_time;
extern int pci_nonburst_time;
extern int agp_nonburst_time;
#define PCI_IO_ON 0x01
#define PCI_IO_DEV0 0x02
extern int pci_flags;
extern uint32_t pci_base;
extern uint32_t pci_size;
extern int pci_burst_time;
extern int agp_burst_time;
extern int pci_nonburst_time;
extern int agp_nonburst_time;
extern int pci_take_over_io;
extern void pci_set_irq_routing(int pci_int, int irq);
extern void pci_set_irq_level(int pci_int, int level);
extern void pci_enable_mirq(int mirq);
extern void pci_set_mirq_routing(int mirq, int irq);
extern uint32_t pci_base;
extern uint32_t pci_size;
/* PCI raise IRQ: the first parameter is slot if < PCI_MIRQ_BASE, MIRQ if >= PCI_MIRQ_BASE
and < PCI_DIRQ_BASE, and direct IRQ line if >= PCI_DIRQ_BASE (RichardG's
hack that may no longer be needed). */
extern void pci_irq(uint8_t slot, uint8_t pci_int, int level, int set, uint8_t *irq_state);
extern uint8_t pci_get_int(uint8_t slot, uint8_t pci_int);
extern void pci_type2_write(uint16_t port, uint8_t val, void *priv);
extern void pci_type2_writew(uint16_t port, uint16_t val, void *priv);
extern void pci_type2_writel(uint16_t port, uint32_t val, void *priv);
extern uint8_t pci_type2_read(uint16_t port, void *priv);
extern uint16_t pci_type2_readw(uint16_t port, void *priv);
extern uint32_t pci_type2_readl(uint16_t port, void *priv);
/* Relocate a PCI device to a new slot, required for the configurable
IDSEL's of ALi M1543(c). */
extern void pci_relocate_slot(int type, int new_slot);
extern void pci_set_irq_routing(int pci_int, int irq);
extern void pci_set_irq_level(int pci_int, int level);
/* Write PCI enable/disable key, split for the ALi M1435. */
extern void pci_key_write(uint8_t val);
extern void pci_enable_mirq(int mirq);
extern void pci_set_mirq_routing(int mirq, int irq);
/* Set PMC (ie. change PCI configuration mechanism), 0 = #2, 1 = #1. */
extern void pci_set_pmc(uint8_t pmc);
extern int pci_irq_is_level(int irq);
extern void pci_pic_reset(void);
extern void pci_reset(void);
extern void pci_set_mirq(uint8_t mirq, int level);
extern void pci_set_irq(uint8_t card, uint8_t pci_int);
extern void pci_clear_mirq(uint8_t mirq, int level);
extern void pci_clear_irq(uint8_t card, uint8_t pci_int);
extern uint8_t pci_get_int(uint8_t card, uint8_t pci_int);
/* Needed for the io.c handling of configuration mechanism #2 ports C000-CFFF. */
extern void pci_write(uint16_t port, uint8_t val, void *priv);
extern void pci_writew(uint16_t port, uint16_t val, void *priv);
extern void pci_writel(uint16_t port, uint32_t val, void *priv);
extern uint8_t pci_read(uint16_t port, void *priv);
extern uint16_t pci_readw(uint16_t port, void *priv);
extern uint32_t pci_readl(uint16_t port, void *priv);
extern void pci_reset(void);
extern void pci_init(int type);
extern uint8_t pci_register_bus(void);
extern void pci_set_pmc(uint8_t pmc);
extern void pci_remap_bus(uint8_t bus_index, uint8_t bus_number);
extern void pci_relocate_slot(int type, int new_slot);
extern void pci_register_slot(int card, int type,
int inta, int intb, int intc, int intd);
extern void pci_register_bus_slot(int bus, int card, int type,
int inta, int intb, int intc, int intd);
extern void pci_close(void);
extern uint8_t pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
extern uint8_t pci_register_bus(void);
extern void pci_remap_bus(uint8_t bus_index, uint8_t bus_number);
extern void pci_register_bus_slot(int bus, int card, int type, int inta, int intb, int intc, int intd);
extern void trc_init(void);
/* Add a PCI card. */
extern void pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv),
void (*write)(int func, int addr, uint8_t val, void *priv), void *priv, uint8_t *slot);
extern uint8_t trc_read(uint16_t port, void *priv);
extern void trc_write(uint16_t port, uint8_t val, void *priv);
/* Add an instance of the PCI bridge. */
extern uint8_t pci_add_bridge(uint8_t (*read)(int func, int addr, void *priv),
void (*write)(int func, int addr, uint8_t val, void *priv), void *priv);
extern void pci_bridge_set_ctl(void *priv, uint8_t ctl);
/* Register the cards that have been added into slots. */
extern void pci_register_cards(void);
extern void pci_pic_reset(void);
extern void pci_init(int flags);
/* PCI bridge stuff. */
extern void pci_bridge_set_ctl(void *priv, uint8_t ctl);
#ifdef EMU_DEVICE_H
extern const device_t dec21150_device;

View File

@@ -19,6 +19,13 @@
#ifndef EMU_PIC_H
#define EMU_PIC_H
typedef struct pic_latch {
uint8_t d;
uint8_t e;
uint8_t q;
uint8_t nq;
} pic_latch_t;
typedef struct pic {
uint8_t icw1;
uint8_t icw2;
@@ -38,8 +45,13 @@ typedef struct pic {
uint8_t special_mask_mode;
uint8_t auto_eoi_rotate;
uint8_t interrupt;
uint8_t lines;
uint8_t data_bus;
uint8_t irq_latch;
uint8_t has_slaves;
uint8_t flags;
uint8_t edge_lines;
uint8_t pad;
uint32_t lines[8];
uint32_t at;
struct pic *slaves[8];
} pic_t;
@@ -70,12 +82,22 @@ extern void pic2_init(void);
extern void pic_reset(void);
extern int picint_is_level(int irq);
extern void picint_common(uint16_t num, int level, int set);
extern void picint(uint16_t num);
extern void picintlevel(uint16_t num);
extern void picintc(uint16_t num);
extern void picint_common(uint16_t num, int level, int set, uint8_t *irq_state);
extern int picinterrupt(void);
#define PIC_IRQ_EDGE 0
#define PIC_IRQ_LEVEL 1
#define PIC_SLAVE_PENDING 0x01
#define PIC_FREEZE 0x02
#define PIC_MASTER_CLEAR 0x04
/* Legacy defines. */
#define picint(num) picint_common(num, PIC_IRQ_EDGE, 1, NULL)
#define picintlevel(num, irq_state) picint_common(num, PIC_IRQ_LEVEL, 1, irq_state)
#define picintc(num) picint_common(num, PIC_IRQ_EDGE, 0, NULL)
#define picintclevel(num, irq_state) picint_common(num, PIC_IRQ_LEVEL, 0, irq_state)
extern uint8_t pic_irq_ack(void);
#endif /*EMU_PIC_H*/

View File

@@ -396,6 +396,10 @@ typedef struct x54x_t {
uint8_t setup_info_len;
uint8_t max_id;
uint8_t pci_slot;
uint8_t irq_state;
uint8_t pad;
uint8_t pad0;
uint8_t pad1;
uint8_t temp_cdb[12];
/* for multi-threading, keep these volatile */
@@ -437,7 +441,7 @@ typedef struct x54x_t {
volatile int PendingInterrupt;
volatile int Lock;
volatile int target_data_len;
volatile int pad0;
volatile int pad2;
uint32_t Base;
uint32_t fdc_address;

View File

@@ -74,13 +74,13 @@ typedef struct serial_s {
uint8_t out;
uint8_t msr_set;
uint8_t pad;
uint8_t irq_state;
uint8_t pad0;
uint8_t pad1;
uint16_t dlab;
uint16_t base_address;
uint16_t out_new;
uint16_t pad2;
uint16_t pad1;
uint8_t rcvr_fifo_pos;
uint8_t xmit_fifo_pos;

View File

@@ -271,6 +271,8 @@ typedef struct voodoo_t {
int pci_enable;
uint8_t pci_slot;
uint8_t dac_data[8];
int dac_reg;
int dac_reg_ff;

View File

@@ -288,12 +288,12 @@ inb(uint16_t port)
int found = 0;
int qfound = 0;
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
ret = pci_type2_read(port, NULL);
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
ret = pci_read(port, NULL);
found = 1;
qfound = 1;
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
ret = pci_type2_read(port, NULL);
} else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) {
ret = pci_read(port, NULL);
found = 1;
qfound = 1;
} else {
@@ -340,12 +340,12 @@ outb(uint16_t port, uint8_t val)
int found = 0;
int qfound = 0;
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
pci_type2_write(port, val, NULL);
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
pci_write(port, val, NULL);
found = 1;
qfound = 1;
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
pci_type2_write(port, val, NULL);
} else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) {
pci_write(port, val, NULL);
found = 1;
qfound = 1;
} else {
@@ -384,12 +384,12 @@ inw(uint16_t port)
int qfound = 0;
uint8_t ret8[2];
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
ret = pci_type2_readw(port, NULL);
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
ret = pci_readw(port, NULL);
found = 2;
qfound = 1;
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
ret = pci_type2_readw(port, NULL);
} else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) {
ret = pci_readw(port, NULL);
found = 2;
qfound = 1;
} else {
@@ -446,12 +446,12 @@ outw(uint16_t port, uint16_t val)
int found = 0;
int qfound = 0;
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
pci_type2_writew(port, val, NULL);
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
pci_writew(port, val, NULL);
found = 2;
qfound = 1;
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
pci_type2_writew(port, val, NULL);
} else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) {
pci_writew(port, val, NULL);
found = 2;
qfound = 1;
} else {
@@ -504,12 +504,12 @@ inl(uint16_t port)
int found = 0;
int qfound = 0;
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
ret = pci_type2_readl(port, NULL);
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
ret = pci_readl(port, NULL);
found = 4;
qfound = 1;
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
ret = pci_type2_readl(port, NULL);
} else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) {
ret = pci_readl(port, NULL);
found = 4;
qfound = 1;
} else {
@@ -594,12 +594,12 @@ outl(uint16_t port, uint32_t val)
int qfound = 0;
int i = 0;
if ((pci_take_over_io & PCI_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
pci_type2_writel(port, val, NULL);
if ((pci_flags & FLAG_CONFIG_IO_ON) && (port >= pci_base) && (port < (pci_base + pci_size))) {
pci_writel(port, val, NULL);
found = 4;
qfound = 1;
} else if ((pci_take_over_io & PCI_IO_DEV0) && (port >= 0xc000) && (port < 0xc100)) {
pci_type2_writel(port, val, NULL);
} else if ((pci_flags & FLAG_CONFIG_DEV0_IO_ON) && (port >= 0xc000) && (port < 0xc100)) {
pci_writel(port, val, NULL);
found = 4;
qfound = 1;
} else {

View File

@@ -1527,11 +1527,11 @@ machine_at_pcm5330_init(const machine_t *model)
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0D, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0E, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0D, PCI_CARD_SOUTHBRIDGE_IDE, 0, 0, 0, 0);
pci_register_slot(0x0E, PCI_CARD_SOUTHBRIDGE_USB, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4);
device_add(&stpc_serial_device);
device_add(&w83977f_370_device);
device_add(&keyboard_ps2_ami_pci_device);
@@ -1738,7 +1738,7 @@ machine_at_ms4134_init(const machine_t *model)
device_add(&fdc37c665_ide_pri_device);
pci_init(PCI_CAN_SWITCH_TYPE | PCI_ALWAYS_EXPOSE_DEV0);
pci_init(FLAG_MECHANISM_1 | FLAG_MECHANISM_2 | PCI_ALWAYS_EXPOSE_DEV0);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0B, PCI_CARD_SCSI, 4, 1, 2, 3);
@@ -1772,7 +1772,7 @@ machine_at_tg486gp_init(const machine_t *model)
device_add(&fdc37c665_ide_pri_device);
pci_init(PCI_CAN_SWITCH_TYPE | PCI_ALWAYS_EXPOSE_DEV0);
pci_init(FLAG_MECHANISM_1 | FLAG_MECHANISM_2 | PCI_ALWAYS_EXPOSE_DEV0);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4);

View File

@@ -108,7 +108,7 @@ machine_init_ex(int m)
/* Reset the fast off stuff. */
cpu_fast_off_reset();
pci_take_over_io = 0x00000000;
pci_flags = 0x00000000;
}
/* All good, boot the machine! */

View File

@@ -97,36 +97,45 @@ static uint8_t rtl8019as_pnp_rom[] = {
typedef struct nic_t {
dp8390_t *dp8390;
const char *name;
uint8_t pnp_csnsav;
uint8_t pci_slot;
uint8_t irq_state;
uint8_t pad;
/* RTL8019AS/RTL8029AS registers */
uint8_t config0;
uint8_t config2;
uint8_t config3;
uint8_t _9346cr;
uint8_t pci_regs[PCI_REGSIZE];
uint8_t eeprom[128]; /* for RTL8029AS */
uint8_t maclocal[6]; /* configured MAC (local) address */
/* POS registers, MCA boards only */
uint8_t pos_regs[8];
int board;
int is_pci;
int is_mca;
int is_8bit;
uint32_t base_address;
int base_irq;
int has_bios;
uint32_t base_address;
uint32_t bios_addr;
uint32_t bios_size;
uint32_t bios_mask;
int card; /* PCI card slot */
int has_bios;
int pad;
bar_t pci_bar[2];
uint8_t pci_regs[PCI_REGSIZE];
uint8_t eeprom[128]; /* for RTL8029AS */
rom_t bios_rom;
void *pnp_card;
uint8_t pnp_csnsav;
uint8_t maclocal[6]; /* configured MAC (local) address */
/* RTL8019AS/RTL8029AS registers */
uint8_t config0;
uint8_t config2;
uint8_t config3;
uint8_t _9346cr;
uint32_t pad0;
/* POS registers, MCA boards only */
uint8_t pos_regs[8];
} nic_t;
#ifdef ENABLE_NE2K_LOG
@@ -150,13 +159,13 @@ nelog(int lvl, const char *fmt, ...)
static void
nic_interrupt(void *priv, int set)
{
const nic_t *dev = (nic_t *) priv;
nic_t *dev = (nic_t *) priv;
if (dev->is_pci) {
if (set)
pci_set_irq(dev->card, PCI_INTA);
pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
else
pci_clear_irq(dev->card, PCI_INTA);
pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
} else {
if (set)
picint(1 << dev->base_irq);
@@ -1087,8 +1096,7 @@ nic_init(const device_t *info)
mem_mapping_disable(&dev->bios_rom.mapping);
/* Add device to the PCI bus, keep its slot number. */
dev->card = pci_add_card(PCI_ADD_NORMAL,
nic_pci_read, nic_pci_write, dev);
pci_add_card(PCI_ADD_NORMAL, nic_pci_read, nic_pci_write, dev, &dev->pci_slot);
}
/* Initialize the RTL8029 EEPROM. */

View File

@@ -216,7 +216,8 @@ typedef struct {
uint32_t base_address;
int base_irq;
int dma_channel;
int card; /* PCI card slot */
uint8_t pci_slot; /* PCI card slot */
uint8_t irq_state;
int xmit_pos;
/** Register Address Pointer */
uint32_t u32RAP;
@@ -413,9 +414,9 @@ pcnet_do_irq(nic_t *dev, int issue)
{
if (dev->is_pci) {
if (issue)
pci_set_irq(dev->card, PCI_INTA);
pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
else
pci_clear_irq(dev->card, PCI_INTA);
pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
} else {
if (issue)
picint(1 << dev->base_irq);
@@ -2995,8 +2996,7 @@ pcnet_init(const device_t *info)
pcnet_pci_regs[0x04] = 3;
/* Add device to the PCI bus, keep its slot number. */
dev->card = pci_add_card(PCI_ADD_NORMAL,
pcnet_pci_read, pcnet_pci_write, dev);
pci_add_card(PCI_ADD_NORMAL, pcnet_pci_read, pcnet_pci_write, dev, &dev->pci_slot);
} else if (dev->board == DEV_AM79C961) {
dev->dma_channel = -1;

View File

@@ -306,7 +306,7 @@ typedef struct local_t {
uint8_t read_addr;
uint8_t wp_0d;
uint8_t wp_32;
uint8_t pad;
uint8_t irq_state;
uint8_t pad0;
uint8_t addr[8];
@@ -434,6 +434,21 @@ check_alarm_via(nvr_t *nvr, int8_t addr, int8_t addr_2)
return 1;
}
static void
timer_update_irq(nvr_t *nvr)
{
local_t *local = (local_t *) nvr->data;
uint8_t irq = (nvr->regs[RTC_REGB] & nvr->regs[RTC_REGC]) & (REGB_UIE | REGB_AIE | REGB_PIE);
if (irq) {
nvr->regs[RTC_REGC] |= REGC_IRQF;
picintlevel(1 << nvr->irq, &local->irq_state);
} else {
nvr->regs[RTC_REGC] &= ~REGC_IRQF;
picintclevel(1 << nvr->irq, &local->irq_state);
}
}
/* Update the NVR registers from the internal clock. */
static void
timer_update(void *priv)
@@ -442,45 +457,38 @@ timer_update(void *priv)
local_t *local = (local_t *) nvr->data;
struct tm tm;
local->ecount = 0LL;
if (local->ecount == (244ULL * TIMER_USEC)) {
rtc_tick();
if (!(nvr->regs[RTC_REGB] & REGB_SET)) {
/* Get the current time from the internal clock. */
nvr_time_get(&tm);
/* Update registers with current time. */
time_set(nvr, &tm);
/* Clear update status. */
local->stat = 0x00;
/* Check for any alarms we need to handle. */
if (check_alarm(nvr, RTC_SECONDS) && check_alarm(nvr, RTC_MINUTES) && check_alarm(nvr, RTC_HOURS) && check_alarm_via(nvr, RTC_DOM, RTC_ALDAY) && check_alarm_via(nvr, RTC_MONTH, RTC_ALMONTH) /* &&
check_alarm_via(nvr, RTC_DOM, RTC_ALDAY_SIS) &&
check_alarm_via(nvr, RTC_MONTH, RTC_ALMONT_SIS)*/
) {
if (check_alarm(nvr, RTC_SECONDS) && check_alarm(nvr, RTC_MINUTES) && check_alarm(nvr, RTC_HOURS) &&
check_alarm_via(nvr, RTC_DOM, RTC_ALDAY) && check_alarm_via(nvr, RTC_MONTH, RTC_ALMONTH) /* &&
check_alarm_via(nvr, RTC_DOM, RTC_ALDAY_SIS) && check_alarm_via(nvr, RTC_MONTH, RTC_ALMONT_SIS) */) {
nvr->regs[RTC_REGC] |= REGC_AF;
if (nvr->regs[RTC_REGB] & REGB_AIE) {
/* Generate an interrupt. */
if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) {
picintlevel(1 << nvr->irq);
nvr->regs[RTC_REGC] |= REGC_IRQF;
}
}
timer_update_irq(nvr);
}
/* Schedule the end of the update. */
local->ecount = 1984ULL * TIMER_USEC;
timer_set_delay_u64(&local->update_timer, local->ecount);
} else {
/*
* The flag and interrupt should be issued
* on update ended, not started.
*/
nvr->regs[RTC_REGC] |= REGC_UF;
if (nvr->regs[RTC_REGB] & REGB_UIE) {
/* Generate an interrupt. */
if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) {
picintlevel(1 << nvr->irq);
nvr->regs[RTC_REGC] |= REGC_IRQF;
}
}
timer_update_irq(nvr);
/* Clear update status. */
local->stat = 0x00;
local->ecount = 0LL;
}
}
@@ -525,13 +533,7 @@ timer_intr(void *priv)
timer_load_count(nvr);
nvr->regs[RTC_REGC] |= REGC_PF;
if (nvr->regs[RTC_REGB] & REGB_PIE) {
/* Generate an interrupt. */
if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) {
picintlevel(1 << nvr->irq);
nvr->regs[RTC_REGC] |= REGC_IRQF;
}
}
timer_update_irq(nvr);
}
}
@@ -541,15 +543,14 @@ timer_tick(nvr_t *nvr)
{
local_t *local = (local_t *) nvr->data;
/* Only update it there is no SET in progress. */
if (!(nvr->regs[RTC_REGB] & REGB_SET)) {
/* Only update it there is no SET in progress.
Also avoid updating it is DV2-DV0 are not set to 0, 1, 0. */
if (((nvr->regs[RTC_REGA] & 0x70) == 0x20) && !(nvr->regs[RTC_REGB] & REGB_SET)) {
/* Set the UIP bit, announcing the update. */
local->stat = REGA_UIP;
rtc_tick();
/* Schedule the actual update. */
local->ecount = (244ULL + 1984ULL) * TIMER_USEC;
local->ecount = 244ULL * TIMER_USEC;
timer_set_delay_u64(&local->update_timer, local->ecount);
}
}
@@ -583,32 +584,29 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv)
local_t *local = (local_t *) nvr->data;
struct tm tm;
uint8_t old;
uint8_t irq = 0;
uint8_t old_irq = 0;
old = nvr->regs[reg];
switch (reg) {
case RTC_SECONDS: /* bit 7 of seconds is read-only */
nvr_reg_common_write(reg, val & 0x7f, nvr, local);
break;
case RTC_REGA:
nvr->regs[RTC_REGA] = val;
timer_load_count(nvr);
if ((val & nvr->regs[RTC_REGA]) & ~REGA_UIP) {
nvr->regs[RTC_REGA] = (nvr->regs[RTC_REGA] & REGA_UIP) | (val & ~REGA_UIP);
timer_load_count(nvr);
}
break;
case RTC_REGB:
old_irq = (nvr->regs[RTC_REGB] & nvr->regs[RTC_REGC]) & 0x70;
nvr->regs[RTC_REGB] = val;
if (((old ^ val) & REGB_SET) && (val & REGB_SET)) {
/* According to the datasheet... */
nvr->regs[RTC_REGA] &= ~REGA_UIP;
nvr->regs[RTC_REGB] &= ~REGB_UIE;
}
irq = (nvr->regs[RTC_REGB] & nvr->regs[RTC_REGC]) & 0x70;
if (old_irq && !irq) {
picintc(1 << nvr->irq);
nvr->regs[RTC_REGC] &= ~REGC_IRQF;
} else if (!old_irq && irq) {
picintlevel(1 << nvr->irq);
nvr->regs[RTC_REGC] |= REGC_IRQF;
val &= ~REGB_UIE;
local->stat &= ~REGA_UIP;
}
nvr->regs[RTC_REGB] = val;
timer_update_irq(nvr);
break;
case RTC_REGC: /* R/O */
@@ -698,9 +696,9 @@ nvr_read(uint16_t addr, void *priv)
break;
case RTC_REGC:
ret = nvr->regs[RTC_REGC];
picintc(1 << nvr->irq);
nvr->regs[RTC_REGC] = 0x00;
ret = nvr->regs[RTC_REGC] & (REGC_IRQF | REGC_PF | REGC_AF | REGC_UF);
nvr->regs[RTC_REGC] &= ~(REGC_IRQF | REGC_PF | REGC_AF | REGC_UF);
timer_update_irq(nvr);
break;
case RTC_REGD:

1674
src/pci.c

File diff suppressed because it is too large Load Diff

View File

@@ -19,15 +19,21 @@ typedef struct pci_dummy_t {
uint8_t card;
uint8_t interrupt_on;
uint8_t irq_level;
} pci_dummy_t;
static void
pci_dummy_interrupt(int set, pci_dummy_t *dev)
{
if (set)
pci_set_irq(dev->card, PCI_INTA);
else
pci_clear_irq(dev->card, PCI_INTA);
if (set != dev->irq_level) {
if (set)
pci_set_irq(dev->card, PCI_INTA);
else
pci_clear_irq(dev->card, PCI_INTA);
}
dev->irq_level = set;
}
static uint8_t

345
src/pic.c
View File

@@ -51,20 +51,22 @@ pic_t pic2;
static pc_timer_t pic_timer;
static uint16_t smi_irq_mask = 0x0000;
static uint16_t smi_irq_status = 0x0000;
static uint16_t enabled_latches = 0x0000;
static uint16_t latched_irqs = 0x0000;
static int shadow = 0;
static int elcr_enabled = 0;
static int tmr_inited = 0;
static int latched = 0;
static int pic_pci = 0;
static int kbd_latch = 0;
static int mouse_latch = 0;
static uint16_t smi_irq_mask = 0x0000;
static uint16_t smi_irq_status = 0x0000;
static void (*update_pending)(void);
static uint16_t latched_irqs = 0x0000;
static void (*update_pending)(void);
static void pic_update_request(pic_t *dev, int irq);
static void pic_cascade(int set);
#ifdef ENABLE_PIC_LOG
int pic_do_log = ENABLE_PIC_LOG;
@@ -236,10 +238,7 @@ pic_update_pending_at(void)
{
pic2.int_pending = (find_best_interrupt(&pic2) != -1);
if (pic2.int_pending)
pic.irr |= (1 << pic2.icw3);
else
pic.irr &= ~(1 << pic2.icw3);
pic_cascade(pic2.int_pending);
pic.int_pending = (find_best_interrupt(&pic) != -1);
}
@@ -268,8 +267,13 @@ pic_reset(void)
pic.is_master = 1;
pic.interrupt = pic2.interrupt = 0x17;
if (is_at)
pic.has_slaves = 0;
pic2.has_slaves = 0;
if (is_at) {
pic.slaves[2] = &pic2;
pic.has_slaves = 1;
}
if (tmr_inited)
timer_on_auto(&pic_timer, 0.0);
@@ -326,8 +330,16 @@ pic_acknowledge(pic_t *dev)
int pic_int_num = 1 << pic_int;
dev->isr |= pic_int_num;
if (!pic_level_triggered(dev, pic_int) || !(dev->lines & pic_int_num))
dev->irr &= ~pic_int_num;
/* Simulate the clearing of the edge pulse. */
dev->edge_lines &= ~pic_int_num;
/* Clear the edge sense latch. */
dev->irq_latch &= ~pic_int_num;
dev->flags |= PIC_FREEZE; /* Freeze it so it still takes interrupts but they do not
override the one currently being processed. */
/* Clear the reset latch. */
pic_update_request(dev, pic_int);
}
/* Find IRQ for non-specific EOI (either by command or automatic) by finding the highest IRQ
@@ -403,12 +415,12 @@ pic_latch_read(UNUSED(uint16_t addr), UNUSED(void *priv))
{
uint8_t ret = 0xff;
pic_log("pic_latch_read(%i, %i): %02X%02X\n", kbd_latch, mouse_latch, pic2.lines & 0x10, pic.lines & 0x02);
pic_log("pic_latch_read(%04X): %02X%02X\n", enabled_latches, latched_irqs & 0x10, latched_irqs & 0x02);
if (kbd_latch && (latched_irqs & 0x0002))
if ((latched_irqs & enabled_latches) & 0x0002)
picintc(0x0002);
if (mouse_latch && (latched_irqs & 0x1000))
if ((latched_irqs & enabled_latches) & 0x1000)
picintc(0x1000);
/* Return FF - we just lower IRQ 1 and IRQ 12. */
@@ -433,12 +445,8 @@ pic_read(uint16_t addr, void *priv)
}
} else {
/* Standard 8259 PIC read */
#ifndef UNDEFINED_READ
/* Put the IRR on to the data bus by default until the real PIC is probed. */
dev->data_bus = dev->irr;
#endif
if (dev->ocw3 & 0x04) {
dev->interrupt &= ~0x20; /* Freeze the interrupt until the poll is over. */
dev->flags &= ~PIC_FREEZE; /* Freeze the interrupt until the poll is over. */
if (dev->int_pending) {
dev->data_bus = 0x80 | (dev->interrupt & 7);
pic_acknowledge(dev);
@@ -452,10 +460,8 @@ pic_read(uint16_t addr, void *priv)
else if (dev->ocw3 & 0x02) {
if (dev->ocw3 & 0x01)
dev->data_bus = dev->isr;
#ifdef UNDEFINED_READ
else
dev->data_bus = 0x00;
#endif
dev->data_bus = dev->irr;
}
/* If A0 = 0, VIA shadow is disabled, and poll mode is disabled,
simply read whatever is currently on the data bus. */
@@ -470,6 +476,7 @@ static void
pic_write(uint16_t addr, uint8_t val, void *priv)
{
pic_t *dev = (pic_t *) priv;
uint8_t i;
pic_log("pic_write(%04X, %02X, %08X)\n", addr, val, priv);
@@ -511,7 +518,13 @@ pic_write(uint16_t addr, uint8_t val, void *priv)
if (!(dev->icw1 & 1))
dev->icw4 = 0x00;
dev->ocw2 = dev->ocw3 = 0x00;
dev->irr = dev->lines;
dev->irr = 0x00;
dev->edge_lines = 0x00;
dev->irq_latch = 0x00;
dev->flags |= PIC_MASTER_CLEAR;
for (i = 0; i <= 7; i++)
pic_update_request(dev, i);
dev->flags &= ~PIC_MASTER_CLEAR;
dev->imr = dev->isr = 0x00;
dev->ack_bytes = dev->priority = 0x00;
dev->auto_eoi_rotate = dev->special_mask_mode = 0x00;
@@ -522,7 +535,7 @@ pic_write(uint16_t addr, uint8_t val, void *priv)
} else if (val & 0x08) {
dev->ocw3 = val;
if (dev->ocw3 & 0x04)
dev->interrupt |= 0x20; /* Freeze the interrupt until the poll is over. */
dev->flags |= PIC_FREEZE; /* Freeze the interrupt until the poll is over. */
if (dev->ocw3 & 0x40)
dev->special_mask_mode = !!(dev->ocw3 & 0x20);
} else {
@@ -549,12 +562,15 @@ pic_set_pci(void)
void
pic_kbd_latch(int enable)
{
uint16_t old_latches = enabled_latches;
pic_log("PIC keyboard latch now %sabled\n", enable ? "en" : "dis");
if (!!(enable | mouse_latch) != !!(kbd_latch | mouse_latch))
io_handler(!!(enable | mouse_latch), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL);
enable = (!!enable) << 1;
enabled_latches = (enabled_latches & 0x1000) | enable;
kbd_latch = !!enable;
if (!!(enabled_latches & 0x1002) != !!(old_latches & 0x1002))
io_handler(!!(enabled_latches & 0x1002), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL);
if (!enable)
picintc(0x0002);
@@ -563,12 +579,15 @@ pic_kbd_latch(int enable)
void
pic_mouse_latch(int enable)
{
uint16_t old_latches = enabled_latches;
pic_log("PIC mouse latch now %sabled\n", enable ? "en" : "dis");
if (!!(kbd_latch | enable) != !!(kbd_latch | mouse_latch))
io_handler(!!(kbd_latch | enable), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL);
enable = (!!enable) << 12;
enabled_latches = (enabled_latches & 0x0002) | enable;
mouse_latch = !!enable;
if (!!(enabled_latches & 0x1002) != !!(old_latches & 0x1002))
io_handler(!!(enabled_latches & 0x1002), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL);
if (!enable)
picintc(0x1000);
@@ -580,11 +599,11 @@ pic_reset_hard(void)
pic_reset();
/* Explicitly reset the latches. */
kbd_latch = mouse_latch = 0;
enabled_latches = 0x0000;
latched_irqs = 0x0000;
/* The situation is as follows: There is a giant mess when it comes to these latches on real hardware,
to the point that there's even boards with board-level latched that get used in place of the latches
to the point that there's even boards with board-level latches that get used in place of the latches
on the chipset, therefore, I'm just doing this here for the sake of simplicity. */
if (machine_has_bus(machine, MACHINE_BUS_PS2_LATCH)) {
pic_kbd_latch(0x01);
@@ -621,30 +640,131 @@ pic2_init(void)
}
void
picint_common(uint16_t num, int level, int set)
pic_update_lines(pic_t *dev, uint16_t num, int level, int set, uint8_t *irq_state)
{
int raise;
uint8_t b;
uint8_t slaves = 0;
uint8_t old_edge_lines, bit;
switch (level) {
case PIC_IRQ_EDGE:
old_edge_lines = dev->edge_lines;
dev->edge_lines &= ~num;
if (set)
dev->edge_lines |= num;
if ((dev->isr & num) || (dev->flags & PIC_MASTER_CLEAR))
dev->irq_latch = (dev->irq_latch & ~num) | (dev->edge_lines & num);
else if ((dev->edge_lines & num) && !(old_edge_lines & num))
dev->irq_latch |= num;
break;
case PIC_IRQ_LEVEL:
for (uint8_t i = 0; i < 8; i++) {
bit = (1 << i);
if ((num & bit) && ((!!*irq_state) != !!set))
dev->lines[i] += (set ? 1 : -1);
}
if ((!!*irq_state) != !!set)
*irq_state = set;
break;
}
}
static uint8_t
pic_irq_get_request(pic_t *dev, int irq)
{
uint8_t ret;
ret = ((dev->edge_lines & (1 << irq)) || (dev->lines[irq] > 0));
pic_log("pic_irq_get_request(%08X, %i) = %02X\n", (uint32_t) (uintptr_t) dev, irq, ret);
return ret;
}
static uint8_t
pic_es_latch_clear(pic_t *dev, int irq)
{
uint8_t ret;
ret = (dev->isr & (1 << irq)) || (dev->flags & PIC_MASTER_CLEAR);
pic_log("pic_es_latch_clear(%08X, %i) = %02X\n", (uint32_t) (uintptr_t) dev, irq, ret);
return ret;
}
static uint8_t
pic_es_latch_out(pic_t *dev, int irq)
{
uint8_t ret;
ret = !((pic_es_latch_clear(dev, irq) && (dev->irq_latch & (1 << irq))) || !pic_irq_get_request(dev, irq));
pic_log("pic_es_latch_out(%08X, %i) = %02X\n", (uint32_t) (uintptr_t) dev, irq, ret);
return ret;
}
static uint8_t
pic_es_latch_nor(pic_t *dev, int irq)
{
uint8_t ret;
ret = !(pic_es_latch_out(dev, irq) || picint_is_level(irq));
pic_log("pic_es_latch_nor(%08X, %i) = %02X\n", (uint32_t) (uintptr_t) dev, irq, ret);
return ret;
}
static uint8_t
pic_irq_request_nor(pic_t *dev, int irq)
{
uint8_t ret;
ret = !(pic_es_latch_nor(dev, irq) || !pic_irq_get_request(dev, irq));
pic_log("pic_irq_request_nor(%08X, %i) = %02X\n", (uint32_t) (uintptr_t) dev, irq, ret);
return ret;
}
static void
pic_update_request(pic_t *dev, int irq)
{
dev->irr &= ~(1 << irq);
if (dev->flags & PIC_FREEZE) {
pic_log("pic_update_request(%08X, %i): FREEZE#\n", (uint32_t) (uintptr_t) dev, irq);
} else {
dev->irr |= (pic_irq_request_nor(dev, irq) << irq);
pic_log("pic_update_request(%08X, %i): IRR = %02X\n", (uint32_t) (uintptr_t) dev, irq, dev->irr);
}
}
static void
pic_update_irr(pic_t *dev, uint16_t num)
{
for (uint8_t i = 0; i < 8; i++) {
if (num & (1 << i))
pic_update_request(dev, i);
}
pic_log("IRQ %04x: IRR now: %02X\n", num, dev->irr);
}
void
picint_common(uint16_t num, int level, int set, uint8_t *irq_state)
{
pic_log("picint_common(%04X, %i, %i, %08X)\n", num, level, set, (uint32_t) (uintptr_t) irq_state);
set = !!set;
/* Make sure to ignore all slave IRQ's, and in case of AT+,
translate IRQ 2 to IRQ 9. */
for (uint8_t i = 0; i < 8; i++) {
b = (uint8_t) (1 << i);
raise = num & b;
if (pic.icw3 & b) {
slaves++;
if (raise) {
num &= ~b;
if (pic.at && (i == 2))
num |= (1 << 9);
}
}
if (num & pic.icw3) {
num &= ~pic.icw3;
if (pic.at)
num |= (1 << 9);
}
if (!slaves)
if (!pic.has_slaves)
num &= 0x00ff;
if (!num) {
@@ -655,77 +775,41 @@ picint_common(uint16_t num, int level, int set)
if (num & 0x0100)
acpi_rtc_status = !!set;
if (set) {
if (smi_irq_mask & num) {
smi_raise();
smi_irq_status |= num;
}
if (num & 0xff00) {
if (level)
pic2.lines |= (num >> 8);
/* Latch IRQ 12 if the mouse latch is enabled. */
if ((num & 0x1000) && mouse_latch)
latched_irqs |= 0x1000;
pic2.irr |= (num >> 8);
}
if (num & 0x00ff) {
if (level)
pic.lines |= (num & 0x00ff);
/* Latch IRQ 1 if the keyboard latch is enabled. */
if (kbd_latch && (num & 0x0002))
latched_irqs |= 0x0002;
pic.irr |= (num & 0x00ff);
}
} else {
smi_irq_status &= ~num;
if (num & 0xff00) {
pic2.lines &= ~(num >> 8);
/* Unlatch IRQ 12 if the mouse latch is enabled. */
if ((num & 0x1000) && mouse_latch)
latched_irqs &= 0xefff;
pic2.irr &= ~(num >> 8);
}
if (num & 0x00ff) {
pic.lines &= ~(num & 0x00ff);
/* Unlatch IRQ 1 if the keyboard latch is enabled. */
if (kbd_latch && (num & 0x0002))
latched_irqs &= 0xfffd;
pic.irr &= ~(num & 0x00ff);
}
smi_irq_status &= ~num;
if (set && (smi_irq_mask & num)) {
smi_raise();
smi_irq_status |= num;
}
if (!(pic.interrupt & 0x20) && !(pic2.interrupt & 0x20))
if (num & 0xff00) {
pic_update_lines(&pic2, num >> 8, level, set, irq_state);
/* Latch IRQ 12 if the mouse latch is enabled. */
if ((num & enabled_latches) & 0x1000)
latched_irqs = (latched_irqs & 0xefff) | (set << 12);
pic_update_irr(&pic2, num >> 8);
}
if (num & 0x00ff) {
pic_update_lines(&pic, num & 0x00ff, level, set, irq_state);
/* Latch IRQ 1 if the keyboard latch is enabled. */
if ((num & enabled_latches) & 0x0002)
latched_irqs = (latched_irqs & 0xfffd) | (set << 1);
pic_update_irr(&pic, num & 0x00ff);
}
if (!(pic.flags & PIC_FREEZE) && !(pic2.flags & PIC_FREEZE))
update_pending();
}
void
picint(uint16_t num)
static void
pic_cascade(int set)
{
picint_common(num, 0, 1);
}
void
picintlevel(uint16_t num)
{
picint_common(num, 1, 1);
}
void
picintc(uint16_t num)
{
picint_common(num, 0, 0);
pic_update_lines(&pic, (1 << pic2.icw3), PIC_IRQ_EDGE, set, NULL);
pic_update_irr(&pic, (1 << pic2.icw3));
}
static uint8_t
@@ -737,15 +821,12 @@ pic_i86_mode(pic_t *dev)
static uint8_t
pic_irq_ack_read(pic_t *dev, int phase)
{
uint8_t intr = dev->interrupt & 0x47;
uint8_t slave = intr & 0x40;
intr &= 0x07;
uint8_t intr = dev->interrupt & 0x07;
uint8_t slave = dev->flags & PIC_SLAVE_PENDING;
pic_log(" pic_irq_ack_read(%08X, %i)\n", dev, phase);
if (dev != NULL) {
if (phase == 0) {
dev->interrupt |= 0x20; /* Freeze it so it still takes interrupts but they do not
override the one currently being processed. */
pic_acknowledge(dev);
if (slave)
dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase);
@@ -791,7 +872,7 @@ pic_irq_ack(void)
exit(-1);
}
pic.interrupt |= 0x40; /* Mark slave pending. */
pic.flags |= PIC_SLAVE_PENDING;
}
ret = pic_irq_ack_read(&pic, pic.ack_bytes);
@@ -799,8 +880,13 @@ pic_irq_ack(void)
if (pic.ack_bytes == 0) {
/* Needed for Xi8088. */
if (pic.interrupt & 0x40)
if (pic.flags & PIC_SLAVE_PENDING) {
pic2.flags &= ~PIC_FREEZE;
pic_update_request(&pic2, pic2.interrupt & 0x07);
pic2.interrupt = 0x17;
}
pic.flags &= ~(PIC_SLAVE_PENDING | PIC_FREEZE);
pic_update_request(&pic, pic.interrupt & 0x07);
pic.interrupt = 0x17;
update_pending();
}
@@ -821,7 +907,7 @@ picinterrupt(void)
exit(-1);
}
pic.interrupt |= 0x40; /* Mark slave pending. */
pic.flags |= PIC_SLAVE_PENDING;
}
if ((pic.interrupt == 0) && (pit_devs[1].data != NULL))
@@ -833,8 +919,13 @@ picinterrupt(void)
pic.ack_bytes = (pic.ack_bytes + 1) % (pic_i86_mode(&pic) ? 2 : 3);
if (pic.ack_bytes == 0) {
if (pic.interrupt & 0x40)
if (pic.flags & PIC_SLAVE_PENDING) {
pic2.flags &= ~PIC_FREEZE;
pic_update_request(&pic2, pic2.interrupt & 0x07);
pic2.interrupt = 0x17;
}
pic.flags &= ~(PIC_SLAVE_PENDING | PIC_FREEZE);
pic_update_request(&pic, pic.interrupt & 0x07);
pic.interrupt = 0x17;
update_pending();
}

View File

@@ -1748,7 +1748,7 @@ buslogic_init(const device_t *info)
}
if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) {
dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, BuslogicPCIRead, BuslogicPCIWrite, dev);
pci_add_card(PCI_ADD_NORMAL, BuslogicPCIRead, BuslogicPCIWrite, dev, &dev->pci_slot);
buslogic_pci_bar[0].addr_regs[0] = 1;
buslogic_pci_bar[1].addr_regs[0] = 0;

View File

@@ -234,6 +234,7 @@ typedef struct ncr53c8xx_t {
int waiting;
uint8_t current_lun;
uint8_t irq_state;
uint8_t istat;
uint8_t dcmd;
@@ -498,10 +499,10 @@ static void
do_irq(ncr53c8xx_t *dev, int level)
{
if (level) {
pci_set_irq(dev->pci_slot, PCI_INTA);
pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
ncr53c8xx_log("Raising IRQ...\n");
} else {
pci_clear_irq(dev->pci_slot, PCI_INTA);
pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
ncr53c8xx_log("Lowering IRQ...\n");
}
}
@@ -534,12 +535,16 @@ ncr53c8xx_update_irq(ncr53c8xx_t *dev)
level = 1;
}
#ifdef STATE_KEEPING
if (level != dev->last_level) {
#endif
ncr53c8xx_log("Update IRQ level %d dstat %02x sist %02x%02x\n",
level, dev->dstat, dev->sist1, dev->sist0);
dev->last_level = level;
do_irq(dev, level); /* Only do something with the IRQ if the new level differs from the previous one. */
#ifdef STATE_KEEPING
}
#endif
}
/* Stop SCRIPTS execution and raise a SCSI interrupt. */
@@ -2552,9 +2557,9 @@ ncr53c8xx_init(const device_t *info)
dev->has_bios = 0;
if (info->local & 0x8000)
dev->pci_slot = pci_add_card(PCI_ADD_SCSI, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev);
pci_add_card(PCI_ADD_SCSI, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev, &dev->pci_slot);
else
dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev);
pci_add_card(PCI_ADD_NORMAL, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev, &dev->pci_slot);
if (dev->chip == CHIP_875) {
dev->chip_rev = 0x04;

View File

@@ -197,6 +197,7 @@ typedef struct esp_t {
int pos;
} dma_86c01;
uint8_t irq_state;
uint8_t pos_regs[8];
} esp_t;
@@ -247,10 +248,10 @@ esp_irq(esp_t *dev, int level)
}
} else {
if (level) {
pci_set_irq(dev->pci_slot, PCI_INTA);
pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
esp_log("Raising IRQ...\n");
} else {
pci_clear_irq(dev->pci_slot, PCI_INTA);
pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
esp_log("Lowering IRQ...\n");
}
}
@@ -1842,7 +1843,7 @@ dc390_init(UNUSED(const device_t *info))
dev->PCIBase = 0;
dev->MMIOBase = 0;
dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, esp_pci_read, esp_pci_write, dev);
pci_add_card(PCI_ADD_NORMAL, esp_pci_read, esp_pci_write, dev, &dev->pci_slot);
esp_pci_bar[0].addr_regs[0] = 1;
esp_pci_regs[0x04] = 3;

View File

@@ -83,23 +83,27 @@ x54x_irq(x54x_t *dev, int set)
if (dev->card_bus & DEVICE_PCI) {
x54x_log("PCI IRQ: %02X, PCI_INTA\n", dev->pci_slot);
if (set)
pci_set_irq(dev->pci_slot, PCI_INTA);
pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
else
pci_clear_irq(dev->pci_slot, PCI_INTA);
pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
} else {
x54x_log("%sing IRQ %i\n", set ? "Rais" : "Lower", irq);
if (set) {
if (dev->interrupt_type)
int_type = dev->interrupt_type(dev);
if (dev->interrupt_type)
int_type = dev->interrupt_type(dev);
if (set) {
if (int_type)
picintlevel(1 << irq);
picintlevel(1 << irq, &dev->irq_state);
else
picint(1 << irq);
} else
picintc(1 << irq);
}
} else {
if (int_type)
picintclevel(1 << irq, &dev->irq_state);
else
picintc(1 << irq);
}
}
}
static void
@@ -1415,6 +1419,7 @@ static void
x54x_reset(x54x_t *dev)
{
clear_irq(dev);
dev->irq_state = 0;
if (dev->flags & X54X_INT_GEOM_WRITABLE)
dev->Geometry = 0x90;
else

View File

@@ -73,7 +73,8 @@ typedef struct _ac97_via_ {
uint8_t regs_linear[256];
};
} codec_shadow[2];
int slot;
uint8_t pci_slot;
uint8_t irq_state;
int irq_pin;
ac97_codec_t *codec[2][2];
@@ -115,8 +116,8 @@ ac97_via_set_slot(void *priv, int slot, int irq_pin)
ac97_via_log("AC97 VIA: set_slot(%d, %d)\n", slot, irq_pin);
dev->slot = slot;
dev->irq_pin = irq_pin;
dev->pci_slot = slot;
dev->irq_pin = irq_pin;
}
uint8_t
@@ -182,12 +183,12 @@ ac97_via_update_irqs(ac97_via_t *dev)
/* Stop immediately if any flag is set. Doing it this way optimizes
rising edges for the playback SGD (0 - first to be checked). */
if (dev->sgd_regs[i] & (dev->sgd_regs[i | 0x2] & 0x03)) {
pci_set_irq(dev->slot, dev->irq_pin);
pci_set_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state);
return;
}
}
pci_clear_irq(dev->slot, dev->irq_pin);
pci_clear_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state);
}
static void

View File

@@ -53,6 +53,7 @@ typedef struct es1371_t {
uint32_t base_addr;
uint8_t int_line;
uint8_t irq_state;
uint16_t pmcsr;
@@ -120,7 +121,7 @@ typedef struct es1371_t {
int cd_vol_l;
int cd_vol_r;
int card;
uint8_t pci_slot;
int pos;
int16_t buffer[SOUNDBUFLEN * 2];
@@ -235,9 +236,9 @@ es1371_update_irqs(es1371_t *dev)
irq = 1;
if (irq)
pci_set_irq(dev->card, PCI_INTA);
pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
else
pci_clear_irq(dev->card, PCI_INTA);
pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
}
static void
@@ -2100,7 +2101,7 @@ es1371_init(const device_t *info)
dev->gameport = gameport_add(&gameport_pnp_device);
gameport_remap(dev->gameport, 0x200);
dev->card = pci_add_card(info->local ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1371_pci_read, es1371_pci_write, dev);
pci_add_card(info->local ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1371_pci_read, es1371_pci_write, dev, &dev->pci_slot);
timer_add(&dev->dac[1].timer, es1371_poll, dev, 1);

View File

@@ -97,7 +97,8 @@ typedef struct _cmi8x38_ {
uint16_t mpu_base;
uint8_t pci_regs[256];
uint8_t io_regs[256];
int slot;
uint8_t pci_slot;
uint8_t irq_state;
sb_t *sb;
void *gameport;
@@ -148,11 +149,11 @@ cmi8x38_update_irqs(cmi8x38_t *dev)
/* Calculate and use the INTR flag. */
if (*((uint32_t *) &dev->io_regs[0x10]) & 0x0401c003) {
dev->io_regs[0x13] |= 0x80;
pci_set_irq(dev->slot, PCI_INTA);
pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
cmi8x38_log("CMI8x38: Raising IRQ\n");
} else {
dev->io_regs[0x13] &= ~0x80;
pci_clear_irq(dev->slot, PCI_INTA);
pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
}
}
@@ -823,9 +824,9 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv)
/* Force IRQ if requested. Clearing this bit is undefined. */
if (val & 0x10)
pci_set_irq(dev->slot, PCI_INTA);
pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
else if ((dev->io_regs[0x17] & 0x10) && !(val & 0x10))
pci_clear_irq(dev->slot, PCI_INTA);
pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state);
/* Enable or disable I/O traps. */
dev->io_regs[addr] = val;
@@ -1473,7 +1474,7 @@ cmi8x38_init(const device_t *info)
}
/* Add PCI card. */
dev->slot = pci_add_card((info->local & (1 << 13)) ? PCI_ADD_SOUND : PCI_ADD_NORMAL, cmi8x38_pci_read, cmi8x38_pci_write, dev);
pci_add_card((info->local & (1 << 13)) ? PCI_ADD_SOUND : PCI_ADD_NORMAL, cmi8x38_pci_read, cmi8x38_pci_write, dev, &dev->pci_slot);
/* Perform initial reset. */
cmi8x38_reset(dev);

View File

@@ -98,6 +98,9 @@ typedef struct gus_t {
int irqnext;
uint8_t irq_state;
uint8_t midi_irq_state;
pc_timer_t timer_1;
pc_timer_t timer_2;
@@ -157,8 +160,10 @@ double vol16bit[4096];
void
gus_update_int_status(gus_t *gus)
{
int irq_pending = 0;
int midi_irq_pending = 0;
int irq_pending = 0;
int midi_irq_pending = 0;
int intr_pending = 0;
int midi_intr_pending = 0;
gus->irqstatus &= ~0x60;
gus->irqstatus2 = 0xE0;
@@ -187,24 +192,35 @@ gus_update_int_status(gus_t *gus)
midi_irq_pending = gus->midi_status & MIDI_INT_MASTER;
if (gus->irq == gus->irq_midi && gus->irq != -1) {
if (gus->irq == gus->irq_midi) {
if (irq_pending || midi_irq_pending)
picintlevel(1 << gus->irq);
intr_pending = 1;
else
picintc(1 << gus->irq);
intr_pending = 0;
} else {
if (gus->irq != -1) {
if (irq_pending)
picintlevel(1 << gus->irq);
else
picintc(1 << gus->irq);
}
if (gus->irq_midi != -1) {
if (midi_irq_pending)
picintlevel(1 << gus->irq_midi);
else
picintc(1 << gus->irq_midi);
}
if (irq_pending)
intr_pending = 1;
else
intr_pending = 0;
if (midi_irq_pending)
midi_intr_pending = 1;
else
midi_intr_pending = 0;
}
if (gus->irq != -1) {
if (intr_pending)
picintlevel(1 << gus->irq, &gus->irq_state);
else
picintclevel(1 << gus->irq, &gus->irq_state);
}
if (gus->irq_midi != -1) {
if (midi_intr_pending)
picintlevel(1 << gus->irq_midi, &gus->midi_irq_state);
else
picintclevel(1 << gus->irq_midi, &gus->midi_irq_state);
}
}
@@ -1174,6 +1190,103 @@ gus_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort)
return 0;
}
static void
gus_reset(void *p)
{
gus_t *gus = (gus_t *) p;
int c;
double out = 1.0;
if (gus == NULL)
return;
memset(gus->ram, 0x00, (gus->gus_end_ram));
for (c = 0; c < 32; c++) {
gus->ctrl[c] = 1;
gus->rctrl[c] = 1;
gus->rfreq[c] = 63 * 512;
}
for (c = 4095; c >= 0; c--) {
vol16bit[c] = out;
out /= 1.002709201; /* 0.0235 dB Steps */
}
gus->voices = 14;
gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / 44100.0));
gus->t1l = gus->t2l = 0xff;
gus->global = 0;
gus->addr = 0;
gus->dmaaddr = 0;
gus->voice = 0;
memset(gus->start, 0x00, 32 * sizeof(uint32_t));
memset(gus->end, 0x00, 32 * sizeof(uint32_t));
memset(gus->cur, 0x00, 32 * sizeof(uint32_t));
memset(gus->startx, 0x00, 32 * sizeof(uint32_t));
memset(gus->endx, 0x00, 32 * sizeof(uint32_t));
memset(gus->curx, 0x00, 32 * sizeof(uint32_t));
memset(gus->rstart, 0x00, 32 * sizeof(int));
memset(gus->rend, 0x00, 32 * sizeof(int));
memset(gus->rcur, 0x00, 32 * sizeof(int));
memset(gus->freq, 0x00, 32 * sizeof(uint16_t));
memset(gus->curvol, 0x00, 32 * sizeof(int));
memset(gus->pan_l, 0x00, 32 * sizeof(int));
memset(gus->pan_r, 0x00, 32 * sizeof(int));
gus->t1on = 0;
gus->t2on = 0;
gus->tctrl = 0;
gus->t1 = 0;
gus->t2 = 0;
gus->irqstatus = 0;
gus->irqstatus2 = 0;
gus->adcommand = 0;
memset(gus->waveirqs, 0x00, 32 * sizeof(int));
memset(gus->rampirqs, 0x00, 32 * sizeof(int));
gus->dmactrl = 0;
gus->uart_out = 1;
gus->sb_2xa = 0;
gus->sb_2xc = 0;
gus->sb_2xe = 0;
gus->sb_ctrl = 0;
gus->sb_nmi = 0;
gus->reg_ctrl = 0;
gus->ad_status = 0;
gus->ad_data = 0;
gus->ad_timer_ctrl = 0;
gus->midi_ctrl = 0;
gus->midi_status = 0;
memset(gus->midi_queue, 0x00, 64 * sizeof(uint8_t));
gus->midi_data = 0;
gus->midi_r = 0;
gus->midi_w = 0;
gus->uart_in = 0;
gus->uart_out = 0;
gus->sysex = 0;
gus->gp1 = 0;
gus->gp2 = 0;
gus->gp1_addr = 0;
gus->gp2_addr = 0;
gus->usrr = 0;
gus->max_ctrl = 0;
gus->irq_state = 0;
gus->midi_irq_state = 0;
gus_update_int_status(gus);
}
void *
gus_init(UNUSED(const device_t *info))
{
@@ -1181,7 +1294,7 @@ gus_init(UNUSED(const device_t *info))
double out = 1.0;
uint8_t gus_ram = device_get_config_int("gus_ram");
gus_t *gus = malloc(sizeof(gus_t));
memset(gus, 0, sizeof(gus_t));
memset(gus, 0x00, sizeof(gus_t));
gus->gus_end_ram = 1 << (18 + gus_ram);
gus->ram = (uint8_t *) malloc(gus->gus_end_ram);
@@ -1359,7 +1472,7 @@ const device_t gus_device = {
.local = 0,
.init = gus_init,
.close = gus_close,
.reset = NULL,
.reset = gus_reset,
{ .available = NULL },
.speed_changed = gus_speed_changed,
.force_redraw = NULL,

View File

@@ -317,10 +317,14 @@ ohci_update_irq(usb_t *dev)
{
uint32_t level = !!(dev->ohci_mmio[OHCI_HcInterruptStatus].l & dev->ohci_mmio[OHCI_HcInterruptEnable].l);
#ifdef STATE_KEEPING
if (level != dev->irq_level) {
#endif
dev->irq_level = level;
usb_interrupt_ohci(dev, level);
#ifdef STATE_KEEPING
}
#endif
}
void

View File

@@ -94,9 +94,11 @@ typedef struct mach64_t {
int type;
int pci;
uint8_t pci_slot;
uint8_t irq_state;
uint8_t pci_regs[256];
uint8_t int_line;
int card;
int bank_r[2];
int bank_w[2];
@@ -647,9 +649,9 @@ mach64_update_irqs(mach64_t *mach64)
}
if ((mach64->crtc_int_cntl & 0xaa0024) & ((mach64->crtc_int_cntl << 1) & 0xaa0024))
pci_set_irq(mach64->card, PCI_INTA);
pci_set_irq(mach64->pci_slot, PCI_INTA, &mach64->irq_state);
else
pci_clear_irq(mach64->card, PCI_INTA);
pci_clear_irq(mach64->pci_slot, PCI_INTA, &mach64->irq_state);
}
static __inline void
@@ -4401,7 +4403,7 @@ mach64_common_init(const device_t *info)
mach64_io_set(mach64);
if (info->flags & DEVICE_PCI)
mach64->card = pci_add_card(PCI_ADD_VIDEO, mach64_pci_read, mach64_pci_write, mach64);
pci_add_card(PCI_ADD_NORMAL, mach64_pci_read, mach64_pci_write, mach64, &mach64->pci_slot);
mach64->pci_regs[PCI_REG_COMMAND] = 3;
mach64->pci_regs[0x30] = 0x00;

View File

@@ -58,7 +58,8 @@ typedef struct mach_t {
uint8_t regs[256];
uint8_t pci_regs[256];
uint8_t int_line;
int card;
uint8_t pci_slot;
uint8_t irq_state;
int index;
uint32_t memory;
@@ -5571,7 +5572,7 @@ mach8_init(const device_t *info)
else if (mach->pci_bus) {
ati_eeprom_load(&mach->eeprom, "mach32_pci.nvr", 1);
mem_mapping_disable(&mach->bios_rom.mapping);
mach->card = pci_add_card(PCI_ADD_VIDEO, mach32_pci_read, mach32_pci_write, mach);
pci_add_card(PCI_ADD_VIDEO, mach32_pci_read, mach32_pci_write, mach, &mach->pci_slot);
mach->pci_regs[PCI_REG_COMMAND] = 0x83;
mach->pci_regs[0x30] = 0x00;
mach->pci_regs[0x32] = 0x0c;

View File

@@ -217,7 +217,10 @@ typedef struct gd54xx_t {
uint8_t fc; /* Feature Connector */
int card, id;
int id;
uint8_t pci_slot;
uint8_t irq_state;
uint8_t pos_regs[8];
@@ -484,9 +487,9 @@ gd54xx_update_irqs(gd54xx_t *gd54xx)
return;
if ((gd54xx->vblank_irq > 0) && gd54xx_vga_vsync_enabled(gd54xx))
pci_set_irq(gd54xx->card, PCI_INTA);
pci_set_irq(gd54xx->pci_slot, PCI_INTA, &gd54xx->irq_state);
else
pci_clear_irq(gd54xx->card, PCI_INTA);
pci_clear_irq(gd54xx->pci_slot, PCI_INTA, &gd54xx->irq_state);
}
static void
@@ -4056,7 +4059,10 @@ static void
io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx);
if (gd54xx->pci && id >= CIRRUS_ID_CLGD5430) {
pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx);
if (romfn == NULL)
pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx, &gd54xx->pci_slot);
else
pci_add_card(PCI_ADD_NORMAL, cl_pci_read, cl_pci_write, gd54xx, &gd54xx->pci_slot);
mem_mapping_disable(&gd54xx->bios_rom.mapping);
}

View File

@@ -69,7 +69,7 @@ typedef struct et4000w32p_t {
svga_t svga;
uint8_t banking, banking2, adjust_cursor, rev;
uint8_t banking, banking2, adjust_cursor, rev, pci_slot;
uint8_t regs[256], pci_regs[256];
@@ -2800,7 +2800,7 @@ et4000w32p_init(const device_t *info)
et4000w32p_io_set(et4000);
if (info->flags & DEVICE_PCI)
pci_add_card(PCI_ADD_VIDEO, et4000w32p_pci_read, et4000w32p_pci_write, et4000);
pci_add_card(PCI_ADD_NORMAL, et4000w32p_pci_read, et4000w32p_pci_write, et4000, &et4000->pci_slot);
/* Hardwired bits: 00000000 1xx0x0xx */
/* R/W bits: xx xxxx */

View File

@@ -424,11 +424,12 @@ typedef struct mystique_t {
xcolkeyl, xcolkeyh,
xcrcbitsel;
uint8_t pci_slot, irq_state, pad, pad0;
uint8_t pci_regs[256], crtcext_regs[6],
xreg_regs[256], dmamap[16];
int card, vram_size, crtcext_idx, xreg_idx,
xzoomctrl,
int vram_size, crtcext_idx, xreg_idx, xzoomctrl,
pixel_count, trap_count;
atomic_int busy, blitter_submit_refcount,
@@ -1031,9 +1032,9 @@ mystique_update_irqs(mystique_t *mystique)
irq = 1;
if (irq)
pci_set_irq(mystique->card, PCI_INTA);
pci_set_irq(mystique->pci_slot, PCI_INTA, &mystique->irq_state);
else
pci_clear_irq(mystique->card, PCI_INTA);
pci_clear_irq(mystique->pci_slot, PCI_INTA, &mystique->irq_state);
}
#define READ8(addr, var) \
@@ -5460,7 +5461,7 @@ static void *
mystique_init(const device_t *info)
{
mystique_t *mystique = malloc(sizeof(mystique_t));
char *romfn;
char *romfn = NULL;
memset(mystique, 0, sizeof(mystique_t));
@@ -5524,7 +5525,10 @@ mystique_init(const device_t *info)
NULL, 0, mystique);
mem_mapping_disable(&mystique->iload_mapping);
mystique->card = pci_add_card(PCI_ADD_VIDEO, mystique_pci_read, mystique_pci_write, mystique);
if (romfn = NULL)
pci_add_card(PCI_ADD_NORMAL, mystique_pci_read, mystique_pci_write, mystique, &mystique->pci_slot);
else
pci_add_card(PCI_ADD_VIDEO, mystique_pci_read, mystique_pci_write, mystique, &mystique->pci_slot);
mystique->pci_regs[0x06] = 0x80;
mystique->pci_regs[0x07] = 0 << 1;
mystique->pci_regs[0x2c] = mystique->bios_rom.rom[0x7ff8];

View File

@@ -209,7 +209,9 @@ typedef struct s3_t {
uint32_t linear_base, linear_size;
uint8_t pci_regs[256];
int card;
uint8_t pci_slot;
uint8_t irq_state;
uint32_t vram_mask;
uint8_t data_available;
@@ -465,9 +467,9 @@ s3_update_irqs(s3_t *s3)
return;
if (s3->subsys_cntl & s3->subsys_stat & INT_MASK) {
pci_set_irq(s3->card, PCI_INTA);
pci_set_irq(s3->pci_slot, PCI_INTA, &s3->irq_state);
} else {
pci_clear_irq(s3->card, PCI_INTA);
pci_clear_irq(s3->pci_slot, PCI_INTA, &s3->irq_state);
}
}
@@ -8349,8 +8351,12 @@ s3_init(const device_t *info)
return NULL;
}
if (s3->pci)
s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3);
if (s3->pci) {
if (bios_fn == NULL)
pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3, &s3->pci_slot);
else
pci_add_card(PCI_ADD_NORMAL, s3_pci_read, s3_pci_write, s3, &s3->pci_slot);
}
s3->i2c = i2c_gpio_init("ddc_s3");
s3->ddc = ddc_init(i2c_gpio_get_bus(s3->i2c));

View File

@@ -172,7 +172,9 @@ typedef struct virge_t {
uint32_t linear_base, linear_size;
uint8_t pci_regs[256];
int card;
uint8_t pci_slot;
uint8_t irq_state;
int pci;
int chip;
@@ -278,7 +280,6 @@ typedef struct virge_t {
uint32_t cmd_dma_base;
uint32_t dma_ptr;
uint64_t blitter_time;
volatile int fifo_slot;
int fifo_slots_num;
pc_timer_t tri_timer;
@@ -419,9 +420,9 @@ static void
s3_virge_update_irqs(virge_t *virge)
{
if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & (virge->subsys_cntl & INT_MASK)))
pci_set_irq(virge->card, PCI_INTA);
pci_set_irq(virge->pci_slot, PCI_INTA, &virge->irq_state);
else
pci_clear_irq(virge->card, PCI_INTA);
pci_clear_irq(virge->pci_slot, PCI_INTA, &virge->irq_state);
}
static void
@@ -998,9 +999,9 @@ s3_virge_vblank_start(svga_t *svga)
static void
s3_virge_mmio_fifo_write(uint32_t addr, uint8_t val, virge_t *virge)
{
if ((addr & 0xffff) < 0x8000) {
if ((addr & 0xffff) < 0x8000)
s3_virge_bitblt(virge, 8, val);
} else {
else {
switch (addr & 0xffff) {
case 0x859c:
virge->cmd_dma = val;
@@ -1032,9 +1033,6 @@ s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge)
else
s3_virge_bitblt(virge, 32, val);
} else {
if (virge->fifo_slot >= virge->fifo_slots_num)
return;
virge->fifo_slot++;
switch (addr & 0xfffc) {
case 0x8590:
virge->cmd_dma_base = val;
@@ -1482,24 +1480,24 @@ s3_virge_mmio_read(uint32_t addr, void *priv)
s3_virge_log("[%04X:%08X]: MMIO ReadB addr = %04x\n", CS, cpu_state.pc, addr & 0xffff);
switch (addr & 0xffff) {
case 0x8504:
virge->subsys_stat |= (INT_3DF_EMP | INT_FIFO_EMP);
ret = virge->subsys_stat;
s3_virge_update_irqs(virge);
return ret;
case 0x8505:
ret = 0xc0;
if (!virge->s3d_busy && !virge->fifo_slot)
ret = 0xd0;
if (!virge->s3d_busy)
ret |= 0x20;
if (virge->fifo_slot)
virge->fifo_slot--;
ret |= (virge->fifo_slots_num - virge->fifo_slot);
return ret;
case 0x850c:
ret = virge->advfunc_cntl & 0x3f;
if (virge->fifo_slot)
virge->fifo_slot--;
ret |= (virge->fifo_slots_num - virge->fifo_slot) << 6;
ret |= virge->fifo_slots_num << 6;
ret &= 0xff;
break;
case 0x850d:
ret = (virge->fifo_slots_num - virge->fifo_slot) >> 2;
ret = virge->fifo_slots_num >> 2;
break;
case 0x83b0:
@@ -1576,23 +1574,17 @@ s3_virge_mmio_read_w(uint32_t addr, void *priv)
switch (addr & 0xfffe) {
case 0x8504:
ret = 0xc000;
if (!virge->s3d_busy && !virge->fifo_slot)
ret = 0xd000;
if (!virge->s3d_busy)
ret |= 0x2000;
if (!virge->fifo_slot)
virge->subsys_stat |= INT_FIFO_EMP;
virge->subsys_stat |= (INT_3DF_EMP | INT_FIFO_EMP);
ret |= virge->subsys_stat;
if (virge->fifo_slot)
virge->fifo_slot--;
ret |= (virge->fifo_slots_num - virge->fifo_slot) << 8;
s3_virge_update_irqs(virge);
return ret;
case 0x850c:
ret = virge->advfunc_cntl & 0x3f;
if (virge->fifo_slot)
virge->fifo_slot--;
ret |= (virge->fifo_slots_num - virge->fifo_slot) << 6;
ret |= virge->fifo_slots_num << 6;
break;
case 0x859c:
@@ -1682,26 +1674,17 @@ s3_virge_mmio_read_l(uint32_t addr, void *priv)
break;
case 0x8504:
ret = 0x0000c000;
if (!virge->s3d_busy && !virge->fifo_slot) {
ret = 0x0000d000;
if (!virge->s3d_busy)
ret |= 0x00002000;
if (!virge->s3d_busy)
virge->subsys_stat |= INT_3DF_EMP;
if (!virge->fifo_slot)
virge->subsys_stat |= INT_FIFO_EMP;
}
virge->subsys_stat |= (INT_3DF_EMP | INT_FIFO_EMP);
ret |= virge->subsys_stat;
if (virge->fifo_slot)
virge->fifo_slot--;
ret |= (virge->fifo_slots_num - virge->fifo_slot) << 8;
s3_virge_update_irqs(virge);
break;
case 0x850c:
ret = virge->advfunc_cntl & 0x3f;
if (virge->fifo_slot)
virge->fifo_slot--;
ret |= (virge->fifo_slots_num - virge->fifo_slot) << 6;
ret |= virge->fifo_slots_num << 6;
break;
case 0x8590:
@@ -4421,7 +4404,10 @@ s3_virge_init(const device_t *info)
virge->svga.crtc[0x37] = 1 | (7 << 5);
virge->svga.crtc[0x53] = 8;
virge->card = pci_add_card(virge->is_agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge);
if (bios_fn == NULL)
pci_add_card(virge->is_agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge, &virge->pci_slot);
else
pci_add_card(virge->is_agp ? PCI_ADD_AGP : PCI_ADD_NORMAL, s3_virge_pci_read, s3_virge_pci_write, virge, &virge->pci_slot);
virge->i2c = i2c_gpio_init("ddc_s3_virge");
virge->ddc = ddc_init(i2c_gpio_get_bus(virge->i2c));

View File

@@ -103,7 +103,10 @@ typedef struct tgui_t {
svga_t svga;
int pci;
int type, card;
uint8_t pci_slot;
uint8_t irq_state;
int type;
uint8_t int_line;
uint8_t pci_regs[256];
@@ -220,9 +223,9 @@ tgui_update_irqs(tgui_t *tgui)
return;
if (!(tgui->oldctrl1 & 0x40)) {
pci_set_irq(tgui->card, PCI_INTA);
pci_set_irq(tgui->pci_slot, PCI_INTA, &tgui->irq_state);
} else {
pci_clear_irq(tgui->card, PCI_INTA);
pci_clear_irq(tgui->pci_slot, PCI_INTA, &tgui->irq_state);
}
}
@@ -3516,9 +3519,9 @@ tgui_init(const device_t *info)
if (tgui->pci && (tgui->type >= TGUI_9440)) {
if (tgui->has_bios)
tgui->card = pci_add_card(PCI_ADD_VIDEO, tgui_pci_read, tgui_pci_write, tgui);
pci_add_card(PCI_ADD_NORMAL, tgui_pci_read, tgui_pci_write, tgui, &tgui->pci_slot);
else
tgui->card = pci_add_card(PCI_ADD_VIDEO | PCI_ADD_STRICT, tgui_pci_read, tgui_pci_write, tgui);
pci_add_card(PCI_ADD_VIDEO | PCI_ADD_STRICT, tgui_pci_read, tgui_pci_write, tgui, &tgui->pci_slot);
}
tgui->pci_regs[PCI_REG_COMMAND] = 7;

View File

@@ -923,7 +923,7 @@ voodoo_card_init(void)
else
voodoo_generate_filter_v1(voodoo);
pci_add_card(PCI_ADD_NORMAL, voodoo_pci_read, voodoo_pci_write, voodoo);
pci_add_card(PCI_ADD_NORMAL, voodoo_pci_read, voodoo_pci_write, voodoo, &voodoo->pci_slot);
mem_mapping_add(&voodoo->mapping, 0, 0, NULL, voodoo_readw, voodoo_readl, NULL, voodoo_writew, voodoo_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo);

View File

@@ -142,8 +142,11 @@ typedef struct banshee_t {
int desktop_y;
uint32_t desktop_stride_tiled;
int type, card, agp, has_bios;
int vblank_irq;
int type, agp;
int has_bios, vblank_irq;
uint8_t pci_slot;
uint8_t irq_state;
void *i2c, *i2c_ddc, *ddc;
} banshee_t;
@@ -306,9 +309,9 @@ static void
banshee_update_irqs(banshee_t *banshee)
{
if (banshee->vblank_irq > 0 && banshee_vga_vsync_enabled(banshee)) {
pci_set_irq(banshee->card, PCI_INTA);
pci_set_irq(banshee->pci_slot, PCI_INTA, &banshee->irq_state);
} else {
pci_clear_irq(banshee->card, PCI_INTA);
pci_clear_irq(banshee->pci_slot, PCI_INTA, &banshee->irq_state);
}
}
@@ -3146,7 +3149,10 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int
banshee->dramInit1 = 1 << 30; /*SDRAM*/
banshee->svga.decode_mask = 0x1ffffff;
banshee->card = pci_add_card(banshee->agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, banshee_pci_read, banshee_pci_write, banshee);
if (banshee->has_bios)
pci_add_card(banshee->agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, banshee_pci_read, banshee_pci_write, banshee, &banshee->pci_slot);
else
pci_add_card(banshee->agp ? PCI_ADD_AGP : PCI_ADD_NORMAL, banshee_pci_read, banshee_pci_write, banshee, &banshee->pci_slot);
banshee->voodoo = voodoo_2d3d_card_init(voodoo_type);
banshee->voodoo->p = banshee;