Added level-sensitive IRQs on PIIX and SiS497. Fixes hanging audio with AudioPCI on Windows 2000.
This commit is contained in:
parent
cb4c92c0f2
commit
6412d01deb
5 changed files with 53 additions and 4 deletions
|
|
@ -363,6 +363,7 @@ typedef struct PIC
|
||||||
int icw;
|
int icw;
|
||||||
uint8_t vector;
|
uint8_t vector;
|
||||||
int read;
|
int read;
|
||||||
|
uint8_t level_sensitive;
|
||||||
} PIC;
|
} PIC;
|
||||||
|
|
||||||
PIC pic,pic2;
|
PIC pic,pic2;
|
||||||
|
|
|
||||||
49
src/pic.c
49
src/pic.c
|
|
@ -36,6 +36,8 @@ void pic_reset()
|
||||||
pic.mask2=0;
|
pic.mask2=0;
|
||||||
pic2.pend=pic2.ins=0;
|
pic2.pend=pic2.ins=0;
|
||||||
pic_intpending = 0;
|
pic_intpending = 0;
|
||||||
|
pic.level_sensitive = 0;
|
||||||
|
pic2.level_sensitive = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pic_update_mask(uint8_t *mask, uint8_t ins)
|
void pic_update_mask(uint8_t *mask, uint8_t ins)
|
||||||
|
|
@ -275,6 +277,41 @@ void pic2_init()
|
||||||
io_sethandler(0x00a0, 0x0002, pic2_read, NULL, NULL, pic2_write, NULL, NULL, NULL);
|
io_sethandler(0x00a0, 0x0002, pic2_read, NULL, NULL, pic2_write, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t pic_elcrx_read(uint16_t addr, void *p)
|
||||||
|
{
|
||||||
|
uint8_t temp = 0xff;
|
||||||
|
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x4d0:
|
||||||
|
temp = pic.level_sensitive;
|
||||||
|
break;
|
||||||
|
case 0x4d1:
|
||||||
|
temp = pic2.level_sensitive;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pic_elcrx_write(uint16_t addr, uint8_t val, void *p)
|
||||||
|
{
|
||||||
|
// pclog("pic_elcrx_write: addr=%04x val=%02x\n", addr, val);
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x4d0:
|
||||||
|
pic.level_sensitive = val & 0xf8;
|
||||||
|
break;
|
||||||
|
case 0x4d1:
|
||||||
|
pic2.level_sensitive = val & 0xde;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pic_init_elcrx()
|
||||||
|
{
|
||||||
|
io_sethandler(0x04d0, 0x0002, pic_elcrx_read, NULL, NULL, pic_elcrx_write, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void clearpic()
|
void clearpic()
|
||||||
{
|
{
|
||||||
|
|
@ -364,7 +401,8 @@ uint8_t picinterrupt()
|
||||||
{
|
{
|
||||||
if (temp & (1 << c))
|
if (temp & (1 << c))
|
||||||
{
|
{
|
||||||
pic.pend &= ~(1 << c);
|
if (!(pic.level_sensitive & (1 << c)))
|
||||||
|
pic.pend &= ~(1 << c);
|
||||||
pic.ins |= (1 << c);
|
pic.ins |= (1 << c);
|
||||||
pic_update_mask(&pic.mask2, pic.ins);
|
pic_update_mask(&pic.mask2, pic.ins);
|
||||||
|
|
||||||
|
|
@ -385,11 +423,13 @@ uint8_t picinterrupt()
|
||||||
{
|
{
|
||||||
if (temp2 & (1 << c))
|
if (temp2 & (1 << c))
|
||||||
{
|
{
|
||||||
pic2.pend &= ~(1 << c);
|
if (!(pic2.level_sensitive & (1 << c)))
|
||||||
|
pic2.pend &= ~(1 << c);
|
||||||
pic2.ins |= (1 << c);
|
pic2.ins |= (1 << c);
|
||||||
pic_update_mask(&pic2.mask2, pic2.ins);
|
pic_update_mask(&pic2.mask2, pic2.ins);
|
||||||
|
|
||||||
pic.pend &= ~(1 << c);
|
if (!(pic2.level_sensitive & (1 << c)))
|
||||||
|
pic.pend &= ~(1 << c);
|
||||||
pic.ins |= (1 << 2); /*Cascade IRQ*/
|
pic.ins |= (1 << 2); /*Cascade IRQ*/
|
||||||
pic_update_mask(&pic.mask2, pic.ins);
|
pic_update_mask(&pic.mask2, pic.ins);
|
||||||
|
|
||||||
|
|
@ -406,7 +446,8 @@ uint8_t picinterrupt()
|
||||||
{
|
{
|
||||||
if (temp & (1 << c))
|
if (temp & (1 << c))
|
||||||
{
|
{
|
||||||
pic.pend &= ~(1 << c);
|
if (!(pic.level_sensitive & (1 << c)))
|
||||||
|
pic.pend &= ~(1 << c);
|
||||||
pic.ins |= (1 << c);
|
pic.ins |= (1 << c);
|
||||||
pic_update_mask(&pic.mask2, pic.ins);
|
pic_update_mask(&pic.mask2, pic.ins);
|
||||||
pic_updatepending();
|
pic_updatepending();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
void pic_init();
|
void pic_init();
|
||||||
void pic2_init();
|
void pic2_init();
|
||||||
|
void pic_init_elcrx();
|
||||||
void pic_reset();
|
void pic_reset();
|
||||||
|
|
||||||
void picint(uint16_t num);
|
void picint(uint16_t num);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
|
#include "pic.h"
|
||||||
|
|
||||||
#include "piix.h"
|
#include "piix.h"
|
||||||
|
|
||||||
|
|
@ -386,4 +387,6 @@ void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d)
|
||||||
|
|
||||||
ide_pri_disable();
|
ide_pri_disable();
|
||||||
ide_sec_disable();
|
ide_sec_disable();
|
||||||
|
|
||||||
|
pic_init_elcrx();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
|
#include "pic.h"
|
||||||
|
|
||||||
#include "sis496.h"
|
#include "sis496.h"
|
||||||
|
|
||||||
|
|
@ -137,6 +138,8 @@ void *sis496_init()
|
||||||
pci_set_card_routing(13, PCI_INTD);
|
pci_set_card_routing(13, PCI_INTD);
|
||||||
pci_set_card_routing(11, PCI_INTC);
|
pci_set_card_routing(11, PCI_INTC);
|
||||||
|
|
||||||
|
pic_init_elcrx();
|
||||||
|
|
||||||
return sis496;
|
return sis496;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue