Reverted the PIC code to basically the old code with the new way of handing level-triggered IRQ's, fixes IDE hard disk and ATAPI CD-ROM problems.
This commit is contained in:
413
src/pic.c
413
src/pic.c
@@ -51,23 +51,20 @@ 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 void (*update_pending)(void);
|
||||
static uint16_t smi_irq_mask = 0x0000;
|
||||
static uint16_t smi_irq_status = 0x0000;
|
||||
|
||||
static void pic_update_request(pic_t *dev, int irq);
|
||||
static void pic_update_irr(pic_t *dev, uint16_t num);
|
||||
static uint16_t latched_irqs = 0x0000;
|
||||
|
||||
static void pic_cascade(int set);
|
||||
static void (*update_pending)(void);
|
||||
|
||||
#ifdef ENABLE_PIC_LOG
|
||||
int pic_do_log = ENABLE_PIC_LOG;
|
||||
@@ -226,29 +223,37 @@ find_best_interrupt(pic_t *dev)
|
||||
static __inline void
|
||||
pic_update_pending_xt(void)
|
||||
{
|
||||
if (!(pic.flags & PIC_FREEZE))
|
||||
pic.int_pending = (find_best_interrupt(&pic) != -1);
|
||||
if (find_best_interrupt(&pic) != -1) {
|
||||
latched++;
|
||||
if (latched == 1)
|
||||
timer_on_auto(&pic_timer, 0.35);
|
||||
} else if (latched == 0)
|
||||
pic.int_pending = 0;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
pic_update_pending_at(void)
|
||||
{
|
||||
if (!(pic2.flags & PIC_FREEZE)) {
|
||||
pic2.int_pending = (find_best_interrupt(&pic2) != -1);
|
||||
pic2.int_pending = (find_best_interrupt(&pic2) != -1);
|
||||
|
||||
pic_cascade(pic2.int_pending);
|
||||
}
|
||||
if (pic2.int_pending)
|
||||
pic.irr |= (1 << pic2.icw3);
|
||||
else
|
||||
pic.irr &= ~(1 << pic2.icw3);
|
||||
|
||||
if (!(pic.flags & PIC_FREEZE))
|
||||
pic.int_pending = (find_best_interrupt(&pic) != -1);
|
||||
|
||||
pic_log("pic_update_pending_at(): dev->int_pending = %i (%i)\n", pic.int_pending, !!(pic.flags & PIC_FREEZE));
|
||||
pic.int_pending = (find_best_interrupt(&pic) != -1);
|
||||
}
|
||||
|
||||
static void
|
||||
pic_callback(UNUSED(void *priv))
|
||||
pic_callback(void *priv)
|
||||
{
|
||||
update_pending();
|
||||
pic_t *dev = (pic_t *) priv;
|
||||
|
||||
dev->int_pending = 1;
|
||||
|
||||
latched--;
|
||||
if (latched > 0)
|
||||
timer_on_auto(&pic_timer, 0.35);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -263,13 +268,8 @@ pic_reset(void)
|
||||
pic.is_master = 1;
|
||||
pic.interrupt = pic2.interrupt = 0x17;
|
||||
|
||||
pic.has_slaves = 0;
|
||||
pic2.has_slaves = 0;
|
||||
|
||||
if (is_at) {
|
||||
if (is_at)
|
||||
pic.slaves[2] = &pic2;
|
||||
pic.has_slaves = 1;
|
||||
}
|
||||
|
||||
if (tmr_inited)
|
||||
timer_on_auto(&pic_timer, 0.0);
|
||||
@@ -320,25 +320,14 @@ picint_is_level(int irq)
|
||||
}
|
||||
|
||||
static void
|
||||
pic_acknowledge(pic_t *dev, int poll)
|
||||
pic_acknowledge(pic_t *dev)
|
||||
{
|
||||
int pic_int = dev->interrupt & 7;
|
||||
int pic_int_num = 1 << pic_int;
|
||||
|
||||
dev->isr |= 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;
|
||||
|
||||
if (!poll) {
|
||||
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);
|
||||
}
|
||||
if (!pic_level_triggered(dev, pic_int) || (dev->lines[pic_int] == 0))
|
||||
dev->irr &= ~pic_int_num;
|
||||
}
|
||||
|
||||
/* Find IRQ for non-specific EOI (either by command or automatic) by finding the highest IRQ
|
||||
@@ -375,7 +364,6 @@ pic_action(pic_t *dev, uint8_t irq, uint8_t eoi, uint8_t rotate)
|
||||
if (rotate)
|
||||
dev->priority = (irq + 1) & 7;
|
||||
|
||||
pic_update_request(dev, irq);
|
||||
update_pending();
|
||||
}
|
||||
}
|
||||
@@ -415,10 +403,13 @@ pic_latch_read(UNUSED(uint16_t addr), UNUSED(void *priv))
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
pic_log("pic_latch_read(%04X): %04X\n", enabled_latches, latched_irqs & 0x1002);
|
||||
pic_log("pic_latch_read(%i, %i)\n", kbd_latch, mouse_latch);
|
||||
|
||||
if (latched_irqs & 0x1002)
|
||||
picintc(latched_irqs & 0x1002);
|
||||
if (kbd_latch && (latched_irqs & 0x0002))
|
||||
picintc(0x0002);
|
||||
|
||||
if (mouse_latch && (latched_irqs & 0x1000))
|
||||
picintc(0x1000);
|
||||
|
||||
/* Return FF - we just lower IRQ 1 and IRQ 12. */
|
||||
return ret;
|
||||
@@ -447,23 +438,24 @@ pic_read(uint16_t addr, void *priv)
|
||||
dev->data_bus = dev->irr;
|
||||
#endif
|
||||
if (dev->ocw3 & 0x04) {
|
||||
dev->interrupt &= ~0x20; /* Freeze the interrupt until the poll is over. */
|
||||
if (dev->int_pending) {
|
||||
dev->data_bus = 0x80 | (dev->interrupt & 7);
|
||||
pic_acknowledge(dev, 1);
|
||||
pic_acknowledge(dev);
|
||||
dev->int_pending = 0;
|
||||
update_pending();
|
||||
} else
|
||||
dev->data_bus = 0x00;
|
||||
dev->ocw3 &= ~0x04;
|
||||
dev->flags &= ~PIC_FREEZE; /* Freeze the interrupt until the poll is over. */
|
||||
pic_update_irr(dev, 0x00ff); /* Update IRR, just in case anything came while frozen. */
|
||||
update_pending();
|
||||
} else if (addr & 0x0001)
|
||||
dev->data_bus = dev->imr;
|
||||
else if (dev->ocw3 & 0x02) {
|
||||
if (dev->ocw3 & 0x01)
|
||||
dev->data_bus = dev->isr;
|
||||
#ifdef UNDEFINED_READ
|
||||
else
|
||||
dev->data_bus = dev->irr;
|
||||
dev->data_bus = 0x00;
|
||||
#endif
|
||||
}
|
||||
/* If A0 = 0, VIA shadow is disabled, and poll mode is disabled,
|
||||
simply read whatever is currently on the data bus. */
|
||||
@@ -502,10 +494,7 @@ pic_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case STATE_NONE:
|
||||
dev->imr = val;
|
||||
if (is286)
|
||||
update_pending();
|
||||
else
|
||||
timer_on_auto(&pic_timer, 1.0 * ((10000000.0 * (double) xt_cpu_multi) / (double) cpu_s->rspeed));
|
||||
update_pending();
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -522,13 +511,11 @@ pic_write(uint16_t addr, uint8_t val, void *priv)
|
||||
if (!(dev->icw1 & 1))
|
||||
dev->icw4 = 0x00;
|
||||
dev->ocw2 = dev->ocw3 = 0x00;
|
||||
dev->flags = PIC_MASTER_CLEAR;
|
||||
dev->irr = 0x00;
|
||||
dev->edge_lines = 0x00;
|
||||
dev->irq_latch = 0x00;
|
||||
for (uint8_t i = 0; i <= 7; i++)
|
||||
pic_update_request(dev, i);
|
||||
dev->flags &= ~PIC_MASTER_CLEAR;
|
||||
dev->irr = 0x00;
|
||||
for (uint8_t i = 0; i <= 7; i++) {
|
||||
if (dev->lines[i] > 0)
|
||||
dev->irr |= (1 << i);
|
||||
}
|
||||
dev->imr = dev->isr = 0x00;
|
||||
dev->ack_bytes = dev->priority = 0x00;
|
||||
dev->auto_eoi_rotate = dev->special_mask_mode = 0x00;
|
||||
@@ -539,7 +526,7 @@ pic_write(uint16_t addr, uint8_t val, void *priv)
|
||||
} else if (val & 0x08) {
|
||||
dev->ocw3 = val;
|
||||
if (dev->ocw3 & 0x04)
|
||||
dev->flags |= PIC_FREEZE; /* Freeze the interrupt until the poll is over. */
|
||||
dev->interrupt |= 0x20; /* Freeze the interrupt until the poll is over. */
|
||||
if (dev->ocw3 & 0x40)
|
||||
dev->special_mask_mode = !!(dev->ocw3 & 0x20);
|
||||
} else {
|
||||
@@ -566,15 +553,12 @@ 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");
|
||||
|
||||
enable = (!!enable) << 1;
|
||||
enabled_latches = (enabled_latches & 0x1000) | enable;
|
||||
if (!!(enable | mouse_latch) != !!(kbd_latch | mouse_latch))
|
||||
io_handler(!!(enable | mouse_latch), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (!!(enabled_latches & 0x1002) != !!(old_latches & 0x1002))
|
||||
io_handler(!!(enabled_latches & 0x1002), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
kbd_latch = !!enable;
|
||||
|
||||
if (!enable)
|
||||
picintc(0x0002);
|
||||
@@ -583,15 +567,12 @@ 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");
|
||||
|
||||
enable = (!!enable) << 12;
|
||||
enabled_latches = (enabled_latches & 0x0002) | enable;
|
||||
if (!!(kbd_latch | enable) != !!(kbd_latch | mouse_latch))
|
||||
io_handler(!!(kbd_latch | enable), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (!!(enabled_latches & 0x1002) != !!(old_latches & 0x1002))
|
||||
io_handler(!!(enabled_latches & 0x1002), 0x0060, 0x0001, pic_latch_read, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
mouse_latch = !!enable;
|
||||
|
||||
if (!enable)
|
||||
picintc(0x1000);
|
||||
@@ -603,11 +584,11 @@ pic_reset_hard(void)
|
||||
pic_reset();
|
||||
|
||||
/* Explicitly reset the latches. */
|
||||
enabled_latches = 0x0000;
|
||||
kbd_latch = mouse_latch = 0;
|
||||
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 latches that get used in place of the latches
|
||||
to the point that there's even boards with board-level latched 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);
|
||||
@@ -643,125 +624,31 @@ pic2_init(void)
|
||||
pic.slaves[2] = &pic2;
|
||||
}
|
||||
|
||||
void
|
||||
pic_update_lines(pic_t *dev, uint16_t num, int level, int set, uint8_t *irq_state)
|
||||
{
|
||||
uint8_t old_edge_lines;
|
||||
uint8_t 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;
|
||||
|
||||
default:
|
||||
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));
|
||||
|
||||
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);
|
||||
|
||||
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));
|
||||
|
||||
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));
|
||||
|
||||
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));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
pic_update_request(pic_t *dev, int irq)
|
||||
{
|
||||
dev->irr &= ~(1 << irq);
|
||||
|
||||
if (!(dev->flags & PIC_FREEZE))
|
||||
dev->irr |= (pic_irq_request_nor(dev, irq) << irq);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
int raise;
|
||||
uint8_t b;
|
||||
uint8_t slaves = 0;
|
||||
|
||||
/* Make sure to ignore all slave IRQ's, and in case of AT+,
|
||||
translate IRQ 2 to IRQ 9. */
|
||||
if (num & pic.icw3) {
|
||||
num &= ~pic.icw3;
|
||||
if (pic.at)
|
||||
num |= (1 << 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 (!pic.has_slaves)
|
||||
if (!slaves)
|
||||
num &= 0x00ff;
|
||||
|
||||
if (!num) {
|
||||
@@ -772,40 +659,93 @@ picint_common(uint16_t num, int level, int set, uint8_t *irq_state)
|
||||
if (num & 0x0100)
|
||||
acpi_rtc_status = !!set;
|
||||
|
||||
smi_irq_status &= ~num;
|
||||
if (set && (smi_irq_mask & num)) {
|
||||
smi_raise();
|
||||
smi_irq_status |= num;
|
||||
if (set) {
|
||||
if (smi_irq_mask & num) {
|
||||
smi_raise();
|
||||
smi_irq_status |= num;
|
||||
}
|
||||
|
||||
if (num & 0xff00) {
|
||||
if (level) {
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
b = (uint8_t) (1 << i);
|
||||
if (((num >> 8) & b) && ((!!*irq_state) != !!set))
|
||||
pic2.lines[i]++;
|
||||
}
|
||||
|
||||
if ((!!*irq_state) != !!set)
|
||||
*irq_state = set;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
b = (uint8_t) (1 << i);
|
||||
if ((num & b) && ((!!*irq_state) != !!set))
|
||||
pic.lines[i]++;
|
||||
}
|
||||
|
||||
if ((!!*irq_state) != !!set)
|
||||
*irq_state = set;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
if (level) {
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
b = (uint8_t) (1 << i);
|
||||
if (((num >> 8) & b) && ((!!*irq_state) != !!set))
|
||||
pic2.lines[i]--;
|
||||
}
|
||||
|
||||
if ((!!*irq_state) != !!set)
|
||||
*irq_state = set;
|
||||
}
|
||||
|
||||
/* Unlatch IRQ 12 if the mouse latch is enabled. */
|
||||
if ((num & 0x1000) && mouse_latch)
|
||||
latched_irqs &= 0xefff;
|
||||
|
||||
pic2.irr &= ~(num >> 8);
|
||||
}
|
||||
|
||||
if (num & 0x00ff) {
|
||||
if (level) {
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
b = (uint8_t) (1 << i);
|
||||
if ((num & b) && ((!!*irq_state) != !!set))
|
||||
pic.lines[i]--;
|
||||
}
|
||||
|
||||
if ((!!*irq_state) != !!set)
|
||||
*irq_state = set;
|
||||
}
|
||||
|
||||
/* Unlatch IRQ 1 if the keyboard latch is enabled. */
|
||||
if (kbd_latch && (num & 0x0002))
|
||||
latched_irqs &= 0xfffd;
|
||||
|
||||
pic.irr &= ~(num & 0x00ff);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
update_pending();
|
||||
}
|
||||
|
||||
static void
|
||||
pic_cascade(int set)
|
||||
{
|
||||
pic_update_lines(&pic, (1 << pic2.icw3), PIC_IRQ_EDGE, set, NULL);
|
||||
pic_update_irr(&pic, (1 << pic2.icw3));
|
||||
if (!(pic.interrupt & 0x20) && !(pic2.interrupt & 0x20))
|
||||
update_pending();
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
@@ -817,13 +757,16 @@ pic_i86_mode(pic_t *dev)
|
||||
static uint8_t
|
||||
pic_irq_ack_read(pic_t *dev, int phase)
|
||||
{
|
||||
uint8_t intr = dev->interrupt & 0x07;
|
||||
uint8_t slave = dev->flags & PIC_SLAVE_PENDING;
|
||||
uint8_t intr = dev->interrupt & 0x47;
|
||||
uint8_t slave = intr & 0x40;
|
||||
intr &= 0x07;
|
||||
pic_log(" pic_irq_ack_read(%08X, %i)\n", dev, phase);
|
||||
|
||||
if (dev != NULL) {
|
||||
if (phase == 0) {
|
||||
pic_acknowledge(dev, 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);
|
||||
else
|
||||
@@ -855,9 +798,6 @@ pic_irq_ack_read(pic_t *dev, int phase)
|
||||
return dev->data_bus;
|
||||
}
|
||||
|
||||
/* 808x: Update the requests for all interrupts since any of them
|
||||
could have arrived during the freeze. */
|
||||
|
||||
uint8_t
|
||||
pic_irq_ack(void)
|
||||
{
|
||||
@@ -871,7 +811,7 @@ pic_irq_ack(void)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
pic.flags |= PIC_SLAVE_PENDING;
|
||||
pic.interrupt |= 0x40; /* Mark slave pending. */
|
||||
}
|
||||
|
||||
ret = pic_irq_ack_read(&pic, pic.ack_bytes);
|
||||
@@ -879,13 +819,8 @@ pic_irq_ack(void)
|
||||
|
||||
if (pic.ack_bytes == 0) {
|
||||
/* Needed for Xi8088. */
|
||||
if (pic.flags & PIC_SLAVE_PENDING) {
|
||||
pic2.flags &= ~PIC_FREEZE;
|
||||
pic_update_irr(&pic2, 0x00ff);
|
||||
if (pic.interrupt & 0x40)
|
||||
pic2.interrupt = 0x17;
|
||||
}
|
||||
pic.flags &= ~(PIC_SLAVE_PENDING | PIC_FREEZE);
|
||||
pic_update_irr(&pic, 0x00ff);
|
||||
pic.interrupt = 0x17;
|
||||
update_pending();
|
||||
}
|
||||
@@ -893,9 +828,6 @@ pic_irq_ack(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 286+: Only update the request for the pending interrupt as it is
|
||||
impossible that any other interrupt has arrived during the
|
||||
freeze. */
|
||||
int
|
||||
picinterrupt(void)
|
||||
{
|
||||
@@ -909,7 +841,7 @@ picinterrupt(void)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
pic.flags |= PIC_SLAVE_PENDING;
|
||||
pic.interrupt |= 0x40; /* Mark slave pending. */
|
||||
}
|
||||
|
||||
if ((pic.interrupt == 0) && (pit_devs[1].data != NULL))
|
||||
@@ -921,13 +853,8 @@ picinterrupt(void)
|
||||
pic.ack_bytes = (pic.ack_bytes + 1) % (pic_i86_mode(&pic) ? 2 : 3);
|
||||
|
||||
if (pic.ack_bytes == 0) {
|
||||
if (pic.flags & PIC_SLAVE_PENDING) {
|
||||
pic2.flags &= ~PIC_FREEZE;
|
||||
pic_update_request(&pic2, pic2.interrupt & 0x07);
|
||||
if (pic.interrupt & 0x40)
|
||||
pic2.interrupt = 0x17;
|
||||
}
|
||||
pic.flags &= ~(PIC_SLAVE_PENDING | PIC_FREEZE);
|
||||
pic_update_request(&pic, pic.interrupt & 0x07);
|
||||
pic.interrupt = 0x17;
|
||||
update_pending();
|
||||
}
|
||||
|
Reference in New Issue
Block a user